This implementation is identical to the one found in the qemu driver.
Signed-off-by: Roman Bogorodskiy <[email protected]>
---
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