[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH 2/2] Modify generic ethernet interface so it will work when sVirt is enabled with qemu



On 09/20/2011 05:18 PM, Tyler Coumbes wrote:
Update code to create generic ethernet interfaces using the new
utility library tunctl making
changes to create the TAP device in libvirt and pass it to qemu as a
file descriptor.

This patch doesn't refactor src/util/bridge.c either, which means that if applied, we would have two copies of very similar code in two different files - that's a maintenance nightmare. We'll definitely need a v2 patch series that refactors things with minimal duplication.

Or, can this patch directly use the existing br* interfaces, instead of introducing a new file in patch 1/2?


---

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index ee4b52b..181f56c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -396,6 +396,51 @@ qemuOpenVhostNet(virDomainDefPtr def,
  }


+int qemuEthernetIfaceCreate(virDomainDefPtr def,
+                            virDomainNetDefPtr net,
+                            virBitmapPtr qemuCaps)
+{
+    int tapfd;
+    int err;
+    int vnet_hdr = 0;
+    unsigned char tapmac[VIR_MAC_BUFLEN];
+
+    if (qemuCapsGet(qemuCaps, QEMU_CAPS_VNET_HDR)&&
+        net->model&&  STREQ(net->model, "virtio"))
+        vnet_hdr = 1;
+
+    if (!net->ifname ||
+        STRPREFIX(net->ifname, "vnet") ||
+        strchr(net->ifname, '%')) {
+        VIR_FREE(net->ifname);
+        if (!(net->ifname = strdup("vnet%d"))) {
+            virReportOOMError();
+            return -1;
+        }
+    }
+
+    err = createTap(&net->ifname, vnet_hdr,&tapfd);
+    virDomainAuditNetDevice(def, net, "/dev/net/tun", tapfd>= 0);
+    if (tapfd<  0 || err)
+        return -1;
+
+    memcpy(tapmac, net->mac, VIR_MAC_BUFLEN);
+    /* Discourage bridge from using TAP dev MAC */
+    tapmac[0] = 0xFE;
+    err = tapSetInterfaceMac(net->ifname, tapmac);
+
+    if (err)
+        return -1;

This leaks tapfd. Our style tends to use 'goto error' to ensure that all cleanup occurs at the end, rather than 'return' in the middle of a function.

+
+    err = tapSetInterfaceUp(net->ifname, 1);
+
+    if (err)
+        return -1;
+
+    return tapfd;
+}
+
+
  static int qemuDomainDeviceAliasIndex(virDomainDeviceInfoPtr info,
                                        const char *prefix)
@@ -4064,6 +4112,18 @@ qemuBuildCommandLine(virConnectPtr conn,
                  if (snprintf(tapfd_name, sizeof(tapfd_name), "%d",
                               tapfd)>= sizeof(tapfd_name))
                      goto no_memory;
+            } else if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET&&
+                       !net->data.ethernet.script) {
+                int tapfd = qemuEthernetIfaceCreate(def, net, qemuCaps);
+                if (tapfd<  0)
+                    goto error;
+
+                last_good_net = i;
+                virCommandTransferFD(cmd, tapfd);

Check for failure to transfer the fd, and abort the command in that case (hmm, that's a pre-existing problem with the other fd transfers in this function).

--
Eric Blake   eblake redhat com    +1-801-349-2682
Libvirt virtualization library http://libvirt.org


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]