Added ability to disable fsync()

Passed config to LocalStatus and Maildir folders so they can look
up the fsync status
This commit is contained in:
John Goerzen 2008-08-02 14:55:08 -05:00
parent e58cd67401
commit 2b23657db0
5 changed files with 35 additions and 14 deletions

View File

@ -98,6 +98,16 @@ ignore-readonly = no
# #
# socktimeout = 60 # socktimeout = 60
# By default, OfflineIMAP will use fsync() to force data out to disk at
# opportune times to ensure consistency. This can, however, reduce
# performance. Users where /home is on SSD (Flash) may also wish to reduce
# write cycles. Therefore, you can disable OfflineIMAP's use of fsync().
# Doing so will come at the expense of greater risk of message duplication
# in the event of a system crash or power loss. Default is fsync = true.
# Set fsync = false ot disable fsync.
#
# fsync = true
################################################## ##################################################
# Mailbox name recorder # Mailbox name recorder
################################################## ##################################################

View File

@ -22,10 +22,12 @@ import os, threading
magicline = "OFFLINEIMAP LocalStatus CACHE DATA - DO NOT MODIFY - FORMAT 1" magicline = "OFFLINEIMAP LocalStatus CACHE DATA - DO NOT MODIFY - FORMAT 1"
class LocalStatusFolder(BaseFolder): class LocalStatusFolder(BaseFolder):
def __init__(self, root, name, repository, accountname): def __init__(self, root, name, repository, accountname, config):
self.name = name self.name = name
self.root = root self.root = root
self.sep = '.' self.sep = '.'
self.config = config
self.dofsync = config.getdefaultboolean("general", "fsync")
self.filename = os.path.join(root, name) self.filename = os.path.join(root, name)
self.filename = repository.getfolderfilename(name) self.filename = repository.getfolderfilename(name)
self.messagelist = None self.messagelist = None
@ -96,16 +98,18 @@ class LocalStatusFolder(BaseFolder):
flags = ''.join(flags) flags = ''.join(flags)
file.write("%s:%s\n" % (msg['uid'], flags)) file.write("%s:%s\n" % (msg['uid'], flags))
file.flush() file.flush()
os.fsync(file.fileno()) if self.dofsync:
os.fsync(file.fileno())
file.close() file.close()
os.rename(self.filename + ".tmp", self.filename) os.rename(self.filename + ".tmp", self.filename)
try: if self.dofsync:
fd = os.open(os.path.dirname(self.filename), os.O_RDONLY) try:
os.fsync(fd) fd = os.open(os.path.dirname(self.filename), os.O_RDONLY)
os.close(fd) os.fsync(fd)
except: os.close(fd)
pass except:
pass
finally: finally:
self.savelock.release() self.savelock.release()

View File

@ -45,8 +45,10 @@ def gettimeseq():
timelock.release() timelock.release()
class MaildirFolder(BaseFolder): class MaildirFolder(BaseFolder):
def __init__(self, root, name, sep, repository, accountname): def __init__(self, root, name, sep, repository, accountname, config):
self.name = name self.name = name
self.config = config
self.dofsync = config.getdefaultboolean("general", "fsync")
self.root = root self.root = root
self.sep = sep self.sep = sep
self.messagelist = None self.messagelist = None
@ -183,7 +185,8 @@ class MaildirFolder(BaseFolder):
# Make sure the data hits the disk # Make sure the data hits the disk
file.flush() file.flush()
os.fsync(file.fileno()) if self.dofsync:
os.fsync(file.fileno())
file.close() file.close()
if rtime != None: if rtime != None:

View File

@ -54,12 +54,14 @@ class LocalStatusRepository(BaseRepository):
retval = [] retval = []
for folder in os.listdir(self.directory): for folder in os.listdir(self.directory):
retval.append(folder.LocalStatus.LocalStatusFolder(self.directory, retval.append(folder.LocalStatus.LocalStatusFolder(self.directory,
folder, self, self.accountname)) folder, self, self.accountname,
self.config))
return retval return retval
def getfolder(self, foldername): def getfolder(self, foldername):
return folder.LocalStatus.LocalStatusFolder(self.directory, foldername, return folder.LocalStatus.LocalStatusFolder(self.directory, foldername,
self, self.accountname) self, self.accountname,
self.config)

View File

@ -113,7 +113,8 @@ class MaildirRepository(BaseRepository):
if self.config.has_option('Repository ' + self.name, 'restoreatime') and self.config.getboolean('Repository ' + self.name, 'restoreatime'): if self.config.has_option('Repository ' + self.name, 'restoreatime') and self.config.getboolean('Repository ' + self.name, 'restoreatime'):
self._append_folder_atimes(foldername) self._append_folder_atimes(foldername)
return folder.Maildir.MaildirFolder(self.root, foldername, return folder.Maildir.MaildirFolder(self.root, foldername,
self.getsep(), self, self.accountname) self.getsep(), self,
self.accountname, self.config)
def _getfolders_scandir(self, root, extension = None): def _getfolders_scandir(self, root, extension = None):
self.debug("_GETFOLDERS_SCANDIR STARTING. root = %s, extension = %s" \ self.debug("_GETFOLDERS_SCANDIR STARTING. root = %s, extension = %s" \
@ -159,7 +160,8 @@ class MaildirRepository(BaseRepository):
if self.config.has_option('Repository ' + self.name, 'restoreatime') and self.config.getboolean('Repository ' + self.name, 'restoreatime'): if self.config.has_option('Repository ' + self.name, 'restoreatime') and self.config.getboolean('Repository ' + self.name, 'restoreatime'):
self._append_folder_atimes(foldername) self._append_folder_atimes(foldername)
retval.append(folder.Maildir.MaildirFolder(self.root, foldername, retval.append(folder.Maildir.MaildirFolder(self.root, foldername,
self.getsep(), self, self.accountname)) self.getsep(), self, self.accountname,
self.config))
if self.getsep() == '/' and dirname != '.': if self.getsep() == '/' and dirname != '.':
# Check sub-directories for folders. # Check sub-directories for folders.
retval.extend(self._getfolders_scandir(root, foldername)) retval.extend(self._getfolders_scandir(root, foldername))