]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
qemu: fix ifindex array reported to systemd
authorLaine Stump <laine@laine.org>
Fri, 20 Feb 2015 19:52:37 +0000 (14:52 -0500)
committerLaine Stump <laine@laine.org>
Wed, 25 Feb 2015 18:11:14 +0000 (13:11 -0500)
Commit f7afeddc added code to report to systemd an array of interface
indexes for all tap devices used by a guest. Unfortunately it not only
didn't add code to report the ifindexes for macvtap interfaces
(interface type='direct') or the tap devices used by type='ethernet',
it ended up sending "-1" as the ifindex for each macvtap or hostdev
interface. This resulted in a failure to start any domain that had a
macvtap or hostdev interface (or actually any type other than
"network" or "bridge").

This patch does the following with the nicindexes array:

1) Modify qemuBuildInterfaceCommandLine() to only fill in the
nicindexes array if given a non-NULL pointer to an array (and modifies
the test jig calls to the function to send NULL). This is because
there are tests in the test suite that have type='ethernet' and still
have an ifname specified, but that device of course doesn't actually
exist on the test system, so attempts to call virNetDevGetIndex() will
fail.

2) Even then, only add an entry to the nicindexes array for
appropriate types, and to do so for all appropriate types ("network",
"bridge", and "direct"), but only if the ifname is known (since that
is required to call virNetDevGetIndex().

src/qemu/qemu_command.c
src/qemu/qemu_command.h
src/qemu/qemu_driver.c
src/qemu/qemu_hotplug.c
tests/qemuxml2argvtest.c
tests/qemuxmlnstest.c

index dd06f099974d1d831b9d0261d7c814a1d1e9335a..24b2ad95b4e21200f3e56fa8fb5f8b0ecbe2adc0 100644 (file)
@@ -289,8 +289,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
                         virDomainNetDefPtr net,
                         virQEMUCapsPtr qemuCaps,
                         int *tapfd,
-                        size_t *tapfdSize,
-                        int *nicindex)
+                        size_t *tapfdSize)
 {
     const char *brname;
     int ret = -1;
@@ -337,8 +336,6 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
             virDomainAuditNetDevice(def, net, tunpath, false);
             goto cleanup;
         }
-        if (virNetDevGetIndex(net->ifname, nicindex) < 0)
-            goto cleanup;
         if (virDomainNetGetActualBridgeMACTableManager(net)
             == VIR_NETWORK_BRIDGE_MAC_TABLE_MANAGER_LIBVIRT) {
             /* libvirt is managing the FDB of the bridge this device
@@ -7757,7 +7754,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
                               int bootindex,
                               virNetDevVPortProfileOp vmop,
                               bool standalone,
-                              int *nicindex)
+                              size_t *nnicindexes,
+                              int **nicindexes)
 {
     int ret = -1;
     char *nic = NULL, *host = NULL;
@@ -7771,8 +7769,6 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
     virNetDevBandwidthPtr actualBandwidth;
     size_t i;
 
-    *nicindex = -1;
-
     if (actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER)
         return qemuBuildVhostuserCommandLine(cmd, def, net, qemuCaps);
 
@@ -7819,7 +7815,7 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
 
         if (qemuNetworkIfaceConnect(def, driver, net,
                                     qemuCaps, tapfd,
-                                    &tapfdSize, nicindex) < 0)
+                                    &tapfdSize) < 0)
             goto cleanup;
     } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
         if (VIR_ALLOC(tapfd) < 0 || VIR_ALLOC(tapfdName) < 0)
@@ -7831,6 +7827,49 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
             goto cleanup;
     }
 
+    /* For types whose implementations use a netdev on the host, add
+     * an entry to nicindexes for passing on to systemd.
+    */
+    switch ((virDomainNetType)actualType) {
+    case VIR_DOMAIN_NET_TYPE_ETHERNET:
+    case VIR_DOMAIN_NET_TYPE_NETWORK:
+    case VIR_DOMAIN_NET_TYPE_BRIDGE:
+    case VIR_DOMAIN_NET_TYPE_DIRECT:
+    {
+        int nicindex;
+
+        /* network and bridge use a tap device, and direct uses a
+         * macvtap device
+         */
+        if (nicindexes && nnicindexes && net->ifname) {
+            if (virNetDevGetIndex(net->ifname, &nicindex) < 0 ||
+                VIR_APPEND_ELEMENT(*nicindexes, *nnicindexes, nicindex) < 0)
+                goto cleanup;
+        }
+        break;
+    }
+
+    case VIR_DOMAIN_NET_TYPE_USER:
+    case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
+    case VIR_DOMAIN_NET_TYPE_SERVER:
+    case VIR_DOMAIN_NET_TYPE_CLIENT:
+    case VIR_DOMAIN_NET_TYPE_MCAST:
+    case VIR_DOMAIN_NET_TYPE_INTERNAL:
+    case VIR_DOMAIN_NET_TYPE_HOSTDEV:
+    case VIR_DOMAIN_NET_TYPE_LAST:
+       /* These types don't use a network device on the host, but
+        * instead use some other type of connection to the emulated
+        * device in the qemu process.
+        *
+        * (Note that hostdev can't be considered as "using a network
+        * device", because by the time it is being used, it has been
+        * detached from the hostside network driver so it doesn't show
+        * up in the list of interfaces on the host - it's just some
+        * PCI device.)
+        */
+       break;
+    }
+
     /* Set bandwidth or warn if requested and not supported. */
     actualBandwidth = virDomainNetGetActualBandwidth(net);
     if (actualBandwidth) {
@@ -8221,9 +8260,6 @@ qemuBuildCommandLine(virConnectPtr conn,
 
     virUUIDFormat(def->uuid, uuid);
 
-    *nnicindexes = 0;
-    *nicindexes = NULL;
-
     emulator = def->emulator;
 
     if (!cfg->privileged) {
@@ -9282,13 +9318,9 @@ qemuBuildCommandLine(virConnectPtr conn,
             else
                 vlan = i;
 
-            if (VIR_EXPAND_N(*nicindexes, *nnicindexes, 1) < 0)
-                goto error;
-
             if (qemuBuildInterfaceCommandLine(cmd, driver, def, net,
                                               qemuCaps, vlan, bootNet, vmop,
-                                              standalone,
-                                              &((*nicindexes)[*nnicindexes - 1])) < 0)
+                                              standalone, nnicindexes, nicindexes) < 0)
                 goto error;
 
             last_good_net = i;
index 89e83515ee6d1296dc29d23f3c78a54dfc036dc4..ee81f920778c1fbc060ef476a32b3e89e767a14c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * qemu_command.h: QEMU command generation
  *
- * Copyright (C) 2006-2014 Red Hat, Inc.
+ * Copyright (C) 2006-2015 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -208,8 +208,7 @@ int qemuNetworkIfaceConnect(virDomainDefPtr def,
                             virDomainNetDefPtr net,
                             virQEMUCapsPtr qemuCaps,
                             int *tapfd,
-                            size_t *tapfdSize,
-                            int *nicindex)
+                            size_t *tapfdSize)
     ATTRIBUTE_NONNULL(2);
 
 int qemuPhysIfaceConnect(virDomainDefPtr def,
index 4057abdf7c503714e0c89a22b4d7b4ee2067e87c..e9aa0b5feeb0d8efc1a293af12385976cfea2e80 100644 (file)
@@ -6447,8 +6447,6 @@ static char *qemuConnectDomainXMLToNative(virConnectPtr conn,
     size_t i;
     virQEMUDriverConfigPtr cfg;
     virCapsPtr caps = NULL;
-    size_t nnicindexes = 0;
-    int *nicindexes = NULL;
 
     virCheckFlags(0, NULL);
 
@@ -6634,14 +6632,12 @@ static char *qemuConnectDomainXMLToNative(virConnectPtr conn,
                                      &buildCommandLineCallbacks,
                                      true,
                                      qemuCheckFips(),
-                                     NULL,
-                                     &nnicindexes, &nicindexes)))
+                                     NULL, NULL, NULL)))
         goto cleanup;
 
     ret = virCommandToString(cmd);
 
  cleanup:
-    VIR_FREE(nicindexes);
     virObjectUnref(qemuCaps);
     virCommandFree(cmd);
     virDomainDefFree(def);
index 51f3573f0953bfd666fd9d2765f815f3836261ba..08047ce1f4ee43fdbc67cdf62645a58efa06a8c3 100644 (file)
@@ -846,7 +846,6 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     char **tapfdName = NULL;
     int *tapfd = NULL;
-    int nicindex = -1;
     size_t tapfdSize = 0;
     char **vhostfdName = NULL;
     int *vhostfd = NULL;
@@ -916,8 +915,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
             goto cleanup;
         memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize);
         if (qemuNetworkIfaceConnect(vm->def, driver, net,
-                                    priv->qemuCaps, tapfd, &tapfdSize,
-                                    &nicindex) < 0)
+                                    priv->qemuCaps, tapfd, &tapfdSize) < 0)
             goto cleanup;
         iface_connected = true;
         if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
index 16f325e2bd1c10bd23a15892b1f42766ab921286..7eba5c95fb9f67889cfccc5dc7b51c8c36c8f82e 100644 (file)
@@ -263,8 +263,6 @@ static int testCompareXMLToArgvFiles(const char *xml,
     char *log = NULL;
     virCommandPtr cmd = NULL;
     size_t i;
-    size_t nnicindexes = 0;
-    int *nicindexes = NULL;
     virBitmapPtr nodeset = NULL;
 
     if (!(conn = virGetConnect()))
@@ -355,7 +353,7 @@ static int testCompareXMLToArgvFiles(const char *xml,
                                      VIR_NETDEV_VPORT_PROFILE_OP_NO_OP,
                                      &testCallbacks, false,
                                      (flags & FLAG_FIPS),
-                                     nodeset, &nnicindexes, &nicindexes))) {
+                                     nodeset, NULL, NULL))) {
         if (!virtTestOOMActive() &&
             (flags & FLAG_EXPECT_FAILURE)) {
             ret = 0;
@@ -402,7 +400,6 @@ static int testCompareXMLToArgvFiles(const char *xml,
     ret = 0;
 
  out:
-    VIR_FREE(nicindexes);
     VIR_FREE(log);
     VIR_FREE(expectargv);
     VIR_FREE(actualargv);
index a068135d16b5e0b241bd10f8ea73c6212ec18d46..4220737e84907114a4988685752e3ad34b3732f8 100644 (file)
@@ -44,8 +44,6 @@ static int testCompareXMLToArgvFiles(const char *xml,
     char *log = NULL;
     char *emulator = NULL;
     virCommandPtr cmd = NULL;
-    size_t nnicindexes = 0;
-    int *nicindexes = NULL;
 
     if (!(conn = virGetConnect()))
         goto fail;
@@ -122,7 +120,7 @@ static int testCompareXMLToArgvFiles(const char *xml,
                                      migrateFrom, migrateFd, NULL,
                                      VIR_NETDEV_VPORT_PROFILE_OP_NO_OP,
                                      &testCallbacks, false, false, NULL,
-                                     &nnicindexes, &nicindexes)))
+                                     NULL, NULL)))
         goto fail;
 
     if (!virtTestOOMActive()) {
@@ -158,7 +156,6 @@ static int testCompareXMLToArgvFiles(const char *xml,
     ret = 0;
 
  fail:
-    VIR_FREE(nicindexes);
     VIR_FREE(log);
     VIR_FREE(emulator);
     VIR_FREE(expectargv);