From: Patrik Martinsson <martinsson.patrik@xxxxxxxxx> This commit simply adds the '--force' flag to the blockresize command to prevent accidental shrinking of a block device. Similar behaviour is already present on the vol-resize command and it makes sense to mimic it. Implemented in virsh and not in the API. This is to prevent existing applications using the BlockResize-API from 'breaking'. Signed-off-by: Patrik Martinsson <martinsson.patrik@xxxxxxxxx> --- docs/news.xml | 13 +++++++++++++ tools/virsh-domain.c | 34 +++++++++++++++++++++++++++++++--- tools/virsh.pod | 6 +++++- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/docs/news.xml b/docs/news.xml index c8d55e357b..595d63137a 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -61,6 +61,19 @@ </change> </section> <section title="Improvements"> + <change> + <summary> + virsh: Add --force to the blockresize command + </summary> + <description> + To prevent accidental shrinking of a block device the --force flag + is introduced for the blockresize command, similar to the --shrink + flag for the vol-resize command. If you intend to shrink a block + device with <code> virsh blockresize</code>, you must now include + --force, otherwise the command will fail with an error. This change + is only in virsh, not in the API. + </description> + </change> </section> <section title="Bug fixes"> <change> diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 2f3ac2d430..412b7e4028 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -2920,6 +2920,10 @@ static const vshCmdOptDef opts_blockresize[] = { .flags = VSH_OFLAG_REQ, .help = N_("New size of the block device, as scaled integer (default KiB)") }, + {.name = "force", + .type = VSH_OT_BOOL, + .help = N_("Allow the resize to shrink the blockdevice") + }, {.name = NULL} }; @@ -2927,10 +2931,12 @@ static bool cmdBlockresize(vshControl *ctl, const vshCmd *cmd) { virDomainPtr dom; + virDomainBlockInfo info; const char *path = NULL; unsigned long long size = 0; unsigned int flags = 0; bool ret = false; + bool force = vshCommandOptBool(cmd, "force"); if (vshCommandOptStringReq(ctl, cmd, "path", (const char **) &path) < 0) return false; @@ -2938,24 +2944,46 @@ cmdBlockresize(vshControl *ctl, const vshCmd *cmd) if (vshCommandOptScaledInt(ctl, cmd, "size", &size, 1024, ULLONG_MAX) < 0) return false; + if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) + return false; + + if (virDomainGetBlockInfo(dom, path, &info, 0) < 0) + goto cleanup; + + /* Make sure to not shrink device if it's already given size */ + if (size == info.capacity) { + vshPrintExtra(ctl, _("Given size (%llu bytes) is the same as the " + "current capacity of '%s', not doing anything"), + size, path); + goto cleanup; + } + + /* Make sure to only allow shrink of device if --force is specified */ + if (size < info.capacity && !force) { + vshError(ctl, _("Can't shrink the size of '%s' below current capacity, " + "unless --force is explicity specified"), path); + goto cleanup; + } + /* Prefer the older interface of KiB. */ if (size % 1024 == 0) size /= 1024; else flags |= VIR_DOMAIN_BLOCK_RESIZE_BYTES; - if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) - return false; - if (virDomainBlockResize(dom, path, size, flags) < 0) { vshError(ctl, _("Failed to resize block device '%s'"), path); + goto cleanup; } else { vshPrintExtra(ctl, _("Block device '%s' is resized"), path); ret = true; + goto cleanup; } + cleanup: virshDomainFree(dom); return ret; + } #ifndef WIN32 diff --git a/tools/virsh.pod b/tools/virsh.pod index cf2798e71a..dc34a2a263 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1027,7 +1027,7 @@ I<bandwidth> specifies copying bandwidth limit in MiB/s. For further information on the I<bandwidth> argument see the corresponding section for the B<blockjob> command. -=item B<blockresize> I<domain> I<path> I<size> +=item B<blockresize> I<domain> I<path> I<size> [I<--force>] Resize a block device of domain while the domain is running, I<path> specifies the absolute path of the block device; it corresponds @@ -1040,6 +1040,10 @@ I<size> is a scaled integer (see B<NOTES> above) which defaults to KiB "B" to get bytes (note that for historical reasons, this differs from B<vol-resize> which defaults to bytes without a suffix). +The I<--force> flag is needed when specified I<size> is less than the current +capacity of the device, ie. when shrinking a device. Always exercise caution +when shrinking a block device. + =item B<console> I<domain> [I<devname>] [I<--safe>] [I<--force>] Connect the virtual serial console for the guest. The optional -- 2.23.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list