[libvirt] [PATCH 25/34] Convert NICs over to use -device & -netdev where possible

Daniel P. Berrange berrange at redhat.com
Fri Jan 8 17:23:21 UTC 2010


The current syntax uses a pair of args

   -net nic,macaddr=52:54:00:56:6c:55,vlan=3,model=pcnet,name=pcnet.0
   -net user,vlan=3,name=user.0

The new syntax does not  need the vlan craziness anymore, and
so has a simplified pair of args

   -netdev user,id=user.0
   -device pcnet,netdev=user.0,id=pcnet.0,mac=52:54:00:56:6c:55,addr=<PCI SLOT>
---
 src/qemu/qemu_conf.c                               |  175 ++++++++++++++++----
 .../qemuxml2argv-net-virtio-device.args            |    1 +
 .../qemuxml2argv-net-virtio-device.xml             |   26 +++
 tests/qemuxml2argvtest.c                           |    1 +
 4 files changed, 174 insertions(+), 29 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.xml

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 8b8455d..709c3f4 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1488,6 +1488,8 @@ qemuAssignDeviceAliases(virDomainDefPtr def)
             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)
+            goto no_memory;
     }
 
     for (i = 0; i < def->nsounds ; i++) {
@@ -2021,6 +2023,41 @@ qemuBuildNicStr(virConnectPtr conn,
     return 0;
 }
 
+static char *
+qemuBuildNicDevStr(virDomainNetDefPtr net)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    const char *nic;
+
+    if (!net->model) {
+        nic = "rtl8139";
+    } else if (STREQ(net->model, "virtio")) {
+        nic = "virtio-net-pci";
+    } else {
+        nic = net->model;
+    }
+
+    virBufferVSprintf(&buf, "%s,netdev=%s", nic, net->hostnet_name);
+    virBufferVSprintf(&buf, ",id=%s", net->info.alias);
+    virBufferVSprintf(&buf, ",mac=%02x:%02x:%02x:%02x:%02x:%02x",
+                      net->mac[0], net->mac[1],
+                      net->mac[2], net->mac[3],
+                      net->mac[4], net->mac[5]);
+    if (qemuBuildDeviceAddressStr(&buf, &net->info) < 0)
+        goto error;
+
+    if (virBufferError(&buf)) {
+        virReportOOMError(NULL);
+        goto error;
+    }
+
+    return virBufferContentAndReset(&buf);
+
+error:
+    virBufferFreeAndReset(&buf);
+    return NULL;
+}
+
 int
 qemuBuildHostNetStr(virConnectPtr conn,
                     virDomainNetDefPtr net,
@@ -2118,6 +2155,88 @@ qemuBuildHostNetStr(virConnectPtr conn,
 }
 
 
+static int
+qemuBuildNetDevStr(virConnectPtr conn,
+                   virDomainNetDefPtr net,
+                   const char *tapfd,
+                   char **str)
+{
+    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 -1;
+        }
+        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 -1;
+            }
+
+            *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 -1;
+            }
+        }
+        break;
+
+    case VIR_DOMAIN_NET_TYPE_USER:
+    default:
+        if (virAsprintf(str, "user,id=%s",
+                        net->hostnet_name) < 0) {
+            virReportOOMError(conn);
+            return -1;
+        }
+        break;
+    }
+
+    return 0;
+}
+
+
 static char *qemuBuildWatchdogDevStr(virDomainWatchdogDefPtr dev)
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
@@ -2961,27 +3080,10 @@ int qemudBuildCommandLine(virConnectPtr conn,
         for (i = 0 ; i < def->nnets ; i++) {
             virDomainNetDefPtr net = def->nets[i];
             char *nic, *host;
-            char *tapfd_name = NULL;
+            char tapfd_name[50];
 
             net->vlan = i;
 
-            ADD_ARG_SPACE;
-            if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) &&
-                !(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) &&
-                qemuAssignNetNames(def, net) < 0)
-                goto no_memory;
-
-            if (qemuBuildNicStr(conn, net, "nic,", net->vlan, &nic) < 0)
-                goto error;
-
-            if ((qargv[qargc++] = strdup("-net")) == NULL) {
-                VIR_FREE(nic);
-                goto no_memory;
-            }
-            ADD_ARG(nic);
-
-
-            ADD_ARG_SPACE;
             if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK ||
                 net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
                 int tapfd = qemudNetworkIfaceConnect(conn, driver, net, qemuCmdFlags);
@@ -2995,23 +3097,38 @@ int qemudBuildCommandLine(virConnectPtr conn,
 
                 (*tapfds)[(*ntapfds)++] = tapfd;
 
-                if (virAsprintf(&tapfd_name, "%d", tapfd) < 0)
+                if (snprintf(tapfd_name, sizeof(tapfd_name), "%d", tapfd) >= sizeof(tapfd_name))
                     goto no_memory;
             }
 
-            if (qemuBuildHostNetStr(conn, net, ',',
-                                    net->vlan, tapfd_name, &host) < 0) {
-                VIR_FREE(tapfd_name);
-                goto error;
+            if ((qemuCmdFlags & QEMUD_CMD_FLAG_NET_NAME) &&
+                !(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) {
+                if (qemuAssignNetNames(def, net) < 0)
+                    goto no_memory;
             }
 
-            if ((qargv[qargc++] = strdup("-net")) == NULL) {
-                VIR_FREE(host);
-                goto no_memory;
-            }
-            ADD_ARG(host);
+            if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
+                ADD_ARG_LIT("-netdev");
+                if (qemuBuildNetDevStr(conn, net, tapfd_name, &host) < 0)
+                    goto error;
+                ADD_ARG(host);
 
-            VIR_FREE(tapfd_name);
+                ADD_ARG_LIT("-device");
+                if (!(nic = qemuBuildNicDevStr(net)))
+                    goto error;
+                ADD_ARG(nic);
+            } else {
+                ADD_ARG_LIT("-net");
+                if (qemuBuildNicStr(conn, net, "nic,", net->vlan, &nic) < 0)
+                    goto error;
+                ADD_ARG(nic);
+
+                ADD_ARG_LIT("-net");
+                if (qemuBuildHostNetStr(conn, net, ',',
+                                        net->vlan, tapfd_name, &host) < 0)
+                    goto error;
+                ADD_ARG(host);
+            }
         }
     }
 
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.args
new file mode 100644
index 0000000..2b5e856
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.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 -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 -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.xml
new file mode 100644
index 0000000..5d34bd4
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-virtio-device.xml
@@ -0,0 +1,26 @@
+<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='user'>
+      <mac address='00:11:22:33:44:55'/>
+      <model type='virtio'/>
+    </interface>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 55e7d58..645f6b4 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -260,6 +260,7 @@ mymain(int argc, char **argv)
             QEMUD_CMD_FLAG_UUID);
     DO_TEST("net-user", 0);
     DO_TEST("net-virtio", 0);
+    DO_TEST("net-virtio-device", QEMUD_CMD_FLAG_DEVICE);
     DO_TEST("net-eth", 0);
     DO_TEST("net-eth-ifname", 0);
     DO_TEST("net-eth-names", QEMUD_CMD_FLAG_NET_NAME);
-- 
1.6.5.2




More information about the libvir-list mailing list