[libvirt] [PATCH] blockResize: add flag for bytes

Eric Blake eblake at redhat.com
Sat Mar 3 14:48:27 UTC 2012


Qemu supports sizing by bytes; we shouldn't force the user to
round up if they really wanted an unaligned total size.

* include/libvirt/libvirt.h.in (VIR_DOMAIN_BLOCK_RESIZE_BYTES):
New flag.
* src/libvirt.c (virDomainBlockResize): Document it.
* src/qemu/qemu_monitor_json.c (qemuMonitorJSONBlockResize): Take
size in bytes.
* src/qemu/qemu_monitor_text.c (qemuMonitorTextBlockResize):
Likewise.  Pass bytes, not megabytes, to monitor.
* src/qemu/qemu_driver.c (qemuDomainBlockResize): Implement new
flag.
---

Virsh support will come later, as part of my cleanups to make
virsh handle scaled integers.

 include/libvirt/libvirt.h.in |   10 ++++++++++
 src/libvirt.c                |   17 +++++++++++------
 src/qemu/qemu_driver.c       |   24 ++++++++++++++----------
 src/qemu/qemu_monitor_json.c |    5 +++--
 src/qemu/qemu_monitor_text.c |    6 +++---
 5 files changed, 41 insertions(+), 21 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 58c4366..b2f8f5f 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1636,6 +1636,16 @@ int                     virDomainBlockPeek (virDomainPtr dom,
                                             size_t size,
                                             void *buffer,
                                             unsigned int flags);
+
+/**
+ * virDomainBlockResizeFlags:
+ *
+ * Flags available for virDomainBlockResize().
+ */
+typedef enum {
+    VIR_DOMAIN_BLOCK_RESIZE_BYTES = 1 << 0, /* size in bytes instead of KiB */
+} virDomainBlockResizeFlags;
+
 int                     virDomainBlockResize (virDomainPtr dom,
                                               const char *disk,
                                               unsigned long long size,
diff --git a/src/libvirt.c b/src/libvirt.c
index c2e9733..d98741b 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -7601,12 +7601,15 @@ error:
  * virDomainBlockResize:
  * @dom: pointer to the domain object
  * @disk: path to the block image, or shorthand
- * @size: new size of the block image in kilobytes
- * @flags: extra flags; not used yet, so callers should always pass 0
+ * @size: new size of the block image, see below for unit
+ * @flags: bitwise-OR of virDomainBlockResizeFlags
  *
- * Note that this call may fail if the underlying virtualization hypervisor
- * does not support it. And this call requires privileged access to the
- * hypervisor.
+ * Resize a block device of domain while the domain is running.  If
+ * @flags is 0, then @size is in kibibytes (blocks of 1024); since
+ * 0.9.11, if @flags includes VIR_DOMAIN_BLOCK_RESIZE_BYTES, @size is
+ * in bytes instead.  @size is taken directly as the new size.
+ * Depending on the file format, the hypervisor may round up to the
+ * next alignment boundary.
  *
  * The @disk parameter is either an unambiguous source name of the
  * block device (the <source file='...'/> sub-element, such as
@@ -7615,7 +7618,9 @@ error:
  * can be found by calling virDomainGetXMLDesc() and inspecting
  * elements within //domain/devices/disk.
  *
- * Resize a block device of domain while the domain is running.
+ * Note that this call may fail if the underlying virtualization hypervisor
+ * does not support it; this call requires privileged access to the
+ * hypervisor.
  *
  * Returns: 0 in case of success or -1 in case of failure.
  */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2afcc3f..1f57508 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7348,10 +7348,10 @@ qemuGetSchedulerParameters(virDomainPtr dom,
  * like LVM volumes.
  */
 static int
-qemuDomainBlockResize (virDomainPtr dom,
-                       const char *path,
-                       unsigned long long size,
-                       unsigned int flags)
+qemuDomainBlockResize(virDomainPtr dom,
+                      const char *path,
+                      unsigned long long size,
+                      unsigned int flags)
 {
     struct qemud_driver *driver = dom->conn->privateData;
     virDomainObjPtr vm;
@@ -7360,7 +7360,7 @@ qemuDomainBlockResize (virDomainPtr dom,
     char *device = NULL;
     virDomainDiskDefPtr disk = NULL;

-    virCheckFlags(0, -1);
+    virCheckFlags(VIR_DOMAIN_BLOCK_RESIZE_BYTES, -1);

     if (path[0] == '\0') {
         qemuReportError(VIR_ERR_INVALID_ARG,
@@ -7368,11 +7368,15 @@ qemuDomainBlockResize (virDomainPtr dom,
         return -1;
     }

-    if (size > ULLONG_MAX / 1024) {
-        qemuReportError(VIR_ERR_INVALID_ARG,
-                        _("size must be less than %llu"),
-                        ULLONG_MAX / 1024);
-        return -1;
+    /* We prefer operating on bytes.  */
+    if ((flags & VIR_DOMAIN_BLOCK_RESIZE_BYTES) == 0) {
+        if (size > ULLONG_MAX / 1024) {
+            qemuReportError(VIR_ERR_INVALID_ARG,
+                            _("size must be less than %llu"),
+                            ULLONG_MAX / 1024);
+            return -1;
+        }
+        size *= 1024;
     }

     qemuDriverLock(driver);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index c0f148b..dc67b4b 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -1783,7 +1783,8 @@ cleanup:
     return ret;
 }

-/* Return 0 on success, -1 on failure, or -2 if not supported. */
+/* Return 0 on success, -1 on failure, or -2 if not supported.  Size
+ * is in bytes.  */
 int qemuMonitorJSONBlockResize(qemuMonitorPtr mon,
                                const char *device,
                                unsigned long long size)
@@ -1794,7 +1795,7 @@ int qemuMonitorJSONBlockResize(qemuMonitorPtr mon,

     cmd = qemuMonitorJSONMakeCommand("block_resize",
                                      "s:device", device,
-                                     "U:size", size * 1024,
+                                     "U:size", size,
                                      NULL);
     if (!cmd)
         return -1;
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index d6f7dac..a7ebfba 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -1097,7 +1097,8 @@ int qemuMonitorTextGetBlockExtent(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     return -1;
 }

-/* Return 0 on success, -1 on failure, or -2 if not supported. */
+/* Return 0 on success, -1 on failure, or -2 if not supported.  Size
+ * is in bytes. */
 int qemuMonitorTextBlockResize(qemuMonitorPtr mon,
                                const char *device,
                                unsigned long long size)
@@ -1106,8 +1107,7 @@ int qemuMonitorTextBlockResize(qemuMonitorPtr mon,
     char *reply = NULL;
     int ret = -1;

-    if (virAsprintf(&cmd, "block_resize %s %llu",
-                    device, VIR_DIV_UP(size, 1024)) < 0) {
+    if (virAsprintf(&cmd, "block_resize %s %lluB", device, size) < 0) {
         virReportOOMError();
         goto cleanup;
     }
-- 
1.7.7.6




More information about the libvir-list mailing list