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 rw = False
def __init__(self, target_dir, kernel_version, **kwargs): def __init__(self, target_dir, kernel_version, **kwargs):
kwargs['vid'] = kernel_version kwargs['vid'] = ''
kwargs['source'] = self kwargs['source'] = self
super(LinuxModules, self).__init__(**kwargs) super(LinuxModules, self).__init__(**kwargs)
self.kernels_dir = os.path.join(target_dir, kernel_version) self._kernel_version = kernel_version
self.path = os.path.join(self.kernels_dir, 'modules.img') self.target_dir = target_dir
self.vmlinuz = os.path.join(self.kernels_dir, 'vmlinuz')
self.initramfs = os.path.join(self.kernels_dir, 'initramfs') @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 @property
def revisions(self): def revisions(self):
return {} return {}
def block_device(self):
if self.vid is not None:
return super().block_device()
class LinuxKernel(Pool): class LinuxKernel(Pool):
''' Provides linux kernels ''' ''' Provides linux kernels '''
driver = 'linux-kernel' driver = 'linux-kernel'
@ -56,7 +98,7 @@ class LinuxKernel(Pool):
def init_volume(self, vm, volume_config): def init_volume(self, vm, volume_config):
assert not volume_config['rw'] 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 return volume
@ -103,7 +145,7 @@ class LinuxKernel(Pool):
def start(self, volume): def start(self, volume):
path = volume.path path = volume.path
if not os.path.exists(path): if path and not os.path.exists(path):
raise StoragePoolException('Missing kernel modules: %s' % path) raise StoragePoolException('Missing kernel modules: %s' % path)
return volume return volume
@ -112,9 +154,10 @@ class LinuxKernel(Pool):
pass pass
def verify(self, volume): def verify(self, volume):
_check_path(volume.path) if volume.vid is not None:
_check_path(volume.vmlinuz) _check_path(volume.path)
_check_path(volume.initramfs) _check_path(volume.vmlinuz)
_check_path(volume.initramfs)
@property @property
def volumes(self): 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 ''' Return all :py:class:`qubes.storage.BlockDevice`s for current domain
for serialization in the libvirt XML template as <disk>. 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 @property
def qdb(self): def qdb(self):