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