storage: make LinuxKernel pool track vm kernel version

Do not initialize it only at qubes.xml load time, but re-read vm.kernel
property each time the path is constructed. While at it, add support for
vm.kernel set to 'None' - simply don't include modules.img (xvdd) then.
This commit is contained in:
Marek Marczykowski-Górecki 2017-05-17 01:37:59 +02:00
parent 595d983659
commit 0b64e3fbe0
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
2 changed files with 57 additions and 11 deletions

View File

@ -32,18 +32,60 @@ class LinuxModules(Volume):
rw = False
def __init__(self, target_dir, kernel_version, **kwargs):
kwargs['vid'] = kernel_version
kwargs['vid'] = ''
kwargs['source'] = self
super(LinuxModules, self).__init__(**kwargs)
self.kernels_dir = os.path.join(target_dir, kernel_version)
self.path = os.path.join(self.kernels_dir, 'modules.img')
self.vmlinuz = os.path.join(self.kernels_dir, 'vmlinuz')
self.initramfs = os.path.join(self.kernels_dir, 'initramfs')
self._kernel_version = kernel_version
self.target_dir = target_dir
@property
def vid(self):
if callable(self._kernel_version):
return self._kernel_version()
return self._kernel_version
@vid.setter
def vid(self, value):
# ignore
pass
@property
def kernels_dir(self):
kernel_version = self.vid
if kernel_version is None:
return None
return os.path.join(self.target_dir, kernel_version)
@property
def path(self):
kernels_dir = self.kernels_dir
if kernels_dir is None:
return None
return os.path.join(kernels_dir, 'modules.img')
@property
def vmlinuz(self):
kernels_dir = self.kernels_dir
if kernels_dir is None:
return None
return os.path.join(kernels_dir, 'vmlinuz')
@property
def initramfs(self):
kernels_dir = self.kernels_dir
if kernels_dir is None:
return None
return os.path.join(kernels_dir, 'initramfs')
@property
def revisions(self):
return {}
def block_device(self):
if self.vid is not None:
return super().block_device()
class LinuxKernel(Pool):
''' Provides linux kernels '''
driver = 'linux-kernel'
@ -56,7 +98,7 @@ class LinuxKernel(Pool):
def init_volume(self, vm, volume_config):
assert not volume_config['rw']
volume = LinuxModules(self.dir_path, vm.kernel, **volume_config)
volume = LinuxModules(self.dir_path, lambda: vm.kernel, **volume_config)
return volume
@ -103,7 +145,7 @@ class LinuxKernel(Pool):
def start(self, volume):
path = volume.path
if not os.path.exists(path):
if path and not os.path.exists(path):
raise StoragePoolException('Missing kernel modules: %s' % path)
return volume
@ -112,9 +154,10 @@ class LinuxKernel(Pool):
pass
def verify(self, volume):
_check_path(volume.path)
_check_path(volume.vmlinuz)
_check_path(volume.initramfs)
if volume.vid is not None:
_check_path(volume.path)
_check_path(volume.vmlinuz)
_check_path(volume.initramfs)
@property
def volumes(self):

View File

@ -607,7 +607,10 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
''' Return all :py:class:`qubes.storage.BlockDevice`s for current domain
for serialization in the libvirt XML template as <disk>.
'''
return [v.block_device() for v in self.volumes.values()]
for v in self.volumes.values():
block_dev = v.block_device()
if block_dev is not None:
yield block_dev
@property
def qdb(self):