QEMU_CAPS_WAKEUP_SUSPEND_SUPPORT is a bool that represents the value
of the wakeup-suspend-support flag of the new query-current-machine
QMP API, available in QEMU 4.0.
The flag is set in qemuProcessLaunch, using a new function called
qemuProcessSetupWakeupSuspendSupport. This function checks first
if the QEMU process has support for the new API, which is reflected
by the QEMU_CAPS_QUERY_CURRENT_MACHINE cap. If positive, query it
and set QEMU_CAPS_WAKEUP_SUSPEND_SUPPORT with the current value
of wakeup-suspend-support.
---
src/qemu/qemu_monitor.c | 8 ++++++++
src/qemu/qemu_monitor.h | 3 +++
src/qemu/qemu_monitor_json.c | 35 +++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 4 ++++
src/qemu/qemu_process.c | 38 ++++++++++++++++++++++++++++++++++++
5 files changed, 88 insertions(+)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index babcbde878..fc6dc2197a 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4472,3 +4472,11 @@ qemuMonitorGetPRManagerInfo(qemuMonitorPtr mon,
virHashFree(info);
return ret;
}
+
+int
+qemuMonitorGetWakeupSuspendSupport(qemuMonitorPtr mon, bool *enabled)
+{
+ QEMU_CHECK_MONITOR(mon);
+
+ return qemuMonitorJSONGetWakeupSuspendSupport(mon, enabled);
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 086195ff98..62074c1acb 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1220,4 +1220,7 @@ struct _qemuMonitorPRManagerInfo {
int qemuMonitorGetPRManagerInfo(qemuMonitorPtr mon,
virHashTablePtr *retinfo);
+int qemuMonitorGetWakeupSuspendSupport(qemuMonitorPtr mon,
+ bool *enabled);
+
#endif /* LIBVIRT_QEMU_MONITOR_H */
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 743a88b914..16d34fb217 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -8452,3 +8452,38 @@ qemuMonitorJSONGetPRManagerInfo(qemuMonitorPtr mon,
return ret;
}
+
+int
+qemuMonitorJSONGetWakeupSuspendSupport(qemuMonitorPtr mon, bool *enabled)
+{
+ int ret = -1;
+ virJSONValuePtr cmd, data;
+ virJSONValuePtr reply = NULL;
+
+ if (!(cmd = qemuMonitorJSONMakeCommand("query-current-machine",
+ NULL)))
+ return -1;
+
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
+
+ if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_OBJECT) < 0)
+ goto cleanup;
+
+ data = virJSONValueObjectGetObject(reply, "return");
+
+ if (virJSONValueObjectGetBoolean(data, "wakeup-suspend-support",
+ enabled)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("missing wakeup-suspend-support in "
+ "query-current-machine response"));
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ return ret;
+}
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index c10513da15..ede828d622 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -576,4 +576,8 @@ int qemuMonitorJSONGetPRManagerInfo(qemuMonitorPtr mon,
virHashTablePtr info)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+int qemuMonitorJSONGetWakeupSuspendSupport(qemuMonitorPtr mon,
+ bool *enabled)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
#endif /* LIBVIRT_QEMU_MONITOR_JSON_H */
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index dc7317b723..71984714de 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6449,6 +6449,41 @@ qemuProcessSetupDiskThrottlingBlockdev(virQEMUDriverPtr driver,
return ret;
}
+/**
+ * qemuProcessSetupWakeupSuspendSupport:
+ *
+ * Sets up QEMU_CAPS_WAKEUP_SUSPEND_SUPPORT in case QEMU has support
+ * for the query-current-machine QMP API. This can be verified by
+ * checking for the QEMU_CAPS_QUERY_CURRENT_MACHINE cap.
+ */
+static int
+qemuProcessSetupWakeupSuspendSupport(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ qemuDomainAsyncJob asyncJob)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ bool enabled;
+ int ret = -1;
+
+ if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QUERY_CURRENT_MACHINE))
+ return 0;
+
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+ return -1;
+
+ if (qemuMonitorGetWakeupSuspendSupport(qemuDomainGetMonitor(vm), &enabled) <
0)
+ goto cleanup;
+
+ if (enabled)
+ virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_WAKEUP_SUSPEND_SUPPORT);
+
+ ret = 0;
+
+ cleanup:
+ if (qemuDomainObjExitMonitor(driver, vm) < 0)
+ ret = -1;
+ return ret;
+}
/**
* qemuProcessLaunch:
@@ -6777,6 +6812,9 @@ qemuProcessLaunch(virConnectPtr conn,
qemuProcessAutoDestroyAdd(driver, vm, conn) < 0)
goto cleanup;
+ if (qemuProcessSetupWakeupSuspendSupport(driver, vm, asyncJob) < 0)
+ goto cleanup;
+
ret = 0;
cleanup:
--
2.20.1