[libvirt] [PATCHv2 1/1] Add --force flag to virsh blockresize

martinsson.patrik at gmail.com martinsson.patrik at gmail.com
Mon Oct 21 19:55:39 UTC 2019


From: Patrik Martinsson <martinsson.patrik at gmail.com>

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 at gmail.com>
---
 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




More information about the libvir-list mailing list