This implementation is identical to the one found in the qemu driver. Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> --- src/bhyve/bhyve_driver.c | 139 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c index 2556384002..f93e6c7b68 100644 --- a/src/bhyve/bhyve_driver.c +++ b/src/bhyve/bhyve_driver.c @@ -2307,6 +2307,144 @@ bhyveDomainSetMemoryParameters(virDomainPtr domain, return ret; } +static int +bhyveDomainGetFSInfoAgent(virDomainObj *vm, + qemuAgentFSInfo ***info) +{ + int ret = -1; + qemuAgent *agent; + + if (virDomainObjBeginAgentJob(vm, VIR_AGENT_JOB_QUERY) < 0) + return ret; + + if (virDomainObjCheckActive(vm) < 0) + goto endjob; + + if (bhyveDomainEnsureAgent(vm, true) < 0) + goto endjob; + + agent = bhyveDomainObjEnterAgent(vm); + ret = qemuAgentGetFSInfo(agent, info, true); + bhyveDomainObjExitAgent(vm, agent); + + endjob: + virDomainObjEndAgentJob(vm); + return ret; +} + +static virDomainFSInfoPtr +qemuAgentFSInfoToPublic(qemuAgentFSInfo *agent, + virDomainDef *vmdef) +{ + virDomainFSInfoPtr ret = NULL; + size_t i; + + ret = g_new0(virDomainFSInfo, 1); + + ret->mountpoint = g_strdup(agent->mountpoint); + ret->name = g_strdup(agent->name); + ret->fstype = g_strdup(agent->fstype); + + if (agent->disks) + ret->devAlias = g_new0(char *, agent->ndisks); + + for (i = 0; i < agent->ndisks; i++) { + qemuAgentDiskAddress *agentdisk = agent->disks[i]; + virDomainDiskDef *diskDef; + + diskDef = virDomainDiskByAddress(vmdef, + &agentdisk->pci_controller, + agentdisk->ccw_addr, + agentdisk->bus, + agentdisk->target, + agentdisk->unit); + if (diskDef != NULL) + ret->devAlias[ret->ndevAlias++] = g_strdup(diskDef->dst); + else + VIR_DEBUG("Missing target name for '%s'.", ret->mountpoint); + } + + return ret; +} + +/* Returns: 0 on success + * -1 otherwise + */ +static int +virDomainFSInfoFormat(qemuAgentFSInfo **agentinfo, + int nagentinfo, + virDomainDef *vmdef, + virDomainFSInfoPtr **info) +{ + int ret = -1; + virDomainFSInfoPtr *info_ret = NULL; + size_t i; + + info_ret = g_new0(virDomainFSInfoPtr, nagentinfo); + + for (i = 0; i < nagentinfo; i++) { + if (!(info_ret[i] = qemuAgentFSInfoToPublic(agentinfo[i], vmdef))) + goto cleanup; + } + + *info = g_steal_pointer(&info_ret); + ret = nagentinfo; + + cleanup: + if (info_ret) { + for (i = 0; i < nagentinfo; i++) { + /* if there was an error, free any memory we've allocated for the + * return value */ + virDomainFSInfoFree(info_ret[i]); + } + g_free(info_ret); + } + return ret; +} + +static int +bhyveDomainGetFSInfo(virDomainPtr dom, + virDomainFSInfoPtr **info, + unsigned int flags) +{ + virDomainObj *vm; + qemuAgentFSInfo **agentinfo = NULL; + int ret = -1; + int nfs = 0; + + virCheckFlags(0, ret); + + if (!(vm = bhyveDomObjFromDomain(dom))) + return ret; + + if (virDomainGetFSInfoEnsureACL(dom->conn, vm->def) < 0) + goto cleanup; + + if ((nfs = bhyveDomainGetFSInfoAgent(vm, &agentinfo)) < 0) + goto cleanup; + + if (virDomainObjBeginJob(vm, VIR_JOB_QUERY) < 0) + goto cleanup; + + if (virDomainObjCheckActive(vm) < 0) + goto endjob; + + ret = virDomainFSInfoFormat(agentinfo, nfs, vm->def, info); + + endjob: + virDomainObjEndJob(vm); + + cleanup: + if (agentinfo) { + size_t i; + for (i = 0; i < nfs; i++) + qemuAgentFSInfoFree(agentinfo[i]); + g_free(agentinfo); + } + virDomainObjEndAPI(&vm); + return ret; +} + static virHypervisorDriver bhyveHypervisorDriver = { .name = "bhyve", .connectURIProbe = bhyveConnectURIProbe, @@ -2378,6 +2516,7 @@ static virHypervisorDriver bhyveHypervisorDriver = { .domainQemuAgentCommand = bhyveDomainQemuAgentCommand, /* 12.4.0 */ .domainGetMemoryParameters = bhyveDomainGetMemoryParameters, /* 12.4.0 */ .domainSetMemoryParameters = bhyveDomainSetMemoryParameters, /* 12.4.0 */ + .domainGetFSInfo = bhyveDomainGetFSInfo, /* 12.4.0 */ }; -- 2.52.0