Skip to content

Commit

Permalink
lvm2 pool: Export immutable snapshot of volume
Browse files Browse the repository at this point in the history
Volumes returned by `export()` must be immutable, since otherwise the
backup will be inconsistent.  Ensure this by exporting a snapshot of the
volume, no the volume itself.

Fixes QubesOS/qubes-issues#7198.

FIXME: tests
  • Loading branch information
DemiMarie committed Apr 1, 2022
1 parent 067b493 commit 5aaf30f
Showing 1 changed file with 22 additions and 5 deletions.
27 changes: 22 additions & 5 deletions qubes/storage/lvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,9 @@ def __init__(self, volume_group, **kwargs):
self._vid_snap = self.vid + '-snap'
if self.save_on_stop:
self._vid_import = self.vid + '-import'
path_export = self._path_export
if os.path.exists(path_export):
subprocess.check_call(_get_lvm_cmdline(['remove', path_export]))

@property
def path(self):
Expand Down Expand Up @@ -470,13 +473,27 @@ async def remove(self):
# pylint: disable=protected-access
self.pool._volume_objects_cache.pop(self.vid, None)

async def export(self):
@property
def _vid_export(self) -> str:
return self.vid + '+export'

@property
def _path_export(self) -> str:
return '/dev/' + self._vid_export

async def export(self) -> str:
''' Returns an object that can be `open()`. '''
# make sure the device node is available
cmd = ['activate', self.path]
await qubes_lvm_coro(cmd, self.log)
devpath = self.path
return devpath
vid_export = self._vid_export
export_path = self._path_export
if not os.path.exists(export_path):
cmd = ['clone', self._vid_current, vid_export]
await qubes_lvm_coro(cmd, self.log)
return export_path

async def export_end(self, path: str) -> None:
assert path == self._vid_export, 'Refusing to remove incorrect path'
await qubes_lvm_coro(['remove', path], self.log)

@qubes.storage.Volume.locked
async def import_volume(self, src_volume):
Expand Down

0 comments on commit 5aaf30f

Please sign in to comment.