提交 8e532d34 编写于 作者: E Eric Blake

qemu: improve errors related to offline domains

https://bugzilla.redhat.com/show_bug.cgi?id=816662 pointed out
that attempting 'virsh blockpull' on an offline domain gave a
misleading error message about qemu lacking support for the
operation, even when qemu was specifically updated to support it.
The real problem is that we have several capabilities that are
only determined when starting a domain, and therefore are still
clear when first working with an inactive domain (namely, any
capability set by qemuMonitorJSONCheckCommands).

While this patch was able to hoist an existing check in one of the
three culprits, it had to add redundant checks in the other two
places (because you always have to check for an active domain after
obtaining a VM job lock, but the capability bits were being checked
prior to obtaining the job lock).

Someday it would be nice to patch libvirt to cache the set of
capabilities per qemu binary (as determined by inode and timestamp),
rather than re-probing the binary every time a domain is started,
and to teach the cache how to query the monitor during the one
time the probe is made rather than having to wait until a guest
is started; then, a capability probe would succeed even for offline
guests because it just refers to the cache, and the single check for
an active domain after grabbing the job lock would be sufficient.
But since that will involve a lot more coding, I'm happy to go
with this simpler solution for an immediate solution.

* src/qemu/qemu_driver.c (qemuDomainPMSuspendForDuration)
(qemuDomainSnapshotCreateXML, qemuDomainBlockJobImpl): Check for
offline state before checking an online-only cap.
上级 4bf9061e
...@@ -10389,6 +10389,12 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, ...@@ -10389,6 +10389,12 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
goto cleanup; goto cleanup;
if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY) { if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY) {
if (!virDomainObjIsActive(vm)) {
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("disk snapshots of inactive domains not "
"implemented yet"));
goto cleanup;
}
if (virDomainSnapshotAlignDisks(def, if (virDomainSnapshotAlignDisks(def,
VIR_DOMAIN_DISK_SNAPSHOT_EXTERNAL, VIR_DOMAIN_DISK_SNAPSHOT_EXTERNAL,
false) < 0) false) < 0)
...@@ -10443,12 +10449,6 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain, ...@@ -10443,12 +10449,6 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
* makes sense, such as checking that qemu-img recognizes the * makes sense, such as checking that qemu-img recognizes the
* snapshot name in at least one of the domain's disks? */ * snapshot name in at least one of the domain's disks? */
} else if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY) { } else if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY) {
if (!virDomainObjIsActive(vm)) {
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("disk snapshots of inactive domains not "
"implemented yet"));
goto cleanup;
}
if (qemuDomainSnapshotCreateDiskActive(domain->conn, driver, if (qemuDomainSnapshotCreateDiskActive(domain->conn, driver,
&vm, snap, flags) < 0) &vm, snap, flags) < 0)
goto cleanup; goto cleanup;
...@@ -11642,6 +11642,12 @@ qemuDomainBlockJobImpl(virDomainPtr dom, const char *path, const char *base, ...@@ -11642,6 +11642,12 @@ qemuDomainBlockJobImpl(virDomainPtr dom, const char *path, const char *base,
_("no domain with matching uuid '%s'"), uuidstr); _("no domain with matching uuid '%s'"), uuidstr);
goto cleanup; goto cleanup;
} }
if (!virDomainObjIsActive(vm)) {
qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("domain is not running"));
goto cleanup;
}
priv = vm->privateData; priv = vm->privateData;
if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKJOB_ASYNC)) { if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKJOB_ASYNC)) {
async = true; async = true;
...@@ -12635,6 +12641,12 @@ qemuDomainPMSuspendForDuration(virDomainPtr dom, ...@@ -12635,6 +12641,12 @@ qemuDomainPMSuspendForDuration(virDomainPtr dom,
priv = vm->privateData; priv = vm->privateData;
if (!virDomainObjIsActive(vm)) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not running"));
goto cleanup;
}
if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_WAKEUP) && if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_WAKEUP) &&
(target == VIR_NODE_SUSPEND_TARGET_MEM || (target == VIR_NODE_SUSPEND_TARGET_MEM ||
target == VIR_NODE_SUSPEND_TARGET_HYBRID)) { target == VIR_NODE_SUSPEND_TARGET_HYBRID)) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册