mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 11:22:23 +00:00
Move virBhyveTapGetRealDeviceName to virnetdevtap
To ease mocking for bhyve unit tests move virBhyveTapGetRealDeviceName() out of bhyve_command.c to virnetdevtap and rename it to virNetDevTapGetRealDeviceName().
This commit is contained in:
parent
6612d1adb7
commit
a1bd8d2546
@ -21,10 +21,7 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <dirent.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <net/if_tap.h>
|
#include <net/if_tap.h>
|
||||||
|
|
||||||
@ -41,75 +38,6 @@
|
|||||||
|
|
||||||
VIR_LOG_INIT("bhyve.bhyve_command");
|
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
|
static int
|
||||||
bhyveBuildNetArgStr(const virDomainDef *def, virCommandPtr cmd)
|
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) {
|
if (realifname == NULL) {
|
||||||
VIR_FREE(net->ifname);
|
VIR_FREE(net->ifname);
|
||||||
|
@ -1584,6 +1584,7 @@ virNetDevTapCreate;
|
|||||||
virNetDevTapCreateInBridgePort;
|
virNetDevTapCreateInBridgePort;
|
||||||
virNetDevTapDelete;
|
virNetDevTapDelete;
|
||||||
virNetDevTapGetName;
|
virNetDevTapGetName;
|
||||||
|
virNetDevTapGetRealDeviceName;
|
||||||
|
|
||||||
|
|
||||||
# util/virnetdevveth.h
|
# util/virnetdevveth.h
|
||||||
|
@ -33,11 +33,15 @@
|
|||||||
#include "virlog.h"
|
#include "virlog.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
# include <linux/if_tun.h> /* IFF_TUN, IFF_NO_PI */
|
# include <linux/if_tun.h> /* IFF_TUN, IFF_NO_PI */
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
# include <net/if_tap.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_NONE
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
||||||
@ -72,6 +76,87 @@ virNetDevTapGetName(int tapfd ATTRIBUTE_UNUSED, char **ifname ATTRIBUTE_UNUSED)
|
|||||||
#endif
|
#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:
|
* virNetDevProbeVnetHdr:
|
||||||
|
@ -45,6 +45,9 @@ int virNetDevTapDelete(const char *ifname)
|
|||||||
int virNetDevTapGetName(int tapfd, char **ifname)
|
int virNetDevTapGetName(int tapfd, char **ifname)
|
||||||
ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
|
ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
|
||||||
|
|
||||||
|
char* virNetDevTapGetRealDeviceName(char *ifname)
|
||||||
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VIR_NETDEV_TAP_CREATE_NONE = 0,
|
VIR_NETDEV_TAP_CREATE_NONE = 0,
|
||||||
/* Bring the interface up */
|
/* Bring the interface up */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user