[libvirt] [PATCH 09/13] Remove direct storage of hostnet_name & vlan

Daniel P. Berrange berrange at redhat.com
Mon Feb 1 18:39:38 UTC 2010


The current way of assigning names to the host network backend and
NIC device in QEMU was over complicated, by varying naming scheme
based on the NIC model and backend type. This simplifies the naming
to simply be 'net0' and 'hostnet0', allowing code to easily determine
the host network name and vlan based off the primary device alias
name 'net0'. This in turn allows removal of alot of QEMU specific
code from the XML parser, and makes it easier to assign new unique
names for NICs that are hotplugged

* src/conf/domain_conf.c, src/conf/domain_conf.h: Remove hostnet_name
  and vlan fields from virNetworkDefPtr
* src/qemu/qemu_conf.c, src/qemu/qemu_conf.h, src/qemu/qemu_driver.c:
  Use a single network alias naming scheme regardless of NIC type
  or backend type. Determine VLANs from the alias name.
* tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.args,
  tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args,
  tests/qemuxml2argvdata/qemuxml2argv-net-virtio-netdev.args: Update
  for new simpler naming scheme
---
 src/conf/domain_conf.c                             |   32 --
 src/conf/domain_conf.h                             |    4 -
 src/qemu/qemu_conf.c                               |  310 ++++++--------------
 src/qemu/qemu_conf.h                               |    9 +-
 src/qemu/qemu_driver.c                             |   45 ++--
 .../qemuxml2argv-net-eth-names.args                |    2 +-
 .../qemuxml2argv-net-virtio-device.args            |    2 +-
 .../qemuxml2argv-net-virtio-netdev.args            |    2 +-
 8 files changed, 127 insertions(+), 279 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 691fc84..b434fc5 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -433,7 +433,6 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
     }
 
     VIR_FREE(def->ifname);
-    VIR_FREE(def->hostnet_name);
 
     virDomainDeviceInfoClear(&def->info);
 
@@ -1631,10 +1630,7 @@ virDomainNetDefParseXML(virConnectPtr conn,
     char *port = NULL;
     char *model = NULL;
     char *internal = NULL;
-    char *nic_name = NULL;
-    char *hostnet_name = NULL;
     char *devaddr = NULL;
-    char *vlan = NULL;
 
     if (VIR_ALLOC(def) < 0) {
         virReportOOMError(conn);
@@ -1704,10 +1700,7 @@ virDomainNetDefParseXML(virConnectPtr conn,
             } else if ((flags & VIR_DOMAIN_XML_INTERNAL_STATUS) &&
                        xmlStrEqual(cur->name, BAD_CAST "state")) {
                 /* Legacy back-compat. Don't add any more attributes here */
-                nic_name = virXMLPropString(cur, "nic");
-                hostnet_name = virXMLPropString(cur, "hostnet");
                 devaddr = virXMLPropString(cur, "devaddr");
-                vlan = virXMLPropString(cur, "vlan");
             }
         }
         cur = cur->next;
@@ -1735,8 +1728,6 @@ virDomainNetDefParseXML(virConnectPtr conn,
             goto error;
         }
         def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
-        def->info.alias = nic_name;
-        nic_name = NULL;
     } else {
         if (virDomainDeviceInfoParseXML(conn, node, &def->info, flags) < 0)
             goto error;
@@ -1751,16 +1742,6 @@ virDomainNetDefParseXML(virConnectPtr conn,
         goto error;
     }
 
-    def->hostnet_name = hostnet_name;
-    hostnet_name = NULL;
-
-    def->vlan = -1;
-    if (vlan && virStrToLong_i(vlan, NULL, 10, &def->vlan) < 0) {
-        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
-                             _("Cannot parse <state> 'vlan' attribute"));
-        goto error;
-    }
-
     switch (def->type) {
     case VIR_DOMAIN_NET_TYPE_NETWORK:
         if (network == NULL) {
@@ -1880,10 +1861,7 @@ cleanup:
     VIR_FREE(model);
     VIR_FREE(type);
     VIR_FREE(internal);
-    VIR_FREE(nic_name);
-    VIR_FREE(hostnet_name);
     VIR_FREE(devaddr);
-    VIR_FREE(vlan);
 
     return def;
 
@@ -4826,16 +4804,6 @@ virDomainNetDefFormat(virConnectPtr conn,
         virBufferEscapeString(buf, "      <model type='%s'/>\n",
                               def->model);
 
-    if (flags & VIR_DOMAIN_XML_INTERNAL_STATUS) {
-        /* Legacy back-compat. Don't add any more attributes here */
-        virBufferAddLit(buf, "      <state");
-        if (def->hostnet_name)
-            virBufferEscapeString(buf, " hostnet='%s'", def->hostnet_name);
-        if (def->vlan > 0)
-            virBufferVSprintf(buf, " vlan='%d'", def->vlan);
-        virBufferAddLit(buf, "/>\n");
-    }
-
     if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
         return -1;
 
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index be0dc92..0b79e88 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -247,10 +247,6 @@ struct _virDomainNetDef {
     } data;
     char *ifname;
     virDomainDeviceInfo info;
-    /* XXX figure out how to remove this */
-    char *hostnet_name;
-    /* XXX figure out how to remove this */
-    int vlan;
 };
 
 enum virDomainChrTargetType {
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index c998fe2..b255503 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1515,6 +1515,28 @@ cleanup:
 }
 
 
+static int qemuDomainDeviceAliasIndex(virDomainDeviceInfoPtr info,
+                                      const char *prefix)
+{
+    int idx;
+
+    if (!info->alias)
+        return -1;
+    if (!STRPREFIX(info->alias, prefix))
+        return -1;
+
+    if (virStrToLong_i(info->alias + strlen(prefix), NULL, 10, &idx) < 0)
+        return -1;
+
+    return idx;
+}
+
+
+int qemuDomainNetVLAN(virDomainNetDefPtr def)
+{
+    return qemuDomainDeviceAliasIndex(&def->info, "net");
+}
+
 static int
 qemuAssignDeviceAliases(virDomainDefPtr def)
 {
@@ -1535,14 +1557,7 @@ qemuAssignDeviceAliases(virDomainDefPtr def)
         }
     }
     for (i = 0; i < def->nnets ; i++) {
-        if (def->nets[i]->model) {
-            if (virAsprintf(&def->nets[i]->info.alias, "%s-nic%d", def->nets[i]->model, i) < 0)
-                goto no_memory;
-        } else {
-            if (virAsprintf(&def->nets[i]->info.alias, "nic%d", i) < 0)
-                goto no_memory;
-        }
-        if (virAsprintf(&def->nets[i]->hostnet_name, "netdev%d", i) < 0)
+        if (virAsprintf(&def->nets[i]->info.alias, "net%d", i) < 0)
             goto no_memory;
     }
 
@@ -2025,68 +2040,31 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
 }
 
 
-static const char *
-qemuNetTypeToHostNet(int type)
-{
-    switch (type) {
-    case VIR_DOMAIN_NET_TYPE_NETWORK:
-    case VIR_DOMAIN_NET_TYPE_BRIDGE:
-    case VIR_DOMAIN_NET_TYPE_ETHERNET:
-        return "tap";
-
-    case VIR_DOMAIN_NET_TYPE_CLIENT:
-    case VIR_DOMAIN_NET_TYPE_SERVER:
-    case VIR_DOMAIN_NET_TYPE_MCAST:
-        return "socket";
-
-    case VIR_DOMAIN_NET_TYPE_USER:
-    default:
-        return "user";
-    }
-}
-
 int
 qemuAssignNetNames(virDomainDefPtr def,
                    virDomainNetDefPtr net)
 {
-    char *nic_name, *hostnet_name;
-    int i, nic_index = 0, hostnet_index = 0;
-
-    for (i = 0; i < def->nnets; i++) {
-        if (def->nets[i] == net)
-            continue;
-
-        if (!def->nets[i]->info.alias || !def->nets[i]->hostnet_name)
-            continue;
+    int i;
+    int lastidx = -1;
 
-        if ((def->nets[i]->model == NULL && net->model == NULL) ||
-            (def->nets[i]->model != NULL && net->model != NULL &&
-             STREQ(def->nets[i]->model, net->model)))
-            ++nic_index;
+    for (i = 0; i < def->nnets && def->nets[i] != net ; i++) {
+        int idx;
 
-        if (STREQ(qemuNetTypeToHostNet(def->nets[i]->type),
-                  qemuNetTypeToHostNet(net->type)))
-            ++hostnet_index;
-    }
+        if ((idx = qemuDomainDeviceAliasIndex(&def->nets[i]->info, "net")) < 0) {
+            qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                             _("Unable to determine device index for network device"));
+            return -1;
+        }
 
-    if (virAsprintf(&nic_name, "%s.%d",
-                    net->model ? net->model : "nic",
-                    nic_index) < 0) {
-        virReportOOMError(NULL);
-        return -1;
+        if (idx > lastidx)
+            lastidx = idx;
     }
 
-    if (virAsprintf(&hostnet_name, "%s.%d",
-                    qemuNetTypeToHostNet(net->type),
-                    hostnet_index) < 0) {
+    if (virAsprintf(&net->info.alias, "net%d", lastidx + 1) < 0) {
         virReportOOMError(NULL);
-        VIR_FREE(nic_name);
         return -1;
     }
 
-    net->info.alias = nic_name;
-    net->hostnet_name = hostnet_name;
-
     return 0;
 }
 
@@ -2390,7 +2368,7 @@ qemuBuildNicStr(virConnectPtr conn,
 
 
 char *
-qemuBuildNicDevStr(virDomainNetDefPtr net, int qemuCmdFlags)
+qemuBuildNicDevStr(virDomainNetDefPtr net, int vlan)
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
     const char *nic;
@@ -2404,10 +2382,10 @@ qemuBuildNicDevStr(virDomainNetDefPtr net, int qemuCmdFlags)
     }
 
     virBufferAdd(&buf, nic, strlen(nic));
-    if (qemuCmdFlags & QEMUD_CMD_FLAG_NETDEV)
-        virBufferVSprintf(&buf, ",netdev=%s", net->hostnet_name);
+    if (vlan == -1)
+        virBufferVSprintf(&buf, ",netdev=host%s", net->info.alias);
     else
-        virBufferVSprintf(&buf, ",vlan=%d", net->vlan);
+        virBufferVSprintf(&buf, ",vlan=%d", vlan);
     virBufferVSprintf(&buf, ",id=%s", net->info.alias);
     virBufferVSprintf(&buf, ",mac=%02x:%02x:%02x:%02x:%02x:%02x",
                       net->mac[0], net->mac[1],
@@ -2436,177 +2414,79 @@ qemuBuildHostNetStr(virConnectPtr conn,
                     int vlan,
                     const char *tapfd)
 {
-    char *str = NULL;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
 
     switch (net->type) {
     case VIR_DOMAIN_NET_TYPE_NETWORK:
     case VIR_DOMAIN_NET_TYPE_BRIDGE:
-        if (virAsprintf(&str, "tap%cfd=%s,vlan=%d%s%s",
-                        type_sep, tapfd, vlan,
-                        (net->hostnet_name ? ",name=" : ""),
-                        (net->hostnet_name ? net->hostnet_name : "")) < 0) {
-            virReportOOMError(conn);
-            return NULL;
-        }
+        virBufferAddLit(&buf, "tap");
+        virBufferVSprintf(&buf, "%cfd=%s", type_sep, tapfd);
+        type_sep = ',';
         break;
 
     case VIR_DOMAIN_NET_TYPE_ETHERNET:
-        {
-            virBuffer buf = VIR_BUFFER_INITIALIZER;
-
-            virBufferAddLit(&buf, "tap");
-            if (net->ifname) {
-                virBufferVSprintf(&buf, "%cifname=%s", type_sep, net->ifname);
-                type_sep = ',';
-            }
-            if (net->data.ethernet.script) {
-                virBufferVSprintf(&buf, "%cscript=%s", type_sep,
-                                  net->data.ethernet.script);
-                type_sep = ',';
-            }
-            virBufferVSprintf(&buf, "%cvlan=%d", type_sep, vlan);
-            if (net->hostnet_name) {
-                virBufferVSprintf(&buf, "%cname=%s", type_sep,
-                                  net->hostnet_name);
-                type_sep = ','; /* dead-store, but leave it, in case... */
-            }
-            if (virBufferError(&buf)) {
-                virBufferFreeAndReset(&buf);
-                virReportOOMError(conn);
-                return NULL;
-            }
-
-            str = virBufferContentAndReset(&buf);
+        virBufferAddLit(&buf, "tap");
+        if (net->ifname) {
+            virBufferVSprintf(&buf, "%cifname=%s", type_sep, net->ifname);
+            type_sep = ',';
+        }
+        if (net->data.ethernet.script) {
+            virBufferVSprintf(&buf, "%cscript=%s", type_sep,
+                              net->data.ethernet.script);
+            type_sep = ',';
         }
         break;
 
     case VIR_DOMAIN_NET_TYPE_CLIENT:
     case VIR_DOMAIN_NET_TYPE_SERVER:
     case VIR_DOMAIN_NET_TYPE_MCAST:
-        {
-            const char *mode = NULL;
-
-            switch (net->type) {
-            case VIR_DOMAIN_NET_TYPE_CLIENT:
-                mode = "connect";
-                break;
-            case VIR_DOMAIN_NET_TYPE_SERVER:
-                mode = "listen";
-                break;
-            case VIR_DOMAIN_NET_TYPE_MCAST:
-                mode = "mcast";
-                break;
-            }
-
-            if (virAsprintf(&str, "socket%c%s=%s:%d,vlan=%d%s%s",
-                            type_sep, mode,
-                            net->data.socket.address,
-                            net->data.socket.port,
-                            vlan,
-                            (net->hostnet_name ? ",name=" : ""),
-                            (net->hostnet_name ? net->hostnet_name : "")) < 0) {
-                virReportOOMError(conn);
-                return NULL;
-            }
+        virBufferAddLit(&buf, "socket");
+        switch (net->type) {
+        case VIR_DOMAIN_NET_TYPE_CLIENT:
+            virBufferVSprintf(&buf, "%cconnect=%s:%d",
+                              type_sep,
+                              net->data.socket.address,
+                              net->data.socket.port);
+            break;
+        case VIR_DOMAIN_NET_TYPE_SERVER:
+            virBufferVSprintf(&buf, "%clisten=%s:%d",
+                              type_sep,
+                              net->data.socket.address,
+                              net->data.socket.port);
+            break;
+        case VIR_DOMAIN_NET_TYPE_MCAST:
+            virBufferVSprintf(&buf, "%cmcast=%s:%d",
+                              type_sep,
+                              net->data.socket.address,
+                              net->data.socket.port);
+            break;
         }
+        type_sep = ',';
         break;
 
     case VIR_DOMAIN_NET_TYPE_USER:
     default:
-        if (virAsprintf(&str, "user%cvlan=%d%s%s",
-                        type_sep, vlan,
-                        (net->hostnet_name ? ",name=" : ""),
-                        (net->hostnet_name ? net->hostnet_name : "")) < 0) {
-            virReportOOMError(conn);
-            return NULL;
-        }
+        virBufferAddLit(&buf, "user");
         break;
     }
 
-    return str;
-}
-
-
-char *
-qemuBuildNetDevStr(virConnectPtr conn,
-                   virDomainNetDefPtr net,
-                   const char *tapfd)
-{
-    char *str = NULL;
-
-    switch (net->type) {
-    case VIR_DOMAIN_NET_TYPE_NETWORK:
-    case VIR_DOMAIN_NET_TYPE_BRIDGE:
-        if (virAsprintf(&str, "tap,fd=%s,id=%s",
-                        tapfd, net->hostnet_name) < 0) {
-            virReportOOMError(conn);
-            return NULL;
-        }
-        break;
-
-    case VIR_DOMAIN_NET_TYPE_ETHERNET:
-        {
-            virBuffer buf = VIR_BUFFER_INITIALIZER;
-
-            virBufferAddLit(&buf, "tap");
-            if (net->ifname)
-                virBufferVSprintf(&buf, ",ifname=%s", net->ifname);
-            if (net->data.ethernet.script)
-                virBufferVSprintf(&buf, ",script=%s",
-                                  net->data.ethernet.script);
-            if (net->hostnet_name)
-                virBufferVSprintf(&buf, ",id=%s",
-                                  net->hostnet_name);
-            if (virBufferError(&buf)) {
-                virBufferFreeAndReset(&buf);
-                virReportOOMError(conn);
-                return NULL;
-            }
-
-            str = virBufferContentAndReset(&buf);
-        }
-        break;
-
-    case VIR_DOMAIN_NET_TYPE_CLIENT:
-    case VIR_DOMAIN_NET_TYPE_SERVER:
-    case VIR_DOMAIN_NET_TYPE_MCAST:
-        {
-            const char *mode = NULL;
-
-            switch (net->type) {
-            case VIR_DOMAIN_NET_TYPE_CLIENT:
-                mode = "connect";
-                break;
-            case VIR_DOMAIN_NET_TYPE_SERVER:
-                mode = "listen";
-                break;
-            case VIR_DOMAIN_NET_TYPE_MCAST:
-                mode = "mcast";
-                break;
-            }
-
-            if (virAsprintf(&str, "socket,%s=%s:%d,id=%s",
-                            mode,
-                            net->data.socket.address,
-                            net->data.socket.port,
-                            net->hostnet_name) < 0) {
-                virReportOOMError(conn);
-                return NULL;
-            }
-        }
-        break;
+    if (vlan >= 0) {
+        virBufferVSprintf(&buf, "%cvlan=%d", type_sep, vlan);
+        if (net->info.alias)
+            virBufferVSprintf(&buf, ",name=host%s",
+                              net->info.alias);
+    } else {
+        virBufferVSprintf(&buf, "%cid=host%s",
+                          type_sep, net->info.alias);
+    }
 
-    case VIR_DOMAIN_NET_TYPE_USER:
-    default:
-        if (virAsprintf(&str, "user,id=%s",
-                        net->hostnet_name) < 0) {
-            virReportOOMError(conn);
-            return NULL;
-        }
-        break;
+    if (virBufferError(&buf)) {
+        virBufferFreeAndReset(&buf);
+        virReportOOMError(conn);
+        return NULL;
     }
 
-    return str;
+    return virBufferContentAndReset(&buf);
 }
 
 
@@ -3634,13 +3514,14 @@ int qemudBuildCommandLine(virConnectPtr conn,
             virDomainNetDefPtr net = def->nets[i];
             char *nic, *host;
             char tapfd_name[50];
+            int vlan;
 
             /* VLANs are not used with -netdev, so don't record them */
             if ((qemuCmdFlags & QEMUD_CMD_FLAG_NETDEV) &&
                 (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE))
-                net->vlan = -1;
+                vlan = -1;
             else
-                net->vlan = i;
+                vlan = i;
 
             if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK ||
                 net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
@@ -3676,18 +3557,19 @@ int qemudBuildCommandLine(virConnectPtr conn,
             if ((qemuCmdFlags & QEMUD_CMD_FLAG_NETDEV) &&
                 (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) {
                 ADD_ARG_LIT("-netdev");
-                if (!(host = qemuBuildNetDevStr(conn, net, tapfd_name)))
+                if (!(host = qemuBuildHostNetStr(conn, net, ',',
+                                                 vlan, tapfd_name)))
                     goto error;
                 ADD_ARG(host);
             }
             if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
                 ADD_ARG_LIT("-device");
-                if (!(nic = qemuBuildNicDevStr(net, qemuCmdFlags)))
+                if (!(nic = qemuBuildNicDevStr(net, vlan)))
                     goto error;
                 ADD_ARG(nic);
             } else {
                 ADD_ARG_LIT("-net");
-                if (!(nic = qemuBuildNicStr(conn, net, "nic,", net->vlan)))
+                if (!(nic = qemuBuildNicStr(conn, net, "nic,", vlan)))
                     goto error;
                 ADD_ARG(nic);
             }
@@ -3695,7 +3577,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
                   (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE))) {
                 ADD_ARG_LIT("-net");
                 if (!(host = qemuBuildHostNetStr(conn, net, ',',
-                                                 net->vlan, tapfd_name)))
+                                                 vlan, tapfd_name)))
                     goto error;
                 ADD_ARG(host);
             }
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 3787e28..7b439fd 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -191,19 +191,13 @@ int         qemudBuildCommandLine       (virConnectPtr conn,
                                          int *ntapfds,
                                          const char *migrateFrom);
 
-/* Legacy, pre device support */
+/* With vlan == -1, use netdev syntax, else old hostnet */
 char * qemuBuildHostNetStr(virConnectPtr conn,
                            virDomainNetDefPtr net,
                            char type_sep,
                            int vlan,
                            const char *tapfd);
 
-/* Current, best practice */
-char * qemuBuildNetDevStr(virConnectPtr conn,
-                          virDomainNetDefPtr net,
-                          const char *tapfd);
-
-
 /* Legacy, pre device support */
 char * qemuBuildNicStr(virConnectPtr conn,
                        virDomainNetDefPtr net,
@@ -291,6 +285,7 @@ int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs,
 void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs);
 int  qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs);
 
+int qemuDomainNetVLAN(virDomainNetDefPtr def);
 
 
 #endif /* __QEMUD_CONF_H */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index df7f8e7..f00bb75 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5595,11 +5595,12 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     char *tapfd_name = NULL;
-    int i, tapfd = -1;
+    int tapfd = -1;
     char *nicstr = NULL;
     char *netstr = NULL;
     int ret = -1;
     virDomainDevicePCIAddress guestAddr;
+    int vlan;
 
     if (!(qemuCmdFlags & QEMUD_CMD_FLAG_HOST_NET_ADD)) {
         qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, "%s",
@@ -5626,22 +5627,16 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
 
     if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) &&
         qemuAssignNetNames(vm->def, net) < 0)
-        goto no_memory;
+        goto cleanup;
 
     if ((qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
         qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &net->info) < 0)
         goto cleanup;
 
-    /* Choose a vlan value greater than all other values since
-     * older versions did not store the value in the state file.
-     */
-    net->vlan = vm->def->nnets;
-    for (i = 0; i < vm->def->nnets; i++)
-        if (vm->def->nets[i]->vlan >= net->vlan)
-            net->vlan = vm->def->nets[i]->vlan;
+    vlan = qemuDomainNetVLAN(net);
 
     if (tapfd != -1) {
-        if (virAsprintf(&tapfd_name, "fd-%s", net->hostnet_name) < 0)
+        if (virAsprintf(&tapfd_name, "fd-%s", net->info.alias) < 0)
             goto no_memory;
 
         qemuDomainObjEnterMonitorWithDriver(driver, vm);
@@ -5653,7 +5648,7 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
     }
 
     if (!(netstr = qemuBuildHostNetStr(conn, net, ' ',
-                                       net->vlan, tapfd_name)))
+                                       vlan, tapfd_name)))
         goto try_tapfd_close;
 
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
@@ -5667,7 +5662,7 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
         close(tapfd);
     tapfd = -1;
 
-    if (!(nicstr = qemuBuildNicStr(conn, net, NULL, net->vlan)))
+    if (!(nicstr = qemuBuildNicStr(conn, net, NULL, vlan)))
         goto try_remove;
 
     qemuDomainObjEnterMonitorWithDriver(driver, vm);
@@ -5700,14 +5695,18 @@ cleanup:
     return ret;
 
 try_remove:
-    if (!net->hostnet_name || net->vlan == 0)
+    if (vlan < 0) {
         VIR_WARN0(_("Unable to remove network backend"));
-    else {
+    } else {
+        char *hostnet_name;
+        if (virAsprintf(&hostnet_name, "host%s", net->info.alias) < 0)
+            goto no_memory;
         qemuDomainObjEnterMonitorWithDriver(driver, vm);
-        if (qemuMonitorRemoveHostNetwork(priv->mon, net->vlan, net->hostnet_name) < 0)
+        if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0)
             VIR_WARN(_("Failed to remove network backend for vlan %d, net %s"),
-                     net->vlan, net->hostnet_name);
+                     vlan, hostnet_name);
         qemuDomainObjExitMonitorWithDriver(driver, vm);
+        VIR_FREE(hostnet_name);
     }
     goto cleanup;
 
@@ -6174,6 +6173,8 @@ qemudDomainDetachNetDevice(virConnectPtr conn,
     int i, ret = -1;
     virDomainNetDefPtr detach = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    int vlan;
+    char *hostnet_name = NULL;
 
     for (i = 0 ; i < vm->def->nnets ; i++) {
         virDomainNetDefPtr net = vm->def->nets[i];
@@ -6200,9 +6201,14 @@ qemudDomainDetachNetDevice(virConnectPtr conn,
         goto cleanup;
     }
 
-    if (detach->vlan < 0 || !detach->hostnet_name) {
+    if ((vlan = qemuDomainNetVLAN(detach)) < 0) {
         qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED,
-                         "%s", _("network device cannot be detached - device state missing"));
+                         "%s", _("unable to determine original VLAN"));
+        goto cleanup;
+    }
+
+    if (virAsprintf(&hostnet_name, "host%s", detach->info.alias) < 0) {
+        virReportOOMError(NULL);
         goto cleanup;
     }
 
@@ -6213,7 +6219,7 @@ qemudDomainDetachNetDevice(virConnectPtr conn,
         goto cleanup;
     }
 
-    if (qemuMonitorRemoveHostNetwork(priv->mon, detach->vlan, detach->hostnet_name) < 0) {
+    if (qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0) {
         qemuDomainObjExitMonitorWithDriver(driver, vm);
         goto cleanup;
     }
@@ -6248,6 +6254,7 @@ qemudDomainDetachNetDevice(virConnectPtr conn,
     ret = 0;
 
 cleanup:
+    VIR_FREE(hostnet_name);
     return ret;
 }
 
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.args b/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.args
index 70a10cd..ad33a55 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.args
@@ -1 +1 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net nic,macaddr=00:11:22:33:44:55,vlan=0,name=nic.0 -net tap,script=/etc/qemu-ifup,vlan=0,name=tap.0 -net nic,macaddr=00:11:22:33:44:56,vlan=1,model=e1000,name=e1000.0 -net tap,script=/etc/qemu-ifup,vlan=1,name=tap.1 -serial none -parallel none -usb
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net nic,macaddr=00:11:22:33:44:55,vlan=0,name=net0 -net tap,script=/etc/qemu-ifup,vlan=0,name=hostnet0 -net nic,macaddr=00:11:22:33:44:56,vlan=1,model=e1000,name=net1 -net tap,script=/etc/qemu-ifup,vlan=1,name=hostnet1 -serial none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args
index 32d2843..48423a2 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args
@@ -1 +1 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -device virtio-net-pci,vlan=0,id=virtio-nic0,mac=00:11:22:33:44:55,bus=pci.0,addr=0x4 -net user,vlan=0,name=netdev0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -device virtio-net-pci,vlan=0,id=net0,mac=00:11:22:33:44:55,bus=pci.0,addr=0x4 -net user,vlan=0,name=hostnet0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-netdev.args b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-netdev.args
index 698ad3a..951bab2 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-netdev.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-netdev.args
@@ -1 +1 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -netdev user,id=netdev0 -device virtio-net-pci,netdev=netdev0,id=virtio-nic0,mac=00:11:22:33:44:55,bus=pci.0,addr=0x4 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -netdev user,id=hostnet0 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=00:11:22:33:44:55,bus=pci.0,addr=0x4 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
-- 
1.6.5.2




More information about the libvir-list mailing list