提交 eef91f94 编写于 作者: E Eric Blake

blockcopy: add qemu implementation of new tunables

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: NEric Blake <eblake@redhat.com>
上级 e3f5f8ee
...@@ -15305,6 +15305,8 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, ...@@ -15305,6 +15305,8 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
const char *path, const char *path,
virStorageSourcePtr mirror, virStorageSourcePtr mirror,
unsigned long long bandwidth, unsigned long long bandwidth,
unsigned int granularity,
unsigned long long buf_size,
unsigned int flags) unsigned int flags)
{ {
virQEMUDriverPtr driver = conn->privateData; virQEMUDriverPtr driver = conn->privateData;
...@@ -15450,7 +15452,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, ...@@ -15450,7 +15452,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
/* Actually start the mirroring */ /* Actually start the mirroring */
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorDriveMirror(priv->mon, device, mirror->path, format, ret = qemuMonitorDriveMirror(priv->mon, device, mirror->path, format,
bandwidth, flags); bandwidth, granularity, buf_size, flags);
virDomainAuditDisk(vm, NULL, mirror, "mirror", ret >= 0); virDomainAuditDisk(vm, NULL, mirror, "mirror", ret >= 0);
qemuDomainObjExitMonitor(driver, vm); qemuDomainObjExitMonitor(driver, vm);
if (ret < 0) { if (ret < 0) {
...@@ -15546,7 +15548,7 @@ qemuDomainBlockRebase(virDomainPtr dom, const char *path, const char *base, ...@@ -15546,7 +15548,7 @@ qemuDomainBlockRebase(virDomainPtr dom, const char *path, const char *base,
flags &= (VIR_DOMAIN_BLOCK_REBASE_SHALLOW | flags &= (VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT); VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT);
ret = qemuDomainBlockCopyCommon(vm, dom->conn, path, dest, ret = qemuDomainBlockCopyCommon(vm, dom->conn, path, dest,
bandwidth, flags); bandwidth, 0, 0, flags);
vm = NULL; vm = NULL;
dest = NULL; dest = NULL;
...@@ -15614,23 +15616,13 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *disk, const char *destxml, ...@@ -15614,23 +15616,13 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *disk, const char *destxml,
buf_size = param->value.ul; 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, if (!(dest = virDomainDiskDefSourceParse(destxml, vm->def, driver->xmlopt,
VIR_DOMAIN_XML_INACTIVE))) VIR_DOMAIN_XML_INACTIVE)))
goto cleanup; goto cleanup;
ret = qemuDomainBlockCopyCommon(vm, dom->conn, disk, dest, ret = qemuDomainBlockCopyCommon(vm, dom->conn, disk, dest,
bandwidth, flags); bandwidth, granularity, buf_size, flags);
vm = NULL; vm = NULL;
cleanup: cleanup:
......
...@@ -1461,7 +1461,7 @@ qemuMigrationDriveMirror(virQEMUDriverPtr driver, ...@@ -1461,7 +1461,7 @@ qemuMigrationDriveMirror(virQEMUDriverPtr driver,
QEMU_ASYNC_JOB_MIGRATION_OUT) < 0) QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
goto error; goto error;
mon_ret = qemuMonitorDriveMirror(priv->mon, diskAlias, nbd_dest, mon_ret = qemuMonitorDriveMirror(priv->mon, diskAlias, nbd_dest,
NULL, speed, mirror_flags); NULL, speed, 0, 0, mirror_flags);
qemuDomainObjExitMonitor(driver, vm); qemuDomainObjExitMonitor(driver, vm);
if (mon_ret < 0) if (mon_ret < 0)
......
...@@ -3189,17 +3189,19 @@ int ...@@ -3189,17 +3189,19 @@ int
qemuMonitorDriveMirror(qemuMonitorPtr mon, qemuMonitorDriveMirror(qemuMonitorPtr mon,
const char *device, const char *file, const char *device, const char *file,
const char *format, unsigned long long bandwidth, const char *format, unsigned long long bandwidth,
unsigned int granularity, unsigned long long buf_size,
unsigned int flags) unsigned int flags)
{ {
int ret = -1; int ret = -1;
VIR_DEBUG("mon=%p, device=%s, file=%s, format=%s, bandwidth=%lld, " VIR_DEBUG("mon=%p, device=%s, file=%s, format=%s, bandwidth=%lld, "
"flags=%x", "granularity=%#x, buf_size=%lld, flags=%x",
mon, device, file, NULLSTR(format), bandwidth, flags); mon, device, file, NULLSTR(format), bandwidth, granularity,
buf_size, flags);
if (mon->json) if (mon->json)
ret = qemuMonitorJSONDriveMirror(mon, device, file, format, bandwidth, ret = qemuMonitorJSONDriveMirror(mon, device, file, format, bandwidth,
flags); granularity, buf_size, flags);
else else
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("drive-mirror requires JSON monitor")); _("drive-mirror requires JSON monitor"));
......
...@@ -650,6 +650,8 @@ int qemuMonitorDriveMirror(qemuMonitorPtr mon, ...@@ -650,6 +650,8 @@ int qemuMonitorDriveMirror(qemuMonitorPtr mon,
const char *file, const char *file,
const char *format, const char *format,
unsigned long long bandwidth, unsigned long long bandwidth,
unsigned int granularity,
unsigned long long buf_size,
unsigned int flags) unsigned int flags)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
int qemuMonitorDrivePivot(qemuMonitorPtr mon, int qemuMonitorDrivePivot(qemuMonitorPtr mon,
......
...@@ -3422,6 +3422,8 @@ int ...@@ -3422,6 +3422,8 @@ int
qemuMonitorJSONDriveMirror(qemuMonitorPtr mon, qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
const char *device, const char *file, const char *device, const char *file,
const char *format, unsigned long long speed, const char *format, unsigned long long speed,
unsigned int granularity,
unsigned long long buf_size,
unsigned int flags) unsigned int flags)
{ {
int ret = -1; int ret = -1;
...@@ -3434,6 +3436,8 @@ qemuMonitorJSONDriveMirror(qemuMonitorPtr mon, ...@@ -3434,6 +3436,8 @@ qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
"s:device", device, "s:device", device,
"s:target", file, "s:target", file,
"Y:speed", speed, "Y:speed", speed,
"z:granularity", granularity,
"P:buf-size", buf_size,
"s:sync", shallow ? "top" : "full", "s:sync", shallow ? "top" : "full",
"s:mode", reuse ? "existing" : "absolute-paths", "s:mode", reuse ? "existing" : "absolute-paths",
"S:format", format, "S:format", format,
......
...@@ -249,6 +249,8 @@ int qemuMonitorJSONDriveMirror(qemuMonitorPtr mon, ...@@ -249,6 +249,8 @@ int qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
const char *file, const char *file,
const char *format, const char *format,
unsigned long long speed, unsigned long long speed,
unsigned int granularity,
unsigned long long buf_size,
unsigned int flags) unsigned int flags)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
int qemuMonitorJSONDrivePivot(qemuMonitorPtr mon, int qemuMonitorJSONDrivePivot(qemuMonitorPtr mon,
......
...@@ -1176,7 +1176,7 @@ GEN_TEST_FUNC(qemuMonitorJSONRemoveNetdev, "net0") ...@@ -1176,7 +1176,7 @@ GEN_TEST_FUNC(qemuMonitorJSONRemoveNetdev, "net0")
GEN_TEST_FUNC(qemuMonitorJSONDelDevice, "ide0") GEN_TEST_FUNC(qemuMonitorJSONDelDevice, "ide0")
GEN_TEST_FUNC(qemuMonitorJSONAddDevice, "some_dummy_devicestr") GEN_TEST_FUNC(qemuMonitorJSONAddDevice, "some_dummy_devicestr")
GEN_TEST_FUNC(qemuMonitorJSONSetDrivePassphrase, "vda", "secret_passhprase") 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) 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(qemuMonitorJSONBlockCommit, "vdb", "/foo/bar1", "/foo/bar2", NULL, 1024)
GEN_TEST_FUNC(qemuMonitorJSONDrivePivot, "vdb", NULL, NULL) GEN_TEST_FUNC(qemuMonitorJSONDrivePivot, "vdb", NULL, NULL)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册