From 46b60dbf42cb9f04a5c00e4d466ff5a4cc7d32b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Tue, 23 May 2017 15:35:55 +0200 Subject: [PATCH] storage: add Pool.import_data to the API Allow importing not only from another volume, but also raw data. In practice, for all currently implemented storage pools, this is the same as Pool.export, because path returned there is read-write. But lets not abuse this fact, some future implementation may need different methods. QubesOS/qubes-issues#2622 QubesOS/qubes-issues#2256 --- qubes/storage/__init__.py | 18 ++++++++++++++++++ qubes/storage/file.py | 3 +++ qubes/storage/lvm.py | 9 +++++---- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/qubes/storage/__init__.py b/qubes/storage/__init__.py index 96697792..2d818114 100644 --- a/qubes/storage/__init__.py +++ b/qubes/storage/__init__.py @@ -544,6 +544,15 @@ class Storage(object): return self.pools[volume].export(self.vm.volumes[volume]) + def import_data(self, volume): + ''' Helper function to import volume data (pool.import_data(volume))''' + assert isinstance(volume, (Volume, str)), \ + "You need to pass a Volume or pool name as str" + if isinstance(volume, Volume): + return self.pools[volume.name].import_data(volume) + + return self.pools[volume].import_data(self.vm.volumes[volume]) + class Pool(object): ''' A Pool is used to manage different kind of volumes (File @@ -614,6 +623,15 @@ class Pool(object): ''' Returns an object that can be `open()`. ''' raise self._not_implemented("export") + def import_data(self, volume): + ''' Returns an object that can be `open()`. + + Storage implementation may register for + `domain-volume-import-end` event to cleanup after this. The + event will have also success=True|False information. + ''' + raise self._not_implemented("import") + def import_volume(self, dst_pool, dst_volume, src_pool, src_volume): ''' Imports data to a volume in this pool ''' raise self._not_implemented("import_volume") diff --git a/qubes/storage/file.py b/qubes/storage/file.py index 6ab47283..98f4ce12 100644 --- a/qubes/storage/file.py +++ b/qubes/storage/file.py @@ -198,6 +198,9 @@ class FilePool(qubes.storage.Pool): def export(self, volume): return volume.path + def import_data(self, volume): + return volume.path + def reset(self, volume): ''' Remove and recreate a volatile volume ''' assert volume._is_volatile, "Not a volatile volume" diff --git a/qubes/storage/lvm.py b/qubes/storage/lvm.py index 77d9995d..0edf321a 100644 --- a/qubes/storage/lvm.py +++ b/qubes/storage/lvm.py @@ -114,10 +114,11 @@ class ThinPool(qubes.storage.Pool): def export(self, volume): ''' Returns an object that can be `open()`. ''' devpath = '/dev/' + volume.vid - if not os.access(devpath, os.R_OK): - # FIXME: convert to udev rules, and drop after introducing qubesd - subprocess.check_call(['sudo', 'chgrp', 'qubes', devpath]) - subprocess.check_call(['sudo', 'chmod', 'g+rw', devpath]) + return devpath + + def import_data(self, volume): + ''' Returns an object that can be `open()`. ''' + devpath = '/dev/' + volume.vid return devpath def init_volume(self, vm, volume_config):