[libvirt] [PATCH 2/2] bhyve: add e1000 nic support

Roman Bogorodskiy bogorodskiy at gmail.com
Sat Aug 27 13:11:57 UTC 2016


Recently e1000 NIC support was added to bhyve; implement that in
the bhyve driver:

 - Add capability check by analyzing output of the 'bhyve -s 0,e1000'
   command
 - Modify bhyveBuildNetArgStr() to support e1000 and also pass
   virConnectPtr so it could call bhyveDriverGetCaps() to check if this
   NIC is supported
 - Add net-e1000 test
---
 src/bhyve/bhyve_capabilities.c                     | 27 ++++++++++++++++++
 src/bhyve/bhyve_capabilities.h                     |  1 +
 src/bhyve/bhyve_command.c                          | 32 +++++++++++++++++++---
 .../bhyvexml2argvdata/bhyvexml2argv-net-e1000.args |  9 ++++++
 .../bhyvexml2argv-net-e1000.ldargs                 |  3 ++
 .../bhyvexml2argvdata/bhyvexml2argv-net-e1000.xml  | 22 +++++++++++++++
 tests/bhyvexml2argvtest.c                          |  7 ++++-
 7 files changed, 96 insertions(+), 5 deletions(-)
 create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-net-e1000.args
 create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-net-e1000.ldargs
 create mode 100644 tests/bhyvexml2argvdata/bhyvexml2argv-net-e1000.xml

diff --git a/src/bhyve/bhyve_capabilities.c b/src/bhyve/bhyve_capabilities.c
index be68e51..0ff34a3 100644
--- a/src/bhyve/bhyve_capabilities.c
+++ b/src/bhyve/bhyve_capabilities.c
@@ -192,6 +192,30 @@ bhyveProbeCapsRTC_UTC(unsigned int *caps, char *binary)
     return ret;
 }
 
+static int
+bhyveProbeCapsNetE1000(unsigned int *caps, char *binary)
+{
+    char *error;
+    virCommandPtr cmd = NULL;
+    int ret = 0, exit;
+
+    cmd = virCommandNew(binary);
+    virCommandAddArgList(cmd, "-s", "0,e1000", NULL);
+    virCommandSetErrorBuffer(cmd, &error);
+    if (virCommandRun(cmd, &exit) < 0) {
+	ret = -1;
+	goto out;
+    }
+
+    if (strstr(error, "pci slot 0:0: unknown device \"e1000\"") == 0)
+	*caps |= BHYVE_CAP_NET_E1000;
+
+ out:
+    VIR_FREE(error);
+    virCommandFree(cmd);
+    return ret;
+}
+
 int
 virBhyveProbeCaps(unsigned int *caps)
 {
@@ -207,6 +231,9 @@ virBhyveProbeCaps(unsigned int *caps)
     if ((ret = bhyveProbeCapsRTC_UTC(caps, binary)))
         goto out;
 
+    if ((ret = bhyveProbeCapsNetE1000(caps, binary)))
+        goto out;
+
  out:
     VIR_FREE(binary);
     return ret;
diff --git a/src/bhyve/bhyve_capabilities.h b/src/bhyve/bhyve_capabilities.h
index 8e7646d..d6c7bb0 100644
--- a/src/bhyve/bhyve_capabilities.h
+++ b/src/bhyve/bhyve_capabilities.h
@@ -38,6 +38,7 @@ typedef enum {
 
 typedef enum {
     BHYVE_CAP_RTC_UTC = 1,
+    BHYVE_CAP_NET_E1000 = 2,
 } virBhyveCapsFlags;
 
 int virBhyveProbeGrubCaps(virBhyveGrubCapsFlags *caps);
diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c
index 9ad3f9b..a4242c9 100644
--- a/src/bhyve/bhyve_command.c
+++ b/src/bhyve/bhyve_command.c
@@ -44,7 +44,8 @@
 VIR_LOG_INIT("bhyve.bhyve_command");
 
 static int
-bhyveBuildNetArgStr(const virDomainDef *def,
+bhyveBuildNetArgStr(virConnectPtr conn,
+                    const virDomainDef *def,
                     virDomainNetDefPtr net,
                     virCommandPtr cmd,
                     bool dryRun)
@@ -52,8 +53,30 @@ bhyveBuildNetArgStr(const virDomainDef *def,
     char macaddr[VIR_MAC_STRING_BUFLEN];
     char *realifname = NULL;
     char *brname = NULL;
+    char *nic_model = NULL;
     int actualType = virDomainNetGetActualType(net);
 
+    if (STREQ(net->model, "virtio")) {
+	if (VIR_STRDUP(nic_model, "virtio-net") < 0)
+	    return -1;
+    } else if (STREQ(net->model, "e1000")) {
+        if ((bhyveDriverGetCaps(conn) & BHYVE_CAP_NET_E1000) != 0) {
+	    if (VIR_STRDUP(nic_model, "e1000") < 0)
+		return -1;
+	} else {
+	    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+			   "%s",
+			   _("NIC model 'e1000' is not supported "
+			     "by given bhyve binary"));
+	    return -1;
+	}
+    } else {
+	virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+		       _("NIC model '%s' is not supported"),
+		       net->model);
+	return -1;
+    }
+
     if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
         if (VIR_STRDUP(brname, virDomainNetGetActualBridgeName(net)) < 0)
             return -1;
@@ -111,10 +134,11 @@ bhyveBuildNetArgStr(const virDomainDef *def,
 
 
     virCommandAddArg(cmd, "-s");
-    virCommandAddArgFormat(cmd, "%d:0,virtio-net,%s,mac=%s",
-                           net->info.addr.pci.slot,
+    virCommandAddArgFormat(cmd, "%d:0,%s,%s,mac=%s",
+                           net->info.addr.pci.slot, nic_model,
                            realifname, virMacAddrFormat(&net->mac, macaddr));
     VIR_FREE(realifname);
+    VIR_FREE(nic_model);
 
     return 0;
 }
@@ -284,7 +308,7 @@ virBhyveProcessBuildBhyveCmd(virConnectPtr conn,
     /* Devices */
     for (i = 0; i < def->nnets; i++) {
         virDomainNetDefPtr net = def->nets[i];
-        if (bhyveBuildNetArgStr(def, net, cmd, dryRun) < 0)
+        if (bhyveBuildNetArgStr(conn, def, net, cmd, dryRun) < 0)
             goto error;
     }
     for (i = 0; i < def->ndisks; i++) {
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-net-e1000.args b/tests/bhyvexml2argvdata/bhyvexml2argv-net-e1000.args
new file mode 100644
index 0000000..cd0e896
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-net-e1000.args
@@ -0,0 +1,9 @@
+/usr/sbin/bhyve \
+-c 1 \
+-m 214 \
+-u \
+-H \
+-P \
+-s 0:0,hostbridge \
+-s 3:0,e1000,faketapdev,mac=52:54:00:00:00:00 \
+-s 2:0,ahci-hd,/tmp/freebsd.img bhyve
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-net-e1000.ldargs b/tests/bhyvexml2argvdata/bhyvexml2argv-net-e1000.ldargs
new file mode 100644
index 0000000..32538b5
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-net-e1000.ldargs
@@ -0,0 +1,3 @@
+/usr/sbin/bhyveload \
+-m 214 \
+-d /tmp/freebsd.img bhyve
diff --git a/tests/bhyvexml2argvdata/bhyvexml2argv-net-e1000.xml b/tests/bhyvexml2argvdata/bhyvexml2argv-net-e1000.xml
new file mode 100644
index 0000000..4b3148c
--- /dev/null
+++ b/tests/bhyvexml2argvdata/bhyvexml2argv-net-e1000.xml
@@ -0,0 +1,22 @@
+<domain type='bhyve'>
+  <name>bhyve</name>
+  <uuid>df3be7e7-a104-11e3-aeb0-50e5492bd3dc</uuid>
+  <memory>219136</memory>
+  <vcpu>1</vcpu>
+  <os>
+    <type>hvm</type>
+  </os>
+  <devices>
+    <disk type='file'>
+      <driver name='file' type='raw'/>
+      <source file='/tmp/freebsd.img'/>
+      <target dev='hda' bus='sata'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+    </disk>
+    <interface type='bridge'>
+      <model type='e1000'/>
+      <source bridge="virbr0"/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+    </interface>
+  </devices>
+</domain>
diff --git a/tests/bhyvexml2argvtest.c b/tests/bhyvexml2argvtest.c
index 7a2d366..57a050c 100644
--- a/tests/bhyvexml2argvtest.c
+++ b/tests/bhyvexml2argvtest.c
@@ -151,7 +151,7 @@ mymain(void)
     DO_TEST_FULL(name, FLAG_EXPECT_PARSE_ERROR)
 
     driver.grubcaps = BHYVE_GRUB_CAP_CONSDEV;
-    driver.bhyvecaps = BHYVE_CAP_RTC_UTC;
+    driver.bhyvecaps = BHYVE_CAP_RTC_UTC | BHYVE_CAP_NET_E1000;
 
     DO_TEST("base");
     DO_TEST("acpiapic");
@@ -174,11 +174,16 @@ mymain(void)
     DO_TEST("disk-cdrom-grub");
     DO_TEST("serial-grub");
     DO_TEST("localtime");
+    DO_TEST("net-e1000");
 
     driver.grubcaps = 0;
 
     DO_TEST("serial-grub-nocons");
 
+    driver.bhyvecaps &= ~BHYVE_CAP_NET_E1000;
+
+    DO_TEST_FAILURE("net-e1000");
+
     virObjectUnref(driver.caps);
     virObjectUnref(driver.xmlopt);
 
-- 
2.9.2




More information about the libvir-list mailing list