core: do not truncate qubes.xml during save()

Save the next one in temporary file, then move over to destination file.
This way when writing the file to disk fails (e.g. out of disk space),
user still have old file version intact.
This commit is contained in:
Marek Marczykowski-Górecki 2013-12-02 03:32:33 +01:00
parent 93b7924bc6
commit bc92c20d67

View File

@ -28,6 +28,8 @@ import xml.parsers.expat
import fcntl import fcntl
import time import time
import warnings import warnings
import tempfile
import grp
# Do not use XenAPI or create/read any VM files # Do not use XenAPI or create/read any VM files
# This is for testing only! # This is for testing only!
@ -527,11 +529,16 @@ class QubesVmCollection(dict):
try: try:
# We need to manually truncate the file, as we open the new_store_file = tempfile.NamedTemporaryFile(prefix=self.qubes_store_filename, delete=False)
# file as "r+" in the lock_db_for_writing() function # XXX: do not get lock on the new file, as in all use cases
self.qubes_store_file.seek (0, os.SEEK_SET) # unlock_db() is the next operation after save()
self.qubes_store_file.truncate() tree.write(new_store_file, encoding="UTF-8", pretty_print=True)
tree.write(self.qubes_store_file, encoding="UTF-8", pretty_print=True) new_store_file.flush()
os.chmod(new_store_file.name, 0660)
os.chown(new_store_file.name, -1, grp.getgrnam('qubes').gr_gid)
os.rename(new_store_file.name, self.qubes_store_filename)
self.qubes_store_file.close()
self.qubes_store_file = new_store_file
except EnvironmentError as err: except EnvironmentError as err:
print("{0}: export error: {1}".format( print("{0}: export error: {1}".format(
os.path.basename(sys.argv[0]), err)) os.path.basename(sys.argv[0]), err))