diff --git a/ChangeLog b/ChangeLog index 390b3fe36..02c540637 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ * Fix displaying file errors when the torrent isn't paused * Fix issue where torrents being check would get removed due to "stop at ratio" rules * Fix #790 tracker hosts not correct for some .uk trackers + * Make sure config files, resume data and state are fsync'd when saved. This should help prevent data losses on crashes/improper shutdowns. ==== GtkUI ==== * Fix hiding bottom pane when no tabs are enabled upon restart diff --git a/deluge/config.py b/deluge/config.py index 99f073501..9d3255f8f 100644 --- a/deluge/config.py +++ b/deluge/config.py @@ -264,13 +264,26 @@ class Config(object): self.__save_timer = None + # Save the new config and make sure it's written to disk try: log.debug("Saving new config file %s", filename + ".new") - pickle.dump(self.__config, open(filename + ".new", "wb")) + f = open(filename + ".new", "w") + pickle.dump(self.__config, f) + f.flush() + os.fsync(f.fileno()) + f.close() except Exception, e: log.error("Error writing new config file: %s", e) return + # Make a backup of the old config + try: + log.debug("Backing up old config file to %s~", filename) + shutil.move(filename, filename + "~") + except Exception, e: + log.error("Error backing up old config..") + return + # The new config file has been written successfully, so let's move it over # the existing one. try: diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py index cf088b5f8..310547375 100644 --- a/deluge/core/torrent.py +++ b/deluge/core/torrent.py @@ -762,6 +762,8 @@ class Torrent: log.debug("Saving fastresume file: %s", path) fastresume = open(path, "wb") fastresume.write(resume_data) + fastresume.flush() + os.fsync(fastresume.fileno()) fastresume.close() except IOError: log.warning("Error trying to save fastresume file") diff --git a/deluge/core/torrentmanager.py b/deluge/core/torrentmanager.py index b4063ed90..d0b068321 100644 --- a/deluge/core/torrentmanager.py +++ b/deluge/core/torrentmanager.py @@ -540,6 +540,8 @@ class TorrentManager(component.Component): os.path.join(self.config["state_location"], "torrents.state.new"), "wb") cPickle.dump(state, state_file) + state_file.flush() + os.fsync(state_file.fileno()) state_file.close() except IOError: log.warning("Unable to save state file.")