Iimplements the new guest information API by querying requested
information via the guest agent.
Signed-off-by: Jonathon Jongsma <jjongsma(a)redhat.com>
---
src/qemu/qemu_driver.c | 110 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 110 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 11f97dbc65..bfbb38a2c8 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -23204,6 +23204,115 @@ qemuDomainGetLaunchSecurityInfo(virDomainPtr domain,
return ret;
}
+static unsigned int supportedGuestInfoTypes =
+ VIR_DOMAIN_GUEST_INFO_USERS |
+ VIR_DOMAIN_GUEST_INFO_OS |
+ VIR_DOMAIN_GUEST_INFO_TIMEZONE |
+ VIR_DOMAIN_GUEST_INFO_HOSTNAME |
+ VIR_DOMAIN_GUEST_INFO_FILESYSTEM;
+
+static void
+qemuDomainGetGuestInfoCheckSupport(unsigned int *types)
+{
+ if (*types == 0)
+ *types = supportedGuestInfoTypes;
+
+ *types = *types & supportedGuestInfoTypes;
+}
+
+static int
+qemuDomainGetGuestInfo(virDomainPtr dom,
+ unsigned int types,
+ virTypedParameterPtr *params,
+ int *nparams,
+ unsigned int flags)
+{
+ virQEMUDriverPtr driver = dom->conn->privateData;
+ virDomainObjPtr vm = NULL;
+ qemuAgentPtr agent;
+ int ret = -1;
+ int rv = -1;
+ int maxparams = 0;
+ char *hostname = NULL;
+ virDomainDefPtr def = NULL;
+ virCapsPtr caps = NULL;
+ unsigned int supportedTypes = types;
+
+ virCheckFlags(0, ret);
+ qemuDomainGetGuestInfoCheckSupport(&supportedTypes);
+
+ if (!(vm = qemuDomObjFromDomain(dom)))
+ goto cleanup;
+
+ if (virDomainGetGuestInfoEnsureACL(dom->conn, vm->def) < 0)
+ goto cleanup;
+
+ if (qemuDomainObjBeginAgentJob(driver, vm, QEMU_AGENT_JOB_QUERY) < 0)
+ goto cleanup;
+
+ if (!qemuDomainAgentAvailable(vm, true))
+ goto endjob;
+
+ agent = qemuDomainObjEnterAgent(vm);
+
+ /* Although the libvirt qemu driver supports all of these guest info types,
+ * some guest agents might be too old to support these commands. If these
+ * info categories were explicitly requested (i.e. 'types' is non-zero),
+ * abort and report an error on any failures, otherwise continue and return
+ * as much info as is supported by the guest agent. */
+ if (supportedTypes & VIR_DOMAIN_GUEST_INFO_USERS) {
+ if (qemuAgentGetUsers(agent, params, nparams, &maxparams) < 0 &&
+ types != 0)
+ goto exitagent;
+ }
+ if (supportedTypes & VIR_DOMAIN_GUEST_INFO_OS) {
+ if (qemuAgentGetOSInfo(agent, params, nparams, &maxparams) < 0
+ && types != 0)
+ goto exitagent;
+ }
+ if (supportedTypes & VIR_DOMAIN_GUEST_INFO_TIMEZONE) {
+ if (qemuAgentGetTimezone(agent, params, nparams, &maxparams) < 0
+ && types != 0)
+ goto exitagent;
+ }
+ if (supportedTypes & VIR_DOMAIN_GUEST_INFO_HOSTNAME) {
+ if (qemuAgentGetHostname(agent, &hostname) < 0) {
+ if (types != 0)
+ goto exitagent;
+ } else {
+ if (virTypedParamsAddString(params, nparams, &maxparams,
"hostname",
+ hostname) < 0)
+ goto exitagent;
+ }
+ }
+ if (supportedTypes & VIR_DOMAIN_GUEST_INFO_FILESYSTEM) {
+ if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+ goto exitagent;
+
+ if (!(def = virDomainDefCopy(vm->def, caps, driver->xmlopt, NULL, false)))
+ goto exitagent;
+
+ if (qemuAgentGetFSInfoParams(agent, params, nparams, &maxparams, def) < 0
&&
+ types != 0)
+ goto exitagent;
+ }
+
+ rv = 0;
+
+ exitagent:
+ qemuDomainObjExitAgent(vm, agent);
+
+ endjob:
+ qemuDomainObjEndAgentJob(vm);
+
+ cleanup:
+ virDomainObjEndAPI(&vm);
+ virDomainDefFree(def);
+ virObjectUnref(caps);
+ VIR_FREE(hostname);
+ return rv;
+}
+
static virHypervisorDriver qemuHypervisorDriver = {
.name = QEMU_DRIVER_NAME,
.connectURIProbe = qemuConnectURIProbe,
@@ -23439,6 +23548,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
.domainCheckpointLookupByName = qemuDomainCheckpointLookupByName, /* 5.6.0 */
.domainCheckpointGetParent = qemuDomainCheckpointGetParent, /* 5.6.0 */
.domainCheckpointDelete = qemuDomainCheckpointDelete, /* 5.6.0 */
+ .domainGetGuestInfo = qemuDomainGetGuestInfo, /* 5.6.0 */
};
--
2.21.0