To ease mocking for bhyve unit tests move virBhyveTapGetRealDeviceName()
out of bhyve_command.c to virnetdevtap and rename it to
virNetDevTapGetRealDeviceName().
---
 src/bhyve/bhyve_command.c | 74 +---------------------------------------
 src/libvirt_private.syms  |  1 +
 src/util/virnetdevtap.c   | 87 +++++++++++++++++++++++++++++++++++++++++++++++
 src/util/virnetdevtap.h   |  3 ++
 4 files changed, 92 insertions(+), 73 deletions(-)

diff --git a/src/bhyve/bhyve_command.c b/src/bhyve/bhyve_command.c
index 42b71fb..3373cfc 100644
--- a/src/bhyve/bhyve_command.c
+++ b/src/bhyve/bhyve_command.c
@@ -21,10 +21,7 @@
 
 #include <config.h>
 
-#include <fcntl.h>
 #include <sys/types.h>
-#include <dirent.h>
-#include <sys/ioctl.h>
 #include <net/if.h>
 #include <net/if_tap.h>
 
@@ -41,75 +38,6 @@
 
 VIR_LOG_INIT("bhyve.bhyve_command");
 
-static char*
-virBhyveTapGetRealDeviceName(char *name)
-{
-    /* This is an ugly hack, because if we rename
-     * tap device to vnet%d, its device name will be
-     * still /dev/tap%d, and bhyve tries to open /dev/tap%d,
-     * so we have to find the real name
-     */
-    char *ret = NULL;
-    struct dirent *dp;
-    char *devpath = NULL;
-    int fd;
-
-    DIR *dirp = opendir("/dev");
-    if (dirp == NULL) {
-        virReportSystemError(errno,
-                             _("Failed to opendir path '%s'"),
-                             "/dev");
-        return NULL;
-    }
-
-    while ((dp = readdir(dirp)) != NULL) {
-        if (STRPREFIX(dp->d_name, "tap")) {
-            struct ifreq ifr;
-            if (virAsprintf(&devpath, "/dev/%s", dp->d_name) < 0) {
-                goto cleanup;
-            }
-            if ((fd = open(devpath, O_RDWR)) < 0) {
-                if (errno == EBUSY) {
-                    VIR_FREE(devpath);
-                    continue;
-                }
-                virReportSystemError(errno, _("Unable to open '%s'"), devpath);
-                goto cleanup;
-            }
-
-            if (ioctl(fd, TAPGIFNAME, (void *)&ifr) < 0) {
-                virReportSystemError(errno, "%s",
-                                     _("Unable to query tap interface name"));
-                goto cleanup;
-            }
-
-            if (STREQ(name, ifr.ifr_name)) {
-                /* we can ignore the return value
-                 * because we still have nothing
-                 * to do but return;
-                 */
-                ignore_value(VIR_STRDUP(ret, dp->d_name));
-                goto cleanup;
-            }
-
-            VIR_FREE(devpath);
-            VIR_FORCE_CLOSE(fd);
-        }
-
-        errno = 0;
-    }
-
-    if (errno != 0)
-        virReportSystemError(errno, "%s",
-                             _("Unable to iterate over TAP devices"));
-
- cleanup:
-    VIR_FREE(devpath);
-    VIR_FORCE_CLOSE(fd);
-    closedir(dirp);
-    return ret;
-}
-
 static int
 bhyveBuildNetArgStr(const virDomainDef *def, virCommandPtr cmd)
 {
@@ -161,7 +89,7 @@ bhyveBuildNetArgStr(const virDomainDef *def, virCommandPtr 
cmd)
         }
     }
 
-    realifname = virBhyveTapGetRealDeviceName(net->ifname);
+    realifname = virNetDevTapGetRealDeviceName(net->ifname);
 
     if (realifname == NULL) {
         VIR_FREE(net->ifname);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 2357f95..38fbf63 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1584,6 +1584,7 @@ virNetDevTapCreate;
 virNetDevTapCreateInBridgePort;
 virNetDevTapDelete;
 virNetDevTapGetName;
+virNetDevTapGetRealDeviceName;
 
 
 # util/virnetdevveth.h
diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c
index 32ad406..3072146 100644
--- a/src/util/virnetdevtap.c
+++ b/src/util/virnetdevtap.c
@@ -22,6 +22,9 @@
 
 #include <config.h>
 
+#include <sys/types.h>
+#include <dirent.h>
+
 #include "virmacaddr.h"
 #include "virnetdevtap.h"
 #include "virnetdev.h"
@@ -38,8 +41,11 @@
 #include <fcntl.h>
 #ifdef __linux__
 # include <linux/if_tun.h>    /* IFF_TUN, IFF_NO_PI */
+#elif defined(__FreeBSD__)
+# include <net/if_tap.h>
 #endif
 
+
 #define VIR_FROM_THIS VIR_FROM_NONE
 
 VIR_LOG_INIT("util.netdevtap");
@@ -72,6 +78,87 @@ virNetDevTapGetName(int tapfd ATTRIBUTE_UNUSED, char 
**ifname ATTRIBUTE_UNUSED)
 #endif
 }
 
+/**
+ * virNetDevTapGetRealDeviceName:
+ * @ifname: the interface name
+ *
+ * Lookup real interface name (i.e. name of the device entry in /dev),
+ * because e.g. on FreeBSD if we rename tap device to vnetN its device
+ * entry still remains unchanged (/dev/tapX), but bhyve needs a name
+ * that matches /dev entry.
+ *
+ * Returns the proper interface name or NULL if no corresponding interface
+ * found.
+ */
+char*
+virNetDevTapGetRealDeviceName(char *ifname ATTRIBUTE_UNUSED)
+{
+#ifdef TAPGIFNAME
+    char *ret = NULL;
+    struct dirent *dp;
+    char *devpath = NULL;
+    int fd;
+
+    DIR *dirp = opendir("/dev");
+    if (dirp == NULL) {
+        virReportSystemError(errno,
+                             _("Failed to opendir path '%s'"),
+                             "/dev");
+        return NULL;
+    }
+
+    while ((dp = readdir(dirp)) != NULL) {
+        if (STRPREFIX(dp->d_name, "tap")) {
+            struct ifreq ifr;
+            if (virAsprintf(&devpath, "/dev/%s", dp->d_name) < 0) {
+                goto cleanup;
+            }
+            if ((fd = open(devpath, O_RDWR)) < 0) {
+                if (errno == EBUSY) {
+                    VIR_FREE(devpath);
+                    continue;
+                }
+
+                virReportSystemError(errno, _("Unable to open '%s'"), devpath);
+                goto cleanup;
+            }
+
+            if (ioctl(fd, TAPGIFNAME, (void *)&ifr) < 0) {
+                virReportSystemError(errno, "%s",
+                                     _("Unable to query tap interface name"));
+                goto cleanup;
+            }
+
+            if (STREQ(ifname, ifr.ifr_name)) {
+                /* we can ignore the return value
+                 * because we still have nothing
+                 * to do but return;
+                 */
+                ignore_value(VIR_STRDUP(ret, dp->d_name));
+                goto cleanup;
+            }
+
+            VIR_FREE(devpath);
+            VIR_FORCE_CLOSE(fd);
+        }
+
+        errno = 0;
+    }
+
+    if (errno != 0)
+        virReportSystemError(errno, "%s",
+                             _("Unable to iterate over TAP devices"));
+
+ cleanup:
+    VIR_FREE(devpath);
+    VIR_FORCE_CLOSE(fd);
+    closedir(dirp);
+    return ret;
+#else
+    return NULL;
+#endif
+}
+
 
 /**
  * virNetDevProbeVnetHdr:
diff --git a/src/util/virnetdevtap.h b/src/util/virnetdevtap.h
index 1e5bd19..03fb5f8 100644
--- a/src/util/virnetdevtap.h
+++ b/src/util/virnetdevtap.h
@@ -45,6 +45,9 @@ int virNetDevTapDelete(const char *ifname)
 int virNetDevTapGetName(int tapfd, char **ifname)
     ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
 
+char* virNetDevTapGetRealDeviceName(char *ifname)
+      ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
+
 typedef enum {
    VIR_NETDEV_TAP_CREATE_NONE = 0,
    /* Bring the interface up */
-- 
1.8.4.2

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to