diff --git a/qubes/storage/__init__.py b/qubes/storage/__init__.py index 64d97329..c8d1305e 100644 --- a/qubes/storage/__init__.py +++ b/qubes/storage/__init__.py @@ -177,6 +177,8 @@ class Storage(object): raise qubes.exc.QubesVMError( self.vm, 'VM directory does not exist: {}'.format(self.vm.dir_path)) + for volume in self.vm.volumes.values(): + self.get_pool(volume).verify(volume) def remove(self): ''' Remove all the volumes. @@ -287,6 +289,11 @@ class Pool(object): raise NotImplementedError("Pool %s has init_volume() not implemented" % self.name) + def verify(self, volume): + ''' Verifies the volume. ''' + raise NotImplementedError("Pool %s has verify() not implemented" % + self.name) + def pool_drivers(): """ Return a list of EntryPoints names """ diff --git a/qubes/storage/file.py b/qubes/storage/file.py index 5b5e04db..d9e41eea 100644 --- a/qubes/storage/file.py +++ b/qubes/storage/file.py @@ -261,6 +261,12 @@ class FilePool(Pool): return known_types[volume_type](**volume_config) + def verify(self, volume): + return volume.verify() + + def verify(self, volume): + return volume.verify() + class FileVolume(Volume): ''' Parent class for the xen volumes implementation which expects a @@ -306,6 +312,7 @@ class SizeMixIn(FileVolume): class ReadWriteFile(SizeMixIn): ''' Represents a readable & writable file image based volume ''' + def __init__(self, **kwargs): super(ReadWriteFile, self).__init__(**kwargs) self.path = os.path.join(self.target_dir, self.name + '.img') @@ -323,6 +330,11 @@ class ReadWriteFile(SizeMixIn): self.path = new_path self.vid = self.path + def verify(self): + ''' Verifies the volume. ''' + if not os.path.exists(self.path): + raise StoragePoolException('Missing image file: %s' % self.path) + class ReadOnlyFile(FileVolume): ''' Represents a readonly file image based volume ''' @@ -351,6 +363,11 @@ class ReadOnlyFile(FileVolume): self.path = new_path self.vid = self.path + def verify(self): + ''' Verifies the volume. ''' + if not os.path.exists(self.path): + raise StoragePoolException('Missing image file: %s' % self.path) + class OriginFile(SizeMixIn): ''' Represents a readable, writeable & snapshotable file image based volume. @@ -396,6 +413,12 @@ class OriginFile(SizeMixIn): result += get_disk_usage(self.path_cow) return result + def verify(self): + ''' Verifies the volume. ''' + if not os.path.exists(self.path_origin): + raise StoragePoolException('Missing image file: %s' % + self.path_origin) + class SnapshotFile(FileVolume): ''' Represents a readonly snapshot of an :py:class:`OriginFile` volume ''' @@ -411,6 +434,12 @@ class SnapshotFile(FileVolume): self.path = '%s:%s' % (self.path_origin, self.path_cow) self.vid = self.path_origin + def verify(self): + ''' Verifies the volume. ''' + if not os.path.exists(self.path_origin): + raise StoragePoolException('Missing image file: %s' % + self.path_origin) + class VolatileFile(SizeMixIn): ''' Represents a readable & writeable file based volume, which will be @@ -432,6 +461,11 @@ class VolatileFile(SizeMixIn): self.path = new_path self.vid = self.path + def verify(self): + ''' Verifies the volume. ''' + pass + + def create_sparse_file(path, size): ''' Create an empty sparse file ''' if os.path.exists(path): diff --git a/qubes/storage/kernels.py b/qubes/storage/kernels.py index f524849c..f07e0aad 100644 --- a/qubes/storage/kernels.py +++ b/qubes/storage/kernels.py @@ -58,10 +58,6 @@ class LinuxKernel(Pool): volume = LinuxModules(self.dir_path, vm.kernel, **volume_config) - _check_path(volume.path) - _check_path(volume.vmlinuz) - _check_path(volume.initramfs) - return volume def clone(self, source, target): @@ -103,6 +99,11 @@ class LinuxKernel(Pool): def stop(self, volume): pass + def verify(self, volume): + _check_path(volume.path) + _check_path(volume.vmlinuz) + _check_path(volume.initramfs) + @property def volumes(self): ''' Return all known kernel volumes '''