]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Implement support for <hostdev caps=net>
authorBogdan Purcareata <bogdan.purcareata@freescale.com>
Fri, 5 Apr 2013 12:26:40 +0000 (08:26 -0400)
committerDaniel P. Berrange <berrange@redhat.com>
Mon, 8 Apr 2013 16:40:08 +0000 (17:40 +0100)
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>
src/lxc/lxc_container.c
src/lxc/lxc_controller.c
src/lxc/lxc_hostdev.c
tests/lxcxml2xmldata/lxc-hostdev.xml

index 002ba9e9d674842af12213689164f5bc04f29a6c..1e8a3db2d10646f312674cc68be329078cdf08b5 100644 (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;
     }
index 6425ff167b8d5ad2eeb5a1a892f3ff6dcd07eb0a..f2462ef5fe8b8d363cff2bd290a9927cfd6f6bc7 100644 (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;
 }
 
index 33b0b60a6925c055c7e309630aa2550e4b8bd491..53a1a31f7f96890a157462c99edb0b63d7f4236d 100644 (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,
index b022cc714bde0f128d25eb5c12bde796fa5333e4..befe0db329eb199b094f5d2efcab12b27ccff254 100644 (file)
         <char>/dev/tty0</char>
       </source>
     </hostdev>
+    <hostdev mode='capabilities' type='net'>
+      <source>
+        <interface>eth0</interface>
+      </source>
+    </hostdev>
   </devices>
 </domain>