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
This commit is contained in:
Marek Marczykowski-Górecki 2017-05-23 15:35:55 +02:00
parent 1692601fcd
commit 46b60dbf42
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
3 changed files with 26 additions and 4 deletions

View File

@ -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")

View File

@ -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"

View File

@ -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):