So, for the multiqueue on macvtaps we are going to need to open
the device multiple times. Currently, this is not supported.
Rework the function, so that upper layers can be reworked too.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/util/virnetdevmacvlan.c | 58 ++++++++++++++++++++++++++++-----------------
1 file changed, 36 insertions(+), 22 deletions(-)
diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c
index c1a5f0f..d20990b 100644
--- a/src/util/virnetdevmacvlan.c
+++ b/src/util/virnetdevmacvlan.c
@@ -226,15 +226,21 @@ int virNetDevMacVLanDelete(const char *ifname)
/**
* virNetDevMacVLanTapOpen:
- * Open the macvtap's tap device.
* @ifname: Name of the macvtap interface
+ * @tapfd: array of file descriptor return value for the new macvtap device
+ * @tapfdSize: number of file descriptors in @tapfd
* @retries : Number of retries in case udev for example may need to be
* waited for to create the tap chardev
- * Returns negative value in case of error, the file descriptor otherwise.
+ *
+ * Open the macvtap's tap device, possibly multiple times if @tapfdSize > 1.
+ *
+ * Returns 0 on success, -1 otherwise.
*/
-static
-int virNetDevMacVLanTapOpen(const char *ifname,
- int retries)
+static int
+virNetDevMacVLanTapOpen(const char *ifname,
+ int *tapfd,
+ size_t tapfdSize,
+ int retries)
{
int ret = -1;
char *path;
@@ -242,7 +248,8 @@ int virNetDevMacVLanTapOpen(const char *ifname,
char *tapname = NULL;
char *buf = NULL;
char *c;
- int tapfd;
+ size_t i = 0;
+ int fd = -1;
if (virNetDevSysfsFile(&path, ifname, "ifindex") < 0)
return -1;
@@ -260,25 +267,32 @@ int virNetDevMacVLanTapOpen(const char *ifname,
if (virAsprintf(&tapname, "/dev/tap%d", ifindex) < 0)
goto cleanup;
- while (1) {
- /* may need to wait for udev to be done */
- tapfd = open(tapname, O_RDWR);
- if (tapfd < 0 && retries > 0) {
- retries--;
- usleep(20000);
- continue;
+ for (i = 0; i < tapfdSize; i++) {
+ retry:
+ fd = open(tapname, O_RDWR);
+ if (fd < 0) {
+ if (retries > 0) {
+ /* may need to wait for udev to be done */
+ retries--;
+ usleep(20000);
+ goto retry;
+ }
+ /* However, if haven't succeeded, quit. */
+ virReportSystemError(errno,
+ _("cannot open macvtap tap device %s"),
+ tapname);
+ goto cleanup;
}
- break;
+ tapfd[i] = fd;
}
- if (tapfd < 0) {
- virReportSystemError(errno,
- _("cannot open macvtap tap device %s"),
- tapname);
- goto cleanup;
- }
- ret = tapfd;
+ ret = 0;
+
cleanup:
+ if (ret < 0) {
+ while (i--)
+ VIR_FORCE_CLOSE(tapfd[i]);
+ }
VIR_FREE(path);
VIR_FREE(tapname);
VIR_FREE(buf);
@@ -847,7 +861,7 @@ int virNetDevMacVLanCreateWithVPortProfile(const char *tgifname,
}
if (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) {
- if ((rc = virNetDevMacVLanTapOpen(cr_ifname, 10)) < 0)
+ if (virNetDevMacVLanTapOpen(cr_ifname, &rc, 1, 10) < 0)
goto disassociate_exit;
if (virNetDevMacVLanTapSetup(rc, vnet_hdr) < 0) {
--
2.4.10