]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add support for misc host device passthrough with LXC
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 28 Nov 2012 18:07:47 +0000 (18:07 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Mon, 17 Dec 2012 17:50:51 +0000 (17:50 +0000)
This extends support for host device passthrough with LXC to
cover misc devices. In this case all we need todo is a
mknod in the container's /dev and whitelist the device in
cgroups

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
src/lxc/lxc_cgroup.c
src/lxc/lxc_container.c

index 0c3d5dd69cf476c24aa5ef841ab8492cdd766ac1..4fe23c1180e81ad37ff823da12ed8205744c02e6 100644 (file)
@@ -439,6 +439,13 @@ static int virLXCCgroupSetupDeviceACL(virDomainDefPtr def,
                                              VIR_CGROUP_DEVICE_MKNOD) < 0)
                     goto cleanup;
                 break;
+            case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_MISC:
+                if (virCgroupAllowDevicePath(cgroup,
+                                             hostdev->source.caps.u.misc.chardev,
+                                             VIR_CGROUP_DEVICE_RW |
+                                             VIR_CGROUP_DEVICE_MKNOD) < 0)
+                    goto cleanup;
+                break;
             default:
                 break;
             }
index 6e5810ca34e7957819eb0fd6d0b67f7cefe0d9d4..da3eae1331c88177cd13142cf5becf26aaf47973 100644 (file)
@@ -1443,6 +1443,64 @@ cleanup:
 }
 
 
+static int lxcContainerSetupHostdevCapsMisc(virDomainDefPtr vmDef ATTRIBUTE_UNUSED,
+                                            virDomainHostdevDefPtr def ATTRIBUTE_UNUSED,
+                                            const char *dstprefix ATTRIBUTE_UNUSED,
+                                            virSecurityManagerPtr securityDriver ATTRIBUTE_UNUSED)
+{
+    char *src = NULL;
+    int ret = -1;
+    struct stat sb;
+    mode_t mode;
+
+    if (def->source.caps.u.misc.chardev == NULL) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("Missing storage host block path"));
+        goto cleanup;
+    }
+
+    if (virAsprintf(&src, "%s/%s", dstprefix, def->source.caps.u.misc.chardev) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if (stat(src, &sb) < 0) {
+        virReportSystemError(errno,
+                             _("Unable to access %s"),
+                             src);
+        goto cleanup;
+    }
+
+    if (!S_ISCHR(sb.st_mode)) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Storage source %s must be a character device"),
+                       def->source.caps.u.misc.chardev);
+        goto cleanup;
+    }
+
+    mode = 0700 | S_IFCHR;
+
+    VIR_DEBUG("Creating dev %s (%d,%d)",
+              def->source.caps.u.misc.chardev,
+              major(sb.st_rdev), minor(sb.st_rdev));
+    if (mknod(def->source.caps.u.misc.chardev, mode, sb.st_rdev) < 0) {
+        virReportSystemError(errno,
+                             _("Unable to create device %s"),
+                             def->source.caps.u.misc.chardev);
+        goto cleanup;
+    }
+
+    if (virSecurityManagerSetHostdevLabel(securityDriver, vmDef, def, NULL) < 0)
+        goto cleanup;
+
+    ret = 0;
+
+cleanup:
+    VIR_FREE(src);
+    return ret;
+}
+
+
 static int lxcContainerSetupHostdevSubsys(virDomainDefPtr vmDef,
                                           virDomainHostdevDefPtr def,
                                           const char *dstprefix,
@@ -1470,6 +1528,9 @@ static int lxcContainerSetupHostdevCaps(virDomainDefPtr vmDef,
     case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_STORAGE:
         return lxcContainerSetupHostdevCapsStorage(vmDef, def, dstprefix, securityDriver);
 
+    case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_MISC:
+        return lxcContainerSetupHostdevCapsMisc(vmDef, def, dstprefix, securityDriver);
+
     default:
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("Unsupported host device mode %s"),