Skip to content

Commit

Permalink
storage/lvm: remove old volume only after successfully cloning new one
Browse files Browse the repository at this point in the history
In some cases, it may happen that new volume (`self._vid_snap`) does not
exists. This is normally an error, but even in such a case, do not
remove the only remaining instance of volume (`self.vid`). Instead,
rename it temporarily and remove only after new volume is successfully
cloned.

Fixes QubesOS/qubes-issues#3164
  • Loading branch information
marmarek committed Oct 12, 2017
1 parent ec4c7d7 commit 021047f
Showing 1 changed file with 17 additions and 3 deletions.
20 changes: 17 additions & 3 deletions qubes/storage/lvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,10 +271,22 @@ def _commit(self):
qubes_lvm(cmd, self.log)
self._remove_revisions()

cmd = ['remove', self.vid]
qubes_lvm(cmd, self.log)
cmd = ['clone', self._vid_snap, self.vid]
# TODO: when converting this function to coroutine, this _must_ be
# under a lock
# remove old volume only after _successful_ clone of the new one
cmd = ['rename', self.vid, self.vid + '-tmp']
qubes_lvm(cmd, self.log)
try:
cmd = ['clone', self._vid_snap, self.vid]
qubes_lvm(cmd, self.log)
except:
# restore original volume
cmd = ['rename', self.vid + '-tmp', self.vid]
qubes_lvm(cmd, self.log)
raise
else:
cmd = ['remove', self.vid + '-tmp']
qubes_lvm(cmd, self.log)


def create(self):
Expand Down Expand Up @@ -494,6 +506,8 @@ def qubes_lvm(cmd, log=logging.getLogger('qubes.storage.lvm')):
lvm_cmd = ["lvextend", "-L%s" % size, cmd[1]]
elif action == 'activate':
lvm_cmd = ['lvchange', '-ay', cmd[1]]
elif action == 'rename':
lvm_cmd = ['lvrename', cmd[1], cmd[2]]
else:
raise NotImplementedError('unsupported action: ' + action)
if lvm_is_very_old:
Expand Down

0 comments on commit 021047f

Please sign in to comment.