[libvirt] [PATCH 06/14] Assign names to qemu NICs and network backends

Mark McLoughlin markmc at redhat.com
Mon Jul 20 11:51:16 UTC 2009


We need these so that we can remove the devices via the monitor.

* src/domain_conf.h: add nic_name and hostnet_name to virDomainNetDef

* src/domain_conf.c: free nic_name and hostnet_name

* src/qemu_conf.c: add qemuAssignNetNames(), use it if qemu has
  support for the param and pass the names on the command line

* tests/qemuxml2argv*: add a test for this
---
 src/domain_conf.c                                  |    2 +
 src/domain_conf.h                                  |    2 +
 src/qemu_conf.c                                    |   95 ++++++++++++++++++--
 .../qemuxml2argv-net-eth-names.args                |    1 +
 .../qemuxml2argv-net-eth-names.xml                 |   31 +++++++
 tests/qemuxml2argvtest.c                           |    1 +
 6 files changed, 124 insertions(+), 8 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.xml

diff --git a/src/domain_conf.c b/src/domain_conf.c
index 16f7d73..a5e4697 100644
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -339,6 +339,8 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
     }
 
     VIR_FREE(def->ifname);
+    VIR_FREE(def->nic_name);
+    VIR_FREE(def->hostnet_name);
     VIR_FREE(def);
 }
 
diff --git a/src/domain_conf.h b/src/domain_conf.h
index 1766b61..1e30107 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -175,6 +175,8 @@ struct _virDomainNetDef {
         } internal;
     } data;
     char *ifname;
+    char *nic_name;
+    char *hostnet_name;
 };
 
 enum virDomainChrSrcType {
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index a9e5e4e..0362d76 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -810,6 +810,68 @@ qemudNetworkIfaceConnect(virConnectPtr conn,
     return tapfd;
 }
 
+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";
+    }
+}
+
+static 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]->nic_name || !def->nets[i]->hostnet_name)
+            continue;
+
+        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;
+
+        if (STREQ(qemuNetTypeToHostNet(def->nets[i]->type),
+                  qemuNetTypeToHostNet(net->type)))
+            ++hostnet_index;
+    }
+
+    if (virAsprintf(&nic_name, "%s.%d",
+                    net->model ? net->model : "nic",
+                    nic_index) < 0)
+        return -1;
+
+    if (virAsprintf(&hostnet_name, "%s.%d",
+                    qemuNetTypeToHostNet(net->type),
+                    hostnet_index) < 0) {
+        VIR_FREE(nic_name);
+        return -1;
+    }
+
+    net->nic_name = nic_name;
+    net->hostnet_name = hostnet_name;
+
+    return 0;
+}
+
 static int
 qemuBuildNicStr(virConnectPtr conn,
                 virDomainNetDefPtr net,
@@ -819,7 +881,7 @@ qemuBuildNicStr(virConnectPtr conn,
                 char **str)
 {
     if (virAsprintf(str,
-                    "%snic%cmacaddr=%02x:%02x:%02x:%02x:%02x:%02x,vlan=%d%s%s",
+                    "%snic%cmacaddr=%02x:%02x:%02x:%02x:%02x:%02x,vlan=%d%s%s%s%s",
                     prefix ? prefix : "",
                     type_sep,
                     net->mac[0], net->mac[1],
@@ -827,7 +889,9 @@ qemuBuildNicStr(virConnectPtr conn,
                     net->mac[4], net->mac[5],
                     vlan,
                     (net->model ? ",model=" : ""),
-                    (net->model ? net->model : "")) < 0) {
+                    (net->model ? net->model : ""),
+                    (net->nic_name ? ",name=" : ""),
+                    (net->nic_name ? net->nic_name : "")) < 0) {
         virReportOOMError(conn);
         return -1;
     }
@@ -847,9 +911,11 @@ qemuBuildHostNetStr(virConnectPtr conn,
     switch (net->type) {
     case VIR_DOMAIN_NET_TYPE_NETWORK:
     case VIR_DOMAIN_NET_TYPE_BRIDGE:
-        if (virAsprintf(str, "%stap%cfd=%d,vlan=%d",
+        if (virAsprintf(str, "%stap%cfd=%d,vlan=%d%s%s",
                         prefix ? prefix : "",
-                        type_sep, tapfd, vlan) < 0) {
+                        type_sep, tapfd, vlan,
+                        (net->hostnet_name ? ",name=" : ""),
+                        (net->hostnet_name ? net->hostnet_name : "")) < 0) {
             virReportOOMError(conn);
             return -1;
         }
@@ -872,6 +938,11 @@ qemuBuildHostNetStr(virConnectPtr conn,
                 type_sep = ',';
             }
             virBufferVSprintf(&buf, "%cvlan=%d", type_sep, vlan);
+            if (net->hostnet_name) {
+                virBufferVSprintf(&buf, "%cname=%s", type_sep,
+                                  net->hostnet_name);
+                type_sep = ',';
+            }
             if (virBufferError(&buf)) {
                 virReportOOMError(conn);
                 return -1;
@@ -899,12 +970,14 @@ qemuBuildHostNetStr(virConnectPtr conn,
                 break;
             }
 
-            if (virAsprintf(str, "%ssocket%c%s=%s:%d,vlan=%d",
+            if (virAsprintf(str, "%ssocket%c%s=%s:%d,vlan=%d%s%s",
                             prefix ? prefix : "",
                             type_sep, mode,
                             net->data.socket.address,
                             net->data.socket.port,
-                            vlan) < 0) {
+                            vlan,
+                            (net->hostnet_name ? ",name=" : ""),
+                            (net->hostnet_name ? net->hostnet_name : "")) < 0) {
                 virReportOOMError(conn);
                 return -1;
             }
@@ -913,9 +986,11 @@ qemuBuildHostNetStr(virConnectPtr conn,
 
     case VIR_DOMAIN_NET_TYPE_USER:
     default:
-        if (virAsprintf(str, "%suser%cvlan=%d",
+        if (virAsprintf(str, "%suser%cvlan=%d%s%s",
                         prefix ? prefix : "",
-                        type_sep, vlan) < 0) {
+                        type_sep, vlan,
+                        (net->hostnet_name ? ",name=" : ""),
+                        (net->hostnet_name ? net->hostnet_name : "")) < 0) {
             virReportOOMError(conn);
             return -1;
         }
@@ -1460,6 +1535,10 @@ int qemudBuildCommandLine(virConnectPtr conn,
             char *nic, *host;
             int tapfd = -1;
 
+            if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) &&
+                qemuAssignNetNames(def, net) < 0)
+                goto no_memory;
+
             if (qemuBuildNicStr(conn, net, NULL, ',', i, &nic) < 0)
                 goto error;
 
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.args b/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.args
new file mode 100644
index 0000000..70a10cd
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.args
@@ -0,0 +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
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.xml
new file mode 100644
index 0000000..8aae269
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-eth-names.xml
@@ -0,0 +1,31 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219200</memory>
+  <currentMemory>219200</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+    </disk>
+    <interface type='ethernet'>
+      <mac address='00:11:22:33:44:55'/>
+      <script path='/etc/qemu-ifup'/>
+    </interface>
+    <interface type='ethernet'>
+      <mac address='00:11:22:33:44:56'/>
+      <script path='/etc/qemu-ifup'/>
+      <model type='e1000'/>
+    </interface>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index b6e258a..73a6709 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -245,6 +245,7 @@ mymain(int argc, char **argv)
     DO_TEST("net-virtio", 0);
     DO_TEST("net-eth", 0);
     DO_TEST("net-eth-ifname", 0);
+    DO_TEST("net-eth-names", QEMUD_CMD_FLAG_NET_NAME);
 
     DO_TEST("serial-vc", 0);
     DO_TEST("serial-pty", 0);
-- 
1.6.2.5




More information about the libvir-list mailing list