]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
blockcopy: add qemu implementation of new tunables
authorEric Blake <eblake@redhat.com>
Mon, 8 Sep 2014 20:53:12 +0000 (14:53 -0600)
committerEric Blake <eblake@redhat.com>
Fri, 12 Sep 2014 14:11:11 +0000 (08:11 -0600)
Upstream qemu 1.4 added some drive-mirror tunables not present
when it was first introduced in 1.3.  Management apps may want
to set these in some cases (for example, without tuning
granularity down to sector size, a copy may end up occupying
more bytes than the original because an entire cluster is
copied even when only a sector within the cluster is dirty,
although tuning it down results in more CPU time to do the
copy).  I haven't personally needed to use the parameters, but
since they exist, and since the new API supports virTypedParams,
we might as well expose them.

Since the tuning parameters aren't often used, and omitted from
the QMP command when unspecified, I think it is safe to rely on
qemu 1.3 to issue an error about them being unsupported, rather
than trying to create a new capability bit in libvirt.

Meanwhile, all versions of qemu from 1.4 to 2.1 have a bug where
a bad granularity (such as non-power-of-2) gives a poor message:
error: internal error: unable to execute QEMU command 'drive-mirror': Invalid parameter 'drive-virtio-disk0'

because of abuse of QERR_INVALID_PARAMETER (which is supposed to
name the parameter that was given a bad value, rather than the
value passed to some other parameter).  I don't see that a
capability check will help, so we'll just live with it (and it
has since been improved in upstream qemu).

* src/qemu/qemu_monitor.h (qemuMonitorDriveMirror): Add
parameters.
* src/qemu/qemu_monitor.c (qemuMonitorDriveMirror): Likewise.
* src/qemu/qemu_monitor_json.h (qemuMonitorJSONDriveMirror):
Likewise.
* src/qemu/qemu_monitor_json.c (qemuMonitorJSONDriveMirror):
Likewise.
* src/qemu/qemu_driver.c (qemuDomainBlockCopyCommon): Likewise.
(qemuDomainBlockRebase, qemuDomainBlockCopy): Adjust callers.
* src/qemu/qemu_migration.c (qemuMigrationDriveMirror): Likewise.
* tests/qemumonitorjsontest.c (qemuMonitorJSONDriveMirror): Likewise.

Signed-off-by: Eric Blake <eblake@redhat.com>
src/qemu/qemu_driver.c
src/qemu/qemu_migration.c
src/qemu/qemu_monitor.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_json.h
tests/qemumonitorjsontest.c

index 99167bb31170db8a0602d4ec1f88f45256de538b..76d5bcf2e2bcc56b4ae9fa84a52748b20761ecbc 100644 (file)
@@ -15305,6 +15305,8 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
                           const char *path,
                           virStorageSourcePtr mirror,
                           unsigned long long bandwidth,
+                          unsigned int granularity,
+                          unsigned long long buf_size,
                           unsigned int flags)
 {
     virQEMUDriverPtr driver = conn->privateData;
@@ -15450,7 +15452,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
     /* Actually start the mirroring */
     qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorDriveMirror(priv->mon, device, mirror->path, format,
-                                 bandwidth, flags);
+                                 bandwidth, granularity, buf_size, flags);
     virDomainAuditDisk(vm, NULL, mirror, "mirror", ret >= 0);
     qemuDomainObjExitMonitor(driver, vm);
     if (ret < 0) {
@@ -15546,7 +15548,7 @@ qemuDomainBlockRebase(virDomainPtr dom, const char *path, const char *base,
     flags &= (VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
               VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT);
     ret = qemuDomainBlockCopyCommon(vm, dom->conn, path, dest,
-                                    bandwidth, flags);
+                                    bandwidth, 0, 0, flags);
     vm = NULL;
     dest = NULL;
 
@@ -15614,23 +15616,13 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *disk, const char *destxml,
             buf_size = param->value.ul;
         }
     }
-    if (granularity) {
-        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
-                       _("granularity tuning not supported yet"));
-        goto cleanup;
-    }
-    if (buf_size) {
-        virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
-                       _("buffer size tuning not supported yet"));
-        goto cleanup;
-    }
 
     if (!(dest = virDomainDiskDefSourceParse(destxml, vm->def, driver->xmlopt,
                                              VIR_DOMAIN_XML_INACTIVE)))
         goto cleanup;
 
     ret = qemuDomainBlockCopyCommon(vm, dom->conn, disk, dest,
-                                    bandwidth, flags);
+                                    bandwidth, granularity, buf_size, flags);
     vm = NULL;
 
  cleanup:
index 4819c047548d6ef2545653ca13ec03ba63b371ad..ce1a5cdaa1958bbba054ee8789947cb3581b18dc 100644 (file)
@@ -1461,7 +1461,7 @@ qemuMigrationDriveMirror(virQEMUDriverPtr driver,
                                            QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
             goto error;
         mon_ret = qemuMonitorDriveMirror(priv->mon, diskAlias, nbd_dest,
-                                         NULL, speed, mirror_flags);
+                                         NULL, speed, 0, 0, mirror_flags);
         qemuDomainObjExitMonitor(driver, vm);
 
         if (mon_ret < 0)
index 702404a0ec1d5ecfc94e12075a1f8b7802762cd0..60591338a4f01b376b78381a9aa7b049456e93bf 100644 (file)
@@ -3189,17 +3189,19 @@ int
 qemuMonitorDriveMirror(qemuMonitorPtr mon,
                        const char *device, const char *file,
                        const char *format, unsigned long long bandwidth,
+                       unsigned int granularity, unsigned long long buf_size,
                        unsigned int flags)
 {
     int ret = -1;
 
     VIR_DEBUG("mon=%p, device=%s, file=%s, format=%s, bandwidth=%lld, "
-              "flags=%x",
-              mon, device, file, NULLSTR(format), bandwidth, flags);
+              "granularity=%#x, buf_size=%lld, flags=%x",
+              mon, device, file, NULLSTR(format), bandwidth, granularity,
+              buf_size, flags);
 
     if (mon->json)
         ret = qemuMonitorJSONDriveMirror(mon, device, file, format, bandwidth,
-                                         flags);
+                                         granularity, buf_size, flags);
     else
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
                        _("drive-mirror requires JSON monitor"));
index ced198e36841c418420e861366caa8f7f76f54c6..c32001d7d26b0f9c4b01c3a31765ca8d9f4aeae5 100644 (file)
@@ -650,6 +650,8 @@ int qemuMonitorDriveMirror(qemuMonitorPtr mon,
                            const char *file,
                            const char *format,
                            unsigned long long bandwidth,
+                           unsigned int granularity,
+                           unsigned long long buf_size,
                            unsigned int flags)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
 int qemuMonitorDrivePivot(qemuMonitorPtr mon,
index 30f9ffb9aec30fa56c1eba6b45110830a9702938..0c4832a5bac152f3ea48dc1ef54a916ccda9ea43 100644 (file)
@@ -3422,6 +3422,8 @@ int
 qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
                            const char *device, const char *file,
                            const char *format, unsigned long long speed,
+                           unsigned int granularity,
+                           unsigned long long buf_size,
                            unsigned int flags)
 {
     int ret = -1;
@@ -3434,6 +3436,8 @@ qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
                                      "s:device", device,
                                      "s:target", file,
                                      "Y:speed", speed,
+                                     "z:granularity", granularity,
+                                     "P:buf-size", buf_size,
                                      "s:sync", shallow ? "top" : "full",
                                      "s:mode", reuse ? "existing" : "absolute-paths",
                                      "S:format", format,
index a6d05b5d0822af65f11f5179e8e2055319eab073..b5c61ca6146f7480f30b6dc7f25ccf090aab6477 100644 (file)
@@ -249,6 +249,8 @@ int qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
                                const char *file,
                                const char *format,
                                unsigned long long speed,
+                               unsigned int granularity,
+                               unsigned long long buf_size,
                                unsigned int flags)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
 int qemuMonitorJSONDrivePivot(qemuMonitorPtr mon,
index e3fb4f75b1ab49ea796c1cee6ebd30152090dfe0..afbf13a667e4900995dbca56ec2c86921e382daf 100644 (file)
@@ -1176,7 +1176,7 @@ GEN_TEST_FUNC(qemuMonitorJSONRemoveNetdev, "net0")
 GEN_TEST_FUNC(qemuMonitorJSONDelDevice, "ide0")
 GEN_TEST_FUNC(qemuMonitorJSONAddDevice, "some_dummy_devicestr")
 GEN_TEST_FUNC(qemuMonitorJSONSetDrivePassphrase, "vda", "secret_passhprase")
-GEN_TEST_FUNC(qemuMonitorJSONDriveMirror, "vdb", "/foo/bar", NULL, 1024,
+GEN_TEST_FUNC(qemuMonitorJSONDriveMirror, "vdb", "/foo/bar", NULL, 1024, 0, 0,
               VIR_DOMAIN_BLOCK_REBASE_SHALLOW | VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT)
 GEN_TEST_FUNC(qemuMonitorJSONBlockCommit, "vdb", "/foo/bar1", "/foo/bar2", NULL, 1024)
 GEN_TEST_FUNC(qemuMonitorJSONDrivePivot, "vdb", NULL, NULL)