on 2012/12/01 04:26, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange(a)redhat.com>
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(a)redhat.com>
---
src/lxc/lxc_cgroup.c | 7 ++++++
src/lxc/lxc_container.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 68 insertions(+)
diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index 0c3d5dd..4fe23c1 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -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;
}
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 19c5702..25a3ab5 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -1442,6 +1442,64 @@ cleanup:
}
+static int lxcContainerSetupHostdevCapsMisc(virDomainDefPtr vmDef ATTRIBUTE_UNUSED,
+ virDomainHostdevDefPtr def
ATTRIBUTE_UNUSED,
+ const char *dstprefix ATTRIBUTE_UNUSED,
+ virSecurityManagerPtr securityDriver
ATTRIBUTE_UNUSED)
ATTRIBUTE_UNUSED should be removed.
+{
+ 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"));
we need proper error message.
+ 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,
@@ -1469,6 +1527,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"),
ACK