[libvirt] [PATCH v2 8/8] blockcopy: add qemu implementation of new tunables

Peter Krempa pkrempa at redhat.com
Tue Aug 26 15:54:57 UTC 2014


On 08/26/14 13:21, Eric Blake wrote:
> 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 I'll
> send a patch to get qemu 2.2 to give a nicer message).
> 
> * 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 at redhat.com>
> ---
> 
> Maybe I need to tweak libvirt's handler to report a nicer message
> if qemu reports an invalid parameter, since playing the qemu
> message verbatim isn't very informative.
> 
>  src/qemu/qemu_driver.c       | 18 +++++-------------
>  src/qemu/qemu_migration.c    |  2 +-
>  src/qemu/qemu_monitor.c      |  8 +++++---
>  src/qemu/qemu_monitor.h      |  2 ++
>  src/qemu/qemu_monitor_json.c |  3 +++
>  src/qemu/qemu_monitor_json.h |  2 ++
>  tests/qemumonitorjsontest.c  |  2 +-
>  7 files changed, 19 insertions(+), 18 deletions(-)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 4876617..d43d257 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -15281,6 +15281,8 @@ qemuDomainBlockCopyCommon(virDomainObjPtr *vmptr,
>                            const char *path,
>                            virStorageSourcePtr dest,
>                            unsigned long bandwidth,
> +                          int granularity,
> +                          int buf_size,

int ??

>                            unsigned int flags)
>  {
>      virDomainObjPtr vm = *vmptr;
> @@ -15421,7 +15423,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr *vmptr,
>      /* Actually start the mirroring */
>      qemuDomainObjEnterMonitor(driver, vm);
>      ret = qemuMonitorDriveMirror(priv->mon, device, dest->path, format,
> -                                 bandwidth, flags);
> +                                 bandwidth, granularity, buf_size, flags);
>      virDomainAuditDisk(vm, NULL, mirror, "mirror", ret >= 0);
>      qemuDomainObjExitMonitor(driver, vm);
>      if (ret < 0) {
> @@ -15498,7 +15500,7 @@ qemuDomainBlockRebase(virDomainPtr dom, const char *path, const char *base,
>       * and VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT map to the same value
>       * as for block copy. */
>      ret = qemuDomainBlockCopyCommon(&vm, dom->conn, path, dest,
> -                                    bandwidth, flags);
> +                                    bandwidth, 0, 0, flags);
> 
>   cleanup:
>      if (vm)
> @@ -15561,23 +15563,13 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *disk, const char *destxml,
>              buf_size = params[i].value.ui;
>          }
>      }
> -    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);

both granularity and bufsize are unsigned here!

> 
>   cleanup:
>      virStorageSourceFree(dest);
> diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
> index 9cfb77e..111f6af 100644
> --- a/src/qemu/qemu_migration.c
> +++ b/src/qemu/qemu_migration.c
> @@ -1279,7 +1279,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)
> diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
> index d5ba08d..0332091 100644
> --- a/src/qemu/qemu_monitor.c
> +++ b/src/qemu/qemu_monitor.c
> @@ -3182,14 +3182,16 @@ int
>  qemuMonitorDriveMirror(qemuMonitorPtr mon,
>                         const char *device, const char *file,
>                         const char *format, unsigned long bandwidth,
> +                       unsigned int granularity, unsigned int buf_size,
>                         unsigned int flags)
>  {
>      int ret = -1;
>      unsigned long long speed;
> 
>      VIR_DEBUG("mon=%p, device=%s, file=%s, format=%s, bandwidth=%ld, "
> -              "flags=%x",
> -              mon, device, file, NULLSTR(format), bandwidth, flags);
> +              "granularity=%#x, buf_size=%#x, flags=%x",

Clever way to check the power-of-2-ness, although bufsize would be beter
off with %u.

> +              mon, device, file, NULLSTR(format), bandwidth, granularity,
> +              buf_size, flags);
> 
>      /* Convert bandwidth MiB to bytes - unfortunately the JSON QMP protocol is
>       * limited to LLONG_MAX also for unsigned values */
> @@ -3204,7 +3206,7 @@ qemuMonitorDriveMirror(qemuMonitorPtr mon,
> 
>      if (mon->json)
>          ret = qemuMonitorJSONDriveMirror(mon, device, file, format, speed,
> -                                         flags);
> +                                         granularity, buf_size, flags);
>      else
>          virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
>                         _("drive-mirror requires JSON monitor"));
> diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
> index 4fd6f01..9da7ee4 100644
> --- a/src/qemu/qemu_monitor.h
> +++ b/src/qemu/qemu_monitor.h
> @@ -650,6 +650,8 @@ int qemuMonitorDriveMirror(qemuMonitorPtr mon,
>                             const char *file,
>                             const char *format,
>                             unsigned long bandwidth,
> +                           unsigned int granularity,
> +                           unsigned int buf_size,
>                             unsigned int flags)
>      ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
>  int qemuMonitorDrivePivot(qemuMonitorPtr mon,
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index 62e7d5d..dcbb693 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -3397,6 +3397,7 @@ int
>  qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
>                             const char *device, const char *file,
>                             const char *format, unsigned long long speed,
> +                           unsigned int granularity, unsigned int buf_size,
>                             unsigned int flags)
>  {
>      int ret = -1;
> @@ -3409,6 +3410,8 @@ qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
>                                       "s:device", device,
>                                       "s:target", file,
>                                       "U:speed", speed,
> +                                     "z:granularity", granularity,
> +                                     "z:buf-size", buf_size,

z is for signed values. both are unsigned. I think you wanted to use a
'p' formatter.

>                                       "s:sync", shallow ? "top" : "full",
>                                       "s:mode", reuse ? "existing" : "absolute-paths",
>                                       "S:format", format,
> diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
> index d8c9308..cd331db 100644
> --- a/src/qemu/qemu_monitor_json.h
> +++ b/src/qemu/qemu_monitor_json.h
> @@ -249,6 +249,8 @@ int qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
>                                 const char *file,
>                                 const char *format,
>                                 unsigned long long speed,
> +                               unsigned int granularity,
> +                               unsigned int buf_size,
>                                 unsigned int flags)
>      ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
>  int qemuMonitorJSONDrivePivot(qemuMonitorPtr mon,
> diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
> index e3fb4f7..afbf13a 100644
> --- a/tests/qemumonitorjsontest.c
> +++ b/tests/qemumonitorjsontest.c
> @@ -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)
> 

There are a few singedness problems in this patch. Although trivial
enough to grant an

ACK if you fix the issues above.

Peter

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20140826/34974acc/attachment-0001.sig>


More information about the libvir-list mailing list