Implement support for <hostdev caps=net>

This allows a container-type domain to have exclusive access to one of
the host's NICs.

Wire <hostdev caps=net> with the lxc_controller - when moving the newly
created veth devices into a new namespace, also look for any hostdev
devices that should be moved. Note: once the container domain has been
destroyed, there is no code that moves the interfaces back to the
original namespace. This does happen, though, probably due to default
cleanup on namespace destruction.

Signed-off-by: Bogdan Purcareata <bogdan.purcareata@freescale.com>
This commit is contained in:
Bogdan Purcareata 2013-04-05 08:26:40 -04:00 committed by Daniel P. Berrange
parent 4aafa1ff86
commit 442d6a0527
4 changed files with 42 additions and 3 deletions

View File

@ -1551,7 +1551,6 @@ cleanup:
return ret;
}
static int lxcContainerSetupHostdevSubsys(virDomainDefPtr vmDef,
virDomainHostdevDefPtr def,
const char *dstprefix,
@ -1582,6 +1581,9 @@ static int lxcContainerSetupHostdevCaps(virDomainDefPtr vmDef,
case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_MISC:
return lxcContainerSetupHostdevCapsMisc(vmDef, def, dstprefix, securityDriver);
case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET:
return 0; // case is handled in virLXCControllerMoveInterfaces
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Unsupported host device mode %s"),
@ -2286,6 +2288,22 @@ virArch lxcContainerGetAlt32bitArch(virArch arch)
}
static bool
lxcNeedNetworkNamespace(virDomainDefPtr def)
{
size_t i;
if (def->nets != NULL)
return true;
if (def->features & (1 << VIR_DOMAIN_FEATURE_PRIVNET))
return true;
for (i = 0 ; i < def->nhostdevs ; i++) {
if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES &&
def->hostdevs[i]->source.caps.type == VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET)
return true;
}
return false;
}
/**
* lxcContainerStart:
* @def: pointer to virtual machine structure
@ -2329,8 +2347,7 @@ int lxcContainerStart(virDomainDefPtr def,
cflags |= CLONE_NEWUSER;
}
if (def->nets != NULL ||
(def->features & (1 << VIR_DOMAIN_FEATURE_PRIVNET))) {
if (lxcNeedNetworkNamespace(def)) {
VIR_DEBUG("Enable network namespaces");
cflags |= CLONE_NEWNET;
}

View File

@ -1050,12 +1050,28 @@ cleanup2:
static int virLXCControllerMoveInterfaces(virLXCControllerPtr ctrl)
{
size_t i;
virDomainDefPtr def = ctrl->def;
for (i = 0 ; i < ctrl->nveths ; i++) {
if (virNetDevSetNamespace(ctrl->veths[i], ctrl->initpid) < 0)
return -1;
}
for (i = 0; i < def->nhostdevs; i ++) {
virDomainHostdevDefPtr hdev = def->hostdevs[i];
if (hdev->mode != VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES)
continue;
virDomainHostdevCaps hdcaps = hdev->source.caps;
if (hdcaps.type != VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET)
continue;
if (virNetDevSetNamespace(hdcaps.u.net.iface, ctrl->initpid) < 0)
return -1;
}
return 0;
}

View File

@ -307,6 +307,7 @@ int virLXCPrepareHostDevices(virLXCDriverPtr driver,
switch (dev->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_STORAGE:
case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_MISC:
case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET:
break;
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,

View File

@ -31,5 +31,10 @@
<char>/dev/tty0</char>
</source>
</hostdev>
<hostdev mode='capabilities' type='net'>
<source>
<interface>eth0</interface>
</source>
</hostdev>
</devices>
</domain>