Implementation is pretty similar to the one found in the qemu driver.
Signed-off-by: Roman Bogorodskiy <[email protected]>
---
src/bhyve/bhyve_driver.c | 192 +++++++++++++++++++++++++++++++++++++++
1 file changed, 192 insertions(+)
diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c
index a0d97d3f86..d72b97c7ac 100644
--- a/src/bhyve/bhyve_driver.c
+++ b/src/bhyve/bhyve_driver.c
@@ -2807,6 +2807,197 @@ bhyveDomainRename(virDomainPtr domain,
return ret;
}
+static const unsigned int bhyveDomainGetGuestInfoSupportedTypes =
+ 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 |
+ VIR_DOMAIN_GUEST_INFO_DISKS |
+ VIR_DOMAIN_GUEST_INFO_INTERFACES |
+ VIR_DOMAIN_GUEST_INFO_LOAD;
+
+static int
+bhyveDomainGetGuestInfoCheckSupport(unsigned int types,
+ unsigned int *supportedTypes)
+{
+ if (types == 0) {
+ *supportedTypes = bhyveDomainGetGuestInfoSupportedTypes;
+ return 0;
+ }
+
+ *supportedTypes = types & bhyveDomainGetGuestInfoSupportedTypes;
+
+ if (types != *supportedTypes) {
+ virReportError(VIR_ERR_INVALID_ARG,
+ _("unsupported guest information types '0x%1$x'"),
+ types & ~bhyveDomainGetGuestInfoSupportedTypes);
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int
+bhyveDomainGetGuestInfo(virDomainPtr domain,
+ unsigned int types,
+ virTypedParameterPtr *params,
+ int *nparams,
+ unsigned int flags)
+{
+ virDomainObj *vm = NULL;
+ qemuAgent *agent = NULL;
+ int ret = -1;
+ g_autofree char *hostname = NULL;
+ unsigned int supportedTypes;
+ bool report_unsupported = types != 0;
+ int rc;
+ size_t nfs = 0;
+ qemuAgentFSInfo **agentfsinfo = NULL;
+ size_t ndisks = 0;
+ qemuAgentDiskInfo **agentdiskinfo = NULL;
+ virDomainInterfacePtr *ifaces = NULL;
+ size_t nifaces = 0;
+ double load1m = 0;
+ double load5m = 0;
+ double load15m = 0;
+ bool format_load = false;
+ size_t i;
+ g_autoptr(virTypedParamList) list = virTypedParamListNew();
+
+ if (bhyveDomainGetGuestInfoCheckSupport(types, &supportedTypes) < 0)
+ return -1;
+
+ virCheckFlags(0, -1);
+
+ if (!(vm = bhyveDomObjFromDomain(domain)))
+ goto cleanup;
+
+ if (virDomainGetGuestInfoEnsureACL(domain->conn, vm->def) < 0)
+ goto cleanup;
+
+ if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0)
+ goto cleanup;
+
+ if (bhyveDomainEnsureAgent(vm, true) < 0)
+ goto endagentjob;
+
+ agent = bhyveDomainObjEnterAgent(vm);
+
+ if (supportedTypes & VIR_DOMAIN_GUEST_INFO_USERS &&
+ qemuAgentGetUsers(agent, list, report_unsupported) == -1)
+ goto exitagent;
+
+ if (supportedTypes & VIR_DOMAIN_GUEST_INFO_OS &&
+ qemuAgentGetOSInfo(agent, list, report_unsupported) == -1)
+ goto exitagent;
+
+ if (supportedTypes & VIR_DOMAIN_GUEST_INFO_TIMEZONE &&
+ qemuAgentGetTimezone(agent, list, report_unsupported) == -1)
+ goto exitagent;
+
+ if (supportedTypes & VIR_DOMAIN_GUEST_INFO_HOSTNAME &&
+ qemuAgentGetHostname(agent, &hostname, report_unsupported) == -1)
+ goto exitagent;
+
+ if (hostname)
+ virTypedParamListAddString(list, hostname,
+ VIR_DOMAIN_GUEST_INFO_HOSTNAME_HOSTNAME);
+
+ if (supportedTypes & VIR_DOMAIN_GUEST_INFO_FILESYSTEM) {
+ rc = qemuAgentGetFSInfo(agent, &agentfsinfo, report_unsupported);
+ if (rc == -1)
+ goto exitagent;
+ if (rc >= 0)
+ nfs = rc;
+ }
+
+ if (supportedTypes & VIR_DOMAIN_GUEST_INFO_DISKS) {
+ rc = qemuAgentGetDisks(agent, &agentdiskinfo, report_unsupported);
+ if (rc == -1)
+ goto exitagent;
+ if (rc >= 0)
+ ndisks = rc;
+ }
+
+ if (supportedTypes & VIR_DOMAIN_GUEST_INFO_INTERFACES) {
+ rc = qemuAgentGetInterfaces(agent, &ifaces, report_unsupported);
+ if (rc == -1)
+ goto exitagent;
+ if (rc >= 0)
+ nifaces = rc;
+ }
+
+ if (supportedTypes & VIR_DOMAIN_GUEST_INFO_LOAD) {
+ rc = qemuAgentGetLoadAvg(agent, &load1m, &load5m, &load15m,
report_unsupported);
+ if (rc == -1)
+ goto exitagent;
+ if (rc >= 0)
+ format_load = true;
+ }
+
+ bhyveDomainObjExitAgent(vm, agent);
+ virDomainObjEndAgentJob(vm);
+
+ if (nfs > 0 || ndisks > 0) {
+ if (virDomainObjBeginJob(vm, VIR_JOB_QUERY) < 0)
+ goto cleanup;
+
+ if (virDomainObjCheckActive(vm) < 0)
+ goto endjob;
+
+ /* we need to convert the agent fsinfo struct to parameters and match
+ * it to the vm disk target */
+ if (nfs > 0)
+ qemuAgentFSInfoFormatParams(agentfsinfo, nfs, vm->def, list);
+
+ if (ndisks > 0)
+ qemuAgentDiskInfoFormatParams(agentdiskinfo, ndisks, vm->def,
list);
+
+ endjob:
+ virDomainObjEndJob(vm);
+ }
+
+ if (nifaces > 0) {
+ qemuAgentInterfaceFormatParams(ifaces, nifaces, list);
+ }
+
+ if (format_load) {
+ virTypedParamListAddDouble(list, load1m,
VIR_DOMAIN_GUEST_INFO_LOAD_1M);
+ virTypedParamListAddDouble(list, load5m,
VIR_DOMAIN_GUEST_INFO_LOAD_5M);
+ virTypedParamListAddDouble(list, load15m,
VIR_DOMAIN_GUEST_INFO_LOAD_15M);
+ }
+
+ if (virTypedParamListSteal(list, params, nparams) < 0)
+ goto cleanup;
+
+ ret = 0;
+
+ cleanup:
+ for (i = 0; i < nfs; i++)
+ qemuAgentFSInfoFree(agentfsinfo[i]);
+ g_free(agentfsinfo);
+ for (i = 0; i < ndisks; i++)
+ qemuAgentDiskInfoFree(agentdiskinfo[i]);
+ g_free(agentdiskinfo);
+ if (ifaces && nifaces > 0) {
+ for (i = 0; i < nifaces; i++)
+ virDomainInterfaceFree(ifaces[i]);
+ }
+ g_free(ifaces);
+
+ virDomainObjEndAPI(&vm);
+ return ret;
+
+ exitagent:
+ bhyveDomainObjExitAgent(vm, agent);
+
+ endagentjob:
+ virDomainObjEndAgentJob(vm);
+ goto cleanup;
+}
+
static virHypervisorDriver bhyveHypervisorDriver = {
.name = "bhyve",
.connectURIProbe = bhyveConnectURIProbe,
@@ -2885,6 +3076,7 @@ static virHypervisorDriver bhyveHypervisorDriver = {
.domainAuthorizedSSHKeysGet = bhyveDomainAuthorizedSSHKeysGet, /* 12.6.0 */
.domainAuthorizedSSHKeysSet = bhyveDomainAuthorizedSSHKeysSet, /* 12.6.0 */
.domainRename = bhyveDomainRename, /* 12.6.0 */
+ .domainGetGuestInfo = bhyveDomainGetGuestInfo, /* 12.7.0 */
};
--
2.52.0