From 4c65a9c69a0202bc8f1080d9e68550093f19b739 Mon Sep 17 00:00:00 2001 From: Bahtiar `kalkin-` Gadimov Date: Sun, 28 Aug 2016 19:43:18 +0200 Subject: [PATCH 01/13] qvm-block refactor attach/detach sub_parser init --- qubes/tools/qvm_block.py | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/qubes/tools/qvm_block.py b/qubes/tools/qvm_block.py index 855370c2..fcf374ed 100644 --- a/qubes/tools/qvm_block.py +++ b/qubes/tools/qvm_block.py @@ -195,6 +195,25 @@ def init_revert_parser(sub_parsers): action=qubes.tools.VolumeAction) revert_parser.set_defaults(func=revert_volume) +def init_attach_parser(sub_parsers): + attach_parser = sub_parsers.add_parser( + 'attach', help="Attach volume to domain", aliases=('at', 'a')) + attach_parser.add_argument('--ro', help='attach device read-only', + action='store_true') + attach_parser.add_argument('VMNAME', action=qubes.tools.RunningVmNameAction) + attach_parser.add_argument(metavar='POOL_NAME:VOLUME_ID', dest='volume', + action=qubes.tools.VolumeAction) + attach_parser.set_defaults(func=attach_volumes) + + +def init_dettach_parser(sub_parsers): + detach_parser = sub_parsers.add_parser( + "detach", help="Detach volume from domain", aliases=('d', 'dt')) + detach_parser.add_argument('VMNAME', action=qubes.tools.RunningVmNameAction) + detach_parser.add_argument(metavar='POOL_NAME:VOLUME_ID', dest='volume', + action=qubes.tools.VolumeAction) + detach_parser.set_defaults(func=detach_volumes) + def get_parser(): '''Create :py:class:`argparse.ArgumentParser` suitable for @@ -206,22 +225,10 @@ def get_parser(): title='commands', description="For more information see qvm-block command -h", dest='command') + init_attach_parser(sub_parsers) + init_dettach_parser(sub_parsers) init_list_parser(sub_parsers) init_revert_parser(sub_parsers) - attach_parser = sub_parsers.add_parser( - 'attach', help="Attach volume to domain", aliases=('at', 'a')) - attach_parser.add_argument('--ro', help='attach device read-only', - action='store_true') - attach_parser.add_argument('VMNAME', action=qubes.tools.RunningVmNameAction) - attach_parser.add_argument(metavar='POOL_NAME:VOLUME_ID', dest='volume', - action=qubes.tools.VolumeAction) - attach_parser.set_defaults(func=attach_volumes) - detach_parser = sub_parsers.add_parser( - "detach", help="Detach volume from domain", aliases=('d', 'dt')) - detach_parser.add_argument('VMNAME', action=qubes.tools.RunningVmNameAction) - detach_parser.add_argument(metavar='POOL_NAME:VOLUME_ID', dest='volume', - action=qubes.tools.VolumeAction) - detach_parser.set_defaults(func=detach_volumes) return parser From 4733e836cecd14f878d1990abba7f46d652945f9 Mon Sep 17 00:00:00 2001 From: Bahtiar `kalkin-` Gadimov Date: Sun, 28 Aug 2016 19:44:39 +0200 Subject: [PATCH 02/13] qvm-block add extend sub command --- qubes/tools/qvm_block.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/qubes/tools/qvm_block.py b/qubes/tools/qvm_block.py index fcf374ed..5affef4b 100644 --- a/qubes/tools/qvm_block.py +++ b/qubes/tools/qvm_block.py @@ -24,6 +24,7 @@ from __future__ import print_function +import re import sys import qubes @@ -168,6 +169,34 @@ def detach_volumes(args): sys.exit(1) +def extend_volumes(args): + ''' Called by the parser to execute the :program:`qvm-block extend` + subcommand + ''' + volume = args.volume + app = args.app + try: + size = int(args.size.strip()) + except ValueError: + if re.match(r'^(\d+[kgm])$', args.size.strip(), re.IGNORECASE): + size = int(args.size.strip()[:-1]) + factor = args.size.strip()[-1:] + elif re.match(r'^(\d+[kgm][B])$', args.size.strip(), re.IGNORECASE): + size = int(args.size.strip()[:-2]) + factor = args.size.strip()[-2:-1] + else: + print("Unknown size %s" % args.size, file=sys.stderr) + sys.exit(1) + if factor == "K": + size *= 1000 + elif factor == "M": + size *= 1000 * 1000 + elif factor == "G": + size *= 1000 * 1000 * 1000 + pool = app.get_pool(volume.pool) + pool.resize(volume, volume.size+size) + app.save() + def init_list_parser(sub_parsers): ''' Configures the parser for the :program:`qvm-block list` subcommand ''' # pylint: disable=protected-access @@ -214,6 +243,14 @@ def init_dettach_parser(sub_parsers): action=qubes.tools.VolumeAction) detach_parser.set_defaults(func=detach_volumes) +def init_extend_parser(sub_parsers): + extend_parser = sub_parsers.add_parser( + "extend", help="extend volume from domain", aliases=('d', 'dt')) + extend_parser.add_argument(metavar='POOL_NAME:VOLUME_ID', dest='volume', + action=qubes.tools.VolumeAction) + extend_parser.add_argument( + 'size', help='size in bytes of the new ThinPoolLogicalVolume') + extend_parser.set_defaults(func=extend_volumes) def get_parser(): '''Create :py:class:`argparse.ArgumentParser` suitable for @@ -227,6 +264,7 @@ def get_parser(): dest='command') init_attach_parser(sub_parsers) init_dettach_parser(sub_parsers) + init_extend_parser(sub_parsers) init_list_parser(sub_parsers) init_revert_parser(sub_parsers) From e7caa14a85cd4d70847a5d062f96cefe505e1f8c Mon Sep 17 00:00:00 2001 From: Bahtiar `kalkin-` Gadimov Date: Sun, 28 Aug 2016 19:51:33 +0200 Subject: [PATCH 03/13] Fix file storage resize --- qubes/storage/file.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qubes/storage/file.py b/qubes/storage/file.py index e8864779..9bf8a20b 100644 --- a/qubes/storage/file.py +++ b/qubes/storage/file.py @@ -136,6 +136,7 @@ class FilePool(qubes.storage.Pool): # resize loop device subprocess.check_call(['sudo', 'losetup', '--set-capacity', loop_dev]) + volume.size = size def remove(self, volume): if not volume.internal: From 53c8324f17bbc17d1b7777866fd9d5e0ff752547 Mon Sep 17 00:00:00 2001 From: Bahtiar `kalkin-` Gadimov Date: Sun, 28 Aug 2016 23:59:02 +0200 Subject: [PATCH 04/13] Document qubes-block extend command in the manpage --- doc/manpages/qvm-block.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/manpages/qvm-block.rst b/doc/manpages/qvm-block.rst index be8fa65f..4cc2b2fc 100644 --- a/doc/manpages/qvm-block.rst +++ b/doc/manpages/qvm-block.rst @@ -86,6 +86,12 @@ Detach the volume with *POOL_NAME:VOLUME_ID* from domain *VMNAME* aliases: d, dt +extend +^^^^^^ +| :command:`qvm-block extend` [-h] [--verbose] [--quiet] *POOL_NAME:VOLUME_ID* *SIZE* + +Extends the volume with *POOL_NAME:VOLUME_ID* BY *SIZE* bytes + revert ^^^^^^ From 0561dfce604543f3a19515df0b44cdc0fb045d51 Mon Sep 17 00:00:00 2001 From: Bahtiar `kalkin-` Gadimov Date: Sun, 28 Aug 2016 20:06:11 +0200 Subject: [PATCH 05/13] Add ThinPool.resize() --- qubes/storage/lvm.py | 20 ++++++++++++++++++++ qubes/tools/qubes_lvm.py | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/qubes/storage/lvm.py b/qubes/storage/lvm.py index 5aad339a..04d3fe71 100644 --- a/qubes/storage/lvm.py +++ b/qubes/storage/lvm.py @@ -192,6 +192,26 @@ class ThinPool(qubes.storage.Pool): qubes_lvm(cmd, self.log) return volume + def resize(self, volume, size): + ''' Expands volume, throws + :py:class:`qubst.storage.qubes.storage.StoragePoolException` if + given size is less than current_size + ''' + if not volume.rw: + msg = 'Can not resize reađonly volume {!s}'.format(volume) + raise qubes.storage.StoragePoolException(msg) + + if size <= volume.size: + raise qubes.storage.StoragePoolException( + 'For your own safety, shrinking of %s is' + ' disabled. If you really know what you' + ' are doing, use `truncate` on %s manually.' % + (volume.name, volume.vid)) + + cmd = ['extend', volume.vid, str(size)] + qubes_lvm(cmd, self.log) + volume.size += size + def _reset(self, volume): try: self.remove(volume) diff --git a/qubes/tools/qubes_lvm.py b/qubes/tools/qubes_lvm.py index 33b4ef4e..cc95ffb0 100644 --- a/qubes/tools/qubes_lvm.py +++ b/qubes/tools/qubes_lvm.py @@ -127,6 +127,21 @@ def rename_volume(old_name, new_name): return new_name +def extend_volume(args): + ''' Extends an existing lvm volume. Note this works on any lvm volume not + only thin volumes. + ''' + vid = args.name + size = int(args.size) / ( 1000 * 1000) + log.debug("Extending LVM %s to %s", vid, size) + cmd = ["lvextend", "-L+%s" % size, vid] + log.debug(cmd) + retcode = subprocess.call(cmd) + if retcode != 0: + raise IOError("Error extending LVM %s to %s " % (vid, size)) + return 0 + + def init_pool_parser(sub_parsers): ''' Initialize pool subparser ''' pool_parser = sub_parsers.add_parser( @@ -219,6 +234,17 @@ def init_remove_parser(sub_parsers): remove_parser.set_defaults(func=remove_volume) +def init_extend_parser(sub_parsers): + ''' Initialize extend subparser ''' + extend_parser = sub_parsers.add_parser('extend', + help='extends a LogicalVolume') + extend_parser.add_argument('name', metavar='VG/VID', + help='volume_group/volume_name') + extend_parser.set_defaults(func=extend_volume) + extend_parser.add_argument( + 'size', help='size in bytes of the new ThinPoolLogicalVolume') + + def get_parser(): '''Create :py:class:`argparse.ArgumentParser` suitable for :program:`qubes-lvm`. @@ -230,12 +256,13 @@ def get_parser(): title='commands', description="For more information see qubes-lvm command -h", dest='command') - init_pool_parser(sub_parsers) + init_clone_parser(sub_parsers) + init_extend_parser(sub_parsers) init_import_parser(sub_parsers) init_new_parser(sub_parsers) - init_volumes_parser(sub_parsers) + init_pool_parser(sub_parsers) init_remove_parser(sub_parsers) - init_clone_parser(sub_parsers) + init_volumes_parser(sub_parsers) return parser From 1ca3c0079724ead46b93f946cd8fd6faeb66831f Mon Sep 17 00:00:00 2001 From: Bahtiar `kalkin-` Gadimov Date: Sun, 28 Aug 2016 23:50:04 +0200 Subject: [PATCH 06/13] Fix lvm size/usage - Uses a size_cache, because it's faster than doing a call for each volume --- qubes/storage/lvm.py | 62 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/qubes/storage/lvm.py b/qubes/storage/lvm.py index 04d3fe71..b1d557d1 100644 --- a/qubes/storage/lvm.py +++ b/qubes/storage/lvm.py @@ -32,6 +32,8 @@ class ThinPool(qubes.storage.Pool): ''' LVM Thin based pool implementation ''' # pylint: disable=protected-access + size_cache = None + driver = 'lvm_thin' def __init__(self, volume_group, thin_pool, revisions_to_keep=1, **kwargs): @@ -90,6 +92,7 @@ class ThinPool(qubes.storage.Pool): str(volume.size) ] qubes_lvm(cmd, self.log) + reset_cache() return volume def destroy(self): @@ -146,6 +149,7 @@ class ThinPool(qubes.storage.Pool): dst.write(tmp) p.stdin.close() p.wait() + reset_cache() return dst_volume def is_dirty(self, volume): @@ -161,6 +165,7 @@ class ThinPool(qubes.storage.Pool): cmd = ['remove', volume.vid] qubes_lvm(cmd, self.log) + reset_cache() def rename(self, volume, old_name, new_name): ''' Called when the domain changes its name ''' @@ -179,6 +184,7 @@ class ThinPool(qubes.storage.Pool): if not volume._is_volatile: volume._vid_snap = volume.vid + '-snap' return volume + reset_cache() def revert(self, volume, revision=None): old_path = volume.path + '-back' @@ -190,6 +196,7 @@ class ThinPool(qubes.storage.Pool): qubes_lvm(cmd, self.log) cmd = ['clone', volume.vid + '-back', volume.vid] qubes_lvm(cmd, self.log) + reset_cache() return volume def resize(self, volume, size): @@ -210,7 +217,7 @@ class ThinPool(qubes.storage.Pool): cmd = ['extend', volume.vid, str(size)] qubes_lvm(cmd, self.log) - volume.size += size + reset_cache() def _reset(self, volume): try: @@ -232,6 +239,7 @@ class ThinPool(qubes.storage.Pool): if not self.is_dirty(volume): self._snapshot(volume) + reset_cache return volume def stop(self, volume): @@ -244,6 +252,7 @@ class ThinPool(qubes.storage.Pool): else: cmd = ['remove', volume._vid_snap] qubes_lvm(cmd, self.log) + reset_cache() return volume def _snapshot(self, volume): @@ -301,10 +310,41 @@ class ThinPool(qubes.storage.Pool): str(volume.size)] qubes_lvm(cmd, self.log) + +def init_cache(log=logging.getLogger('qube.storage.lvm')): + cmd = ['sudo', 'lvs', '--noheadings', '-o', + 'vg_name,name,lv_size,data_percent', '--units', 'b', '--separator', + ','] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = p.communicate() + return_code = p.returncode + if return_code == 0 and err: + log.warning(err) + elif return_code != 0: + raise qubes.storage.StoragePoolException(err) + + result = {} + + for l in out.splitlines(): + l = l.strip() + pool_name, name, size, usage_percent = l.split(',', 3) + if '' in [pool_name, name, size, usage_percent]: + continue + name = pool_name + "/" + name + size = int(size[:-1]) + usage = int(size / 100 * float(usage_percent)) + result[name] = {'size':size, 'usage': usage} + + return result + + +size_cache = init_cache() + class ThinVolume(qubes.storage.Volume): ''' Default LVM thin volume implementation ''' # pylint: disable=too-few-public-methods + def __init__(self, volume_group, **kwargs): self.volume_group = volume_group super(ThinVolume, self).__init__(**kwargs) @@ -347,6 +387,22 @@ class ThinVolume(qubes.storage.Volume): def _is_volatile(self): return not self.snap_on_start and not self.save_on_stop + @property + def size(self): + try: + return qubes.storage.lvm.size_cache[self.vid]['size'] + except KeyError: + return self._size + + @property + def usage(self): # lvm thin usage always returns at least the same usage as + # the parent + try: + return qubes.storage.lvm.size_cache[self.vid]['usage'] + except KeyError: + return 0 + + def pool_exists(pool_id): ''' Return true if pool exists ''' cmd = ['pool', pool_id] @@ -369,3 +425,7 @@ def qubes_lvm(cmd, log=logging.getLogger('qube.storage.lvm')): assert err, "Command exited unsuccessful, but printed nothing to stderr" raise qubes.storage.StoragePoolException(err) return True + + +def reset_cache(log=logging.getLogger('qube.storage.lvm')): + qubes.storage.lvm.size_cache = init_cache From 818ed20248cdaababf05a7d15513921cbec97af9 Mon Sep 17 00:00:00 2001 From: Bahtiar `kalkin-` Gadimov Date: Fri, 2 Sep 2016 19:17:00 +0200 Subject: [PATCH 07/13] =?UTF-8?q?Make=20pylint=20happy=20=E2=99=A5=20qubes?= =?UTF-8?q?=5Flvm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qubes/tools/qubes_lvm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qubes/tools/qubes_lvm.py b/qubes/tools/qubes_lvm.py index cc95ffb0..28295945 100644 --- a/qubes/tools/qubes_lvm.py +++ b/qubes/tools/qubes_lvm.py @@ -132,7 +132,7 @@ def extend_volume(args): only thin volumes. ''' vid = args.name - size = int(args.size) / ( 1000 * 1000) + size = int(args.size) / (1000 * 1000) log.debug("Extending LVM %s to %s", vid, size) cmd = ["lvextend", "-L+%s" % size, vid] log.debug(cmd) From 1cf701ff6090bf48dc4870bfffce4ddb00734f30 Mon Sep 17 00:00:00 2001 From: Bahtiar `kalkin-` Gadimov Date: Fri, 2 Sep 2016 19:21:04 +0200 Subject: [PATCH 08/13] qvm-block extend use qubes.utils.parse_size --- qubes/tools/qvm_block.py | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/qubes/tools/qvm_block.py b/qubes/tools/qvm_block.py index 5affef4b..1c295cef 100644 --- a/qubes/tools/qvm_block.py +++ b/qubes/tools/qvm_block.py @@ -24,12 +24,12 @@ from __future__ import print_function -import re import sys import qubes import qubes.exc import qubes.tools +import qubes.utils def prepare_table(vd_list, full=False): @@ -175,24 +175,7 @@ def extend_volumes(args): ''' volume = args.volume app = args.app - try: - size = int(args.size.strip()) - except ValueError: - if re.match(r'^(\d+[kgm])$', args.size.strip(), re.IGNORECASE): - size = int(args.size.strip()[:-1]) - factor = args.size.strip()[-1:] - elif re.match(r'^(\d+[kgm][B])$', args.size.strip(), re.IGNORECASE): - size = int(args.size.strip()[:-2]) - factor = args.size.strip()[-2:-1] - else: - print("Unknown size %s" % args.size, file=sys.stderr) - sys.exit(1) - if factor == "K": - size *= 1000 - elif factor == "M": - size *= 1000 * 1000 - elif factor == "G": - size *= 1000 * 1000 * 1000 + size = qubes.utils.parse_size(args.size) pool = app.get_pool(volume.pool) pool.resize(volume, volume.size+size) app.save() From 8974b2cbc09715d81aebd57a402eb02b5ecd7f85 Mon Sep 17 00:00:00 2001 From: Bahtiar `kalkin-` Gadimov Date: Fri, 2 Sep 2016 19:45:31 +0200 Subject: [PATCH 09/13] Fix ThinVolume _size access --- qubes/storage/lvm.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qubes/storage/lvm.py b/qubes/storage/lvm.py index b1d557d1..dddb852f 100644 --- a/qubes/storage/lvm.py +++ b/qubes/storage/lvm.py @@ -345,9 +345,9 @@ class ThinVolume(qubes.storage.Volume): ''' # pylint: disable=too-few-public-methods - def __init__(self, volume_group, **kwargs): + def __init__(self, volume_group, size=0, **kwargs): self.volume_group = volume_group - super(ThinVolume, self).__init__(**kwargs) + super(ThinVolume, self).__init__(size=size, **kwargs) if self.snap_on_start and self.source is None: msg = "snap_on_start specified on {!r} but no volume source set" @@ -362,6 +362,8 @@ class ThinVolume(qubes.storage.Volume): if not self._is_volatile: self._vid_snap = self.vid + '-snap' + self._size = size + @property def revisions(self): path = self.path + '-back' From be48d48e56b5350ef5a923971e641615f2a536b9 Mon Sep 17 00:00:00 2001 From: Bahtiar `kalkin-` Gadimov Date: Fri, 2 Sep 2016 19:46:11 +0200 Subject: [PATCH 10/13] =?UTF-8?q?Make=20pylint=20happy=20=E2=99=A5=20qubes?= =?UTF-8?q?.storage.lvm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- qubes/storage/lvm.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qubes/storage/lvm.py b/qubes/storage/lvm.py index dddb852f..e105ef15 100644 --- a/qubes/storage/lvm.py +++ b/qubes/storage/lvm.py @@ -325,9 +325,9 @@ def init_cache(log=logging.getLogger('qube.storage.lvm')): result = {} - for l in out.splitlines(): - l = l.strip() - pool_name, name, size, usage_percent = l.split(',', 3) + for line in out.splitlines(): + line = line.strip() + pool_name, name, size, usage_percent = line.split(',', 3) if '' in [pool_name, name, size, usage_percent]: continue name = pool_name + "/" + name @@ -429,5 +429,5 @@ def qubes_lvm(cmd, log=logging.getLogger('qube.storage.lvm')): return True -def reset_cache(log=logging.getLogger('qube.storage.lvm')): +def reset_cache(): qubes.storage.lvm.size_cache = init_cache From dcfc47fefe5e1ac22cf2bf5b61e771362897de8a Mon Sep 17 00:00:00 2001 From: Bahtiar `kalkin-` Gadimov Date: Fri, 2 Sep 2016 19:55:54 +0200 Subject: [PATCH 11/13] qvm-block extends volumes to NEW_SIZE --- doc/manpages/qvm-block.rst | 4 ++-- qubes/tools/qubes_lvm.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/manpages/qvm-block.rst b/doc/manpages/qvm-block.rst index 4cc2b2fc..fb340d24 100644 --- a/doc/manpages/qvm-block.rst +++ b/doc/manpages/qvm-block.rst @@ -88,9 +88,9 @@ aliases: d, dt extend ^^^^^^ -| :command:`qvm-block extend` [-h] [--verbose] [--quiet] *POOL_NAME:VOLUME_ID* *SIZE* +| :command:`qvm-block extend` [-h] [--verbose] [--quiet] *POOL_NAME:VOLUME_ID* *NEW_SIZE* -Extends the volume with *POOL_NAME:VOLUME_ID* BY *SIZE* bytes +Extend the volume with *POOL_NAME:VOLUME_ID* TO *NEW_SIZE* revert ^^^^^^ diff --git a/qubes/tools/qubes_lvm.py b/qubes/tools/qubes_lvm.py index 28295945..8ad9627c 100644 --- a/qubes/tools/qubes_lvm.py +++ b/qubes/tools/qubes_lvm.py @@ -129,12 +129,12 @@ def rename_volume(old_name, new_name): def extend_volume(args): ''' Extends an existing lvm volume. Note this works on any lvm volume not - only thin volumes. + only on thin volumes. ''' vid = args.name size = int(args.size) / (1000 * 1000) log.debug("Extending LVM %s to %s", vid, size) - cmd = ["lvextend", "-L+%s" % size, vid] + cmd = ["lvextend", "-L%s" % size, vid] log.debug(cmd) retcode = subprocess.call(cmd) if retcode != 0: From 46eb4a72ddf8ac8a532994319422e6688518c2b2 Mon Sep 17 00:00:00 2001 From: Bahtiar `kalkin-` Gadimov Date: Fri, 2 Sep 2016 19:57:35 +0200 Subject: [PATCH 12/13] Fix a few typo bugs in qubes.storage.lvm --- qubes/storage/lvm.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qubes/storage/lvm.py b/qubes/storage/lvm.py index e105ef15..44049151 100644 --- a/qubes/storage/lvm.py +++ b/qubes/storage/lvm.py @@ -183,8 +183,8 @@ class ThinPool(qubes.storage.Pool): if not volume._is_volatile: volume._vid_snap = volume.vid + '-snap' - return volume reset_cache() + return volume def revert(self, volume, revision=None): old_path = volume.path + '-back' @@ -212,7 +212,7 @@ class ThinPool(qubes.storage.Pool): raise qubes.storage.StoragePoolException( 'For your own safety, shrinking of %s is' ' disabled. If you really know what you' - ' are doing, use `truncate` on %s manually.' % + ' are doing, use `lvresize` on %s manually.' % (volume.name, volume.vid)) cmd = ['extend', volume.vid, str(size)] @@ -239,7 +239,7 @@ class ThinPool(qubes.storage.Pool): if not self.is_dirty(volume): self._snapshot(volume) - reset_cache + reset_cache() return volume def stop(self, volume): From 5f586a99d4b1637d171ede5800800aaf664ea937 Mon Sep 17 00:00:00 2001 From: Bahtiar `kalkin-` Gadimov Date: Sun, 4 Sep 2016 21:01:16 +0200 Subject: [PATCH 13/13] qvm-block extend Fix help message --- qubes/tools/qvm_block.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qubes/tools/qvm_block.py b/qubes/tools/qvm_block.py index 1c295cef..fff2e44e 100644 --- a/qubes/tools/qvm_block.py +++ b/qubes/tools/qvm_block.py @@ -231,8 +231,7 @@ def init_extend_parser(sub_parsers): "extend", help="extend volume from domain", aliases=('d', 'dt')) extend_parser.add_argument(metavar='POOL_NAME:VOLUME_ID', dest='volume', action=qubes.tools.VolumeAction) - extend_parser.add_argument( - 'size', help='size in bytes of the new ThinPoolLogicalVolume') + extend_parser.add_argument('size', help='New size in bytes') extend_parser.set_defaults(func=extend_volumes) def get_parser():