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

Reply via email to