[libvirt] [PATCH 3/5] macvtap support for libvirt -- qemu support
Daniel P. Berrange
berrange at redhat.com
Wed Feb 10 18:23:30 UTC 2010
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 at us.ibm.com>
>
>
>
> 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 :|
More information about the libvir-list
mailing list