On Mon, Feb 08, 2010 at 02:37:18PM -0500, Stefan Berger wrote: > This part adds support for qemu making a macvtap tap device available > via file descriptor passed to qemu command line. This also attempts to > tear down the macvtap device when a VM terminates. This includes support > for attachment and detachment to/from running VM. > > Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx> > > > > Index: libvirt-macvtap/src/qemu/qemu_conf.c > =================================================================== > --- libvirt-macvtap.orig/src/qemu/qemu_conf.c > +++ libvirt-macvtap/src/qemu/qemu_conf.c > @@ -52,6 +52,7 @@ > #include "nodeinfo.h" > #include "logging.h" > #include "network.h" > +#include "macvtap.h" > #include "cpu/cpu.h" > > #define VIR_FROM_THIS VIR_FROM_QEMU > @@ -1423,6 +1424,43 @@ int qemudExtractVersion(virConnectPtr co > > > int > +qemudPhysIfaceConnect(virConnectPtr conn, > + virDomainNetDefPtr net, > + char *linkdev, > + int brmode) > +{ > + int rc; > +#if defined(WITH_MACVTAP) > + char *res_ifname = NULL; > + int hasBusyDev = 0; > + > + delMacvtapByMACAddress(conn, net->mac, &hasBusyDev); > + > + if (hasBusyDev) { > + virReportSystemError(NULL, errno, "%s", > + _("A macvtap with the same MAC address is in use")); > + return -1; > + } > + > + rc = openMacvtapTap(conn, net->ifname, net->mac, linkdev, brmode, > + &res_ifname); > + if (rc > 0) { > + VIR_FREE(net->ifname); > + net->ifname = res_ifname; > + } > +#else > + (void)net; > + (void)linkdev; > + (void)brmode; > + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, > + "%s", _("No support for macvtap device")); > + rc = -1; > +#endif > + return rc; > +} > + > + > +int > qemudNetworkIfaceConnect(virConnectPtr conn, > struct qemud_driver *driver, > virDomainNetDefPtr net, > @@ -2520,6 +2558,7 @@ qemuBuildHostNetStr(virConnectPtr conn, > switch (net->type) { > case VIR_DOMAIN_NET_TYPE_NETWORK: > case VIR_DOMAIN_NET_TYPE_BRIDGE: > + case VIR_DOMAIN_NET_TYPE_DIRECT: > virBufferAddLit(&buf, "tap"); > virBufferVSprintf(&buf, "%cfd=%s", type_sep, tapfd); > type_sep = ','; > @@ -3636,6 +3675,22 @@ int qemudBuildCommandLine(virConnectPtr > > if (snprintf(tapfd_name, sizeof(tapfd_name), "%d", tapfd) >= sizeof(tapfd_name)) > goto no_memory; > + } else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) { > + int tapfd = qemudPhysIfaceConnect(conn, net, > + net->data.direct.linkdev, > + net->data.direct.mode); > + if (tapfd < 0) > + goto error; > + > + if (VIR_REALLOC_N(*tapfds, (*ntapfds)+1) < 0) { > + close(tapfd); > + goto no_memory; > + } > + > + (*tapfds)[(*ntapfds)++] = tapfd; > + > + if (snprintf(tapfd_name, sizeof(tapfd_name), "%d", tapfd) >= sizeof(tapfd_name)) > + goto no_memory; > } > > /* Possible combinations: > Index: libvirt-macvtap/src/qemu/qemu_driver.c > =================================================================== > --- libvirt-macvtap.orig/src/qemu/qemu_driver.c > +++ libvirt-macvtap/src/qemu/qemu_driver.c > @@ -75,6 +75,7 @@ > #include "libvirt_internal.h" > #include "xml.h" > #include "cpu/cpu.h" > +#include "macvtap.h" > > > #define VIR_FROM_THIS VIR_FROM_QEMU > @@ -2825,6 +2826,8 @@ static void qemudShutdownVMDaemon(virCon > int retries = 0; > qemuDomainObjPrivatePtr priv = vm->privateData; > virErrorPtr orig_err; > + virDomainDefPtr def; > + int i; > > if (!virDomainObjIsActive(vm)) > return; > @@ -2836,8 +2839,7 @@ static void qemudShutdownVMDaemon(virCon > orig_err = virSaveLastError(); > > if (driver->macFilter) { > - int i; > - virDomainDefPtr def = vm->def; > + def = vm->def; > for (i = 0 ; i < def->nnets ; i++) { > virDomainNetDefPtr net = def->nets[i]; > if (net->ifname == NULL) > @@ -2851,6 +2853,17 @@ static void qemudShutdownVMDaemon(virCon > } > } > > +#if defined(WITH_MACVTAP) > + def = vm->def; > + for (i = 0; i < def->nnets; i++) { > + virDomainNetDefPtr net = def->nets[i]; > + if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) { > + int dummy; > + delMacvtapByMACAddress(conn, net->mac, &dummy); > + } > + } > +#endif > + > if (virKillProcess(vm->pid, 0) == 0 && > virKillProcess(vm->pid, SIGTERM) < 0) > virReportSystemError(conn, errno, > @@ -5629,6 +5642,19 @@ static int qemudDomainAttachNetDevice(vi > > if ((tapfd = qemudNetworkIfaceConnect(conn, driver, net, qemuCmdFlags)) < 0) > return -1; > + } else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) { > + if (priv->monConfig->type != VIR_DOMAIN_CHR_TYPE_UNIX) { > + qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, > + _("direct device type '%s' cannot be attached: " > + "qemu is not using a unix socket monitor"), > + virDomainNetTypeToString(net->type)); > + return -1; > + } > + > + if ((tapfd = qemudPhysIfaceConnect(conn, net, > + net->data.direct.linkdev, > + net->data.direct.mode)) < 0) > + return -1; > } > > if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets+1) < 0) > @@ -6242,6 +6268,11 @@ qemudDomainDetachNetDevice(virConnectPtr > } > qemuDomainObjExitMonitorWithDriver(driver, vm); > > + if (detach->type == VIR_DOMAIN_NET_TYPE_DIRECT) { > + int dummy; > + delMacvtapByMACAddress(conn, detach->mac, &dummy); > + } > + > if ((driver->macFilter) && (detach->ifname != NULL)) { > if ((errno = networkDisallowMacOnPort(conn, > driver, > Index: libvirt-macvtap/src/qemu/qemu_conf.h > =================================================================== > --- libvirt-macvtap.orig/src/qemu/qemu_conf.h > +++ libvirt-macvtap/src/qemu/qemu_conf.h > @@ -247,6 +247,11 @@ int qemudNetworkIfaceConnect > virDomainNetDefPtr net, > int qemuCmdFlags); > > +int qemudPhysIfaceConnect(virConnectPtr conn, > + virDomainNetDefPtr net, > + char *linkdev, > + int brmode); > + > int qemudProbeMachineTypes (const char *binary, > virCapsGuestMachinePtr **machines, > int *nmachines); ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list