Currently, to probe PCI devices, for each device libvirt
calls "bhyve -s 0,<device_type>" and parses the error message to check
if this specific device is supported.

For quite some time, bhyve reports the list of devices using:

 bhyve -s help

where it prints all supported devices, one device per line.

Update the code to use this command:

 * It is more accurate as we don't need to rely on the error message
   parsing.
 * It's faster as we get all the devices in one run instead of
   running bhyve for every device type.
 * The code is simpler.

Signed-off-by: Roman Bogorodskiy <[email protected]>
---
 src/bhyve/bhyve_capabilities.c | 139 ++++++++++-----------------------
 1 file changed, 40 insertions(+), 99 deletions(-)

diff --git a/src/bhyve/bhyve_capabilities.c b/src/bhyve/bhyve_capabilities.c
index 0585fff8e9..2e5e2ae3bc 100644
--- a/src/bhyve/bhyve_capabilities.c
+++ b/src/bhyve/bhyve_capabilities.c
@@ -258,24 +258,51 @@ bhyveProbeCapsFromHelp(unsigned int *caps, char *binary)
 }
 
 static int
-bhyveProbeCapsAHCI32Slot(unsigned int *caps, char *binary)
+bhyveFillCapForDevice(unsigned int *caps, const char *device)
 {
-    return bhyveProbeCapsDeviceHelper(caps, binary,
-                                      "-s",
-                                      "0,ahci",
-                                      "pci slot 0:0: unknown device \"ahci\"",
-                                      BHYVE_CAP_AHCI32SLOT);
+   if (STREQ(device, "ahci"))
+       *caps |= BHYVE_CAP_AHCI32SLOT;
+   else if (STREQ(device, "e1000"))
+       *caps |= BHYVE_CAP_NET_E1000;
+   else if (STREQ(device, "fbuf"))
+       *caps |= BHYVE_CAP_FBUF;
+   else if (STREQ(device, "hda"))
+       *caps |= BHYVE_CAP_SOUND_HDA;
+   else if (STREQ(device, "nvme"))
+       *caps |= BHYVE_CAP_NVME;
+   else if (STREQ(device, "virtio-9p"))
+       *caps |= BHYVE_CAP_VIRTIO_9P;
+   else if (STREQ(device, "virtio-rnd"))
+       *caps |= BHYVE_CAP_VIRTIO_RND;
+   else if (STREQ(device, "xhci"))
+       *caps |= BHYVE_CAP_XHCI;
+
+   return 0;
 }
 
 
 static int
-bhyveProbeCapsNetE1000(unsigned int *caps, char *binary)
+bhyveProbeCapsFromSHelp(unsigned int *caps, char *binary)
 {
-    return bhyveProbeCapsDeviceHelper(caps, binary,
-                                      "-s",
-                                      "0,e1000",
-                                      "pci slot 0:0: unknown device \"e1000\"",
-                                      BHYVE_CAP_NET_E1000);
+    g_autofree char *help = NULL;
+    g_autoptr(virCommand) cmd = NULL;
+    int exit;
+    char *cur = NULL;
+    char *saveptr = NULL;
+
+    cmd = virCommandNew(binary);
+    virCommandAddArgList(cmd, "-s", "help", NULL);
+    virCommandSetOutputBuffer(cmd, &help);
+    if (virCommandRun(cmd, &exit) < 0)
+        return -1;
+
+    cur = strtok_r(help, "\n", &saveptr);
+    while (cur != NULL) {
+        bhyveFillCapForDevice(caps, cur);
+        cur = strtok_r(NULL, "\n", &saveptr);
+    }
+
+    return 0;
 }
 
 static int
@@ -289,39 +316,6 @@ bhyveProbeCapsLPC_Bootrom(unsigned int *caps, char *binary)
 }
 
 
-static int
-bhyveProbeCapsFramebuffer(unsigned int *caps, char *binary)
-{
-    return bhyveProbeCapsDeviceHelper(caps, binary,
-                                      "-s",
-                                      "0,fbuf",
-                                      "pci slot 0:0: unknown device \"fbuf\"",
-                                      BHYVE_CAP_FBUF);
-}
-
-
-static int
-bhyveProbeCapsXHCIController(unsigned int *caps, char *binary)
-{
-    return bhyveProbeCapsDeviceHelper(caps, binary,
-                                      "-s",
-                                      "0,xhci",
-                                      "pci slot 0:0: unknown device \"xhci\"",
-                                      BHYVE_CAP_FBUF);
-}
-
-
-static int
-bhyveProbeCapsSoundHda(unsigned int *caps, char *binary)
-{
-    return bhyveProbeCapsDeviceHelper(caps, binary,
-                                      "-s",
-                                      "0,hda",
-                                      "pci slot 0:0: unknown device \"hda\"",
-                                      BHYVE_CAP_SOUND_HDA);
-}
-
-
 static int
 bhyveProbeCapsVNCPassword(unsigned int *caps, char *binary)
 {
@@ -333,39 +327,6 @@ bhyveProbeCapsVNCPassword(unsigned int *caps, char *binary)
 }
 
 
-static int
-bhyveProbeCapsVirtio9p(unsigned int *caps, char *binary)
-{
-    return bhyveProbeCapsDeviceHelper(caps, binary,
-                                      "-s",
-                                      "0,virtio-9p",
-                                      "pci slot 0:0: unknown device \"hda\"",
-                                      BHYVE_CAP_VIRTIO_9P);
-}
-
-
-static int
-bhyveProbeCapsVirtioRnd(unsigned int *caps, char *binary)
-{
-    return bhyveProbeCapsDeviceHelper(caps, binary,
-                                      "-s",
-                                      "0,virtio-rnd",
-                                      "pci slot 0:0: unknown device 
\"virtio-rnd\"",
-                                      BHYVE_CAP_VIRTIO_RND);
-}
-
-
-static int
-bhyveProbeCapsNvme(unsigned int *caps, char *binary)
-{
-    return bhyveProbeCapsDeviceHelper(caps, binary,
-                                      "-s",
-                                      "0,nvme",
-                                      "pci slot 0:0: unknown device \"nvme\"",
-                                      BHYVE_CAP_NVME);
-}
-
-
 int
 virBhyveProbeCaps(unsigned int *caps)
 {
@@ -379,35 +340,15 @@ virBhyveProbeCaps(unsigned int *caps)
     if ((ret = bhyveProbeCapsFromHelp(caps, binary)))
         goto out;
 
-    if ((ret = bhyveProbeCapsAHCI32Slot(caps, binary)))
-        goto out;
-
-    if ((ret = bhyveProbeCapsNetE1000(caps, binary)))
+    if ((ret = bhyveProbeCapsFromSHelp(caps, binary)))
         goto out;
 
     if ((ret = bhyveProbeCapsLPC_Bootrom(caps, binary)))
         goto out;
 
-    if ((ret = bhyveProbeCapsFramebuffer(caps, binary)))
-        goto out;
-
-    if ((ret = bhyveProbeCapsXHCIController(caps, binary)))
-        goto out;
-
-    if ((ret = bhyveProbeCapsSoundHda(caps, binary)))
-        goto out;
-
     if ((ret = bhyveProbeCapsVNCPassword(caps, binary)))
         goto out;
 
-    if ((ret = bhyveProbeCapsVirtio9p(caps, binary)))
-        goto out;
-
-    if ((ret = bhyveProbeCapsVirtioRnd(caps, binary)))
-        goto out;
-
-    if ((ret = bhyveProbeCapsNvme(caps, binary)))
-        goto out;
 
  out:
     VIR_FREE(binary);
-- 
2.52.0

Reply via email to