bhyve: implement virDomainGetGuestInfo()

Implementation is pretty similar to the one found in the qemu driver.

Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
Roman Bogorodskiy committed 2026-08-13 19:01:12 +02:00
1 parent c2b1b9f745
commit e0a2cc5cd6
1 file changed
+192
+192
View File
@@ -2854,6 +2854,197 @@ bhyveDomainAgentSetResponseTimeout(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,
@@ -2933,6 +3124,7 @@ static virHypervisorDriver bhyveHypervisorDriver = {
.domainAuthorizedSSHKeysSet = bhyveDomainAuthorizedSSHKeysSet, /* 12.5.0 */
.domainRename = bhyveDomainRename, /* 12.6.0 */
.domainAgentSetResponseTimeout = bhyveDomainAgentSetResponseTimeout, /* 12.7.0 */
.domainGetGuestInfo = bhyveDomainGetGuestInfo, /* 12.7.0 */
};