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 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list