[libvirt] [PATCH 21/23] Add support for hotplug/unplug of host misc devices in LXC
Gao feng
gaofeng at cn.fujitsu.com
Fri Dec 14 12:10:32 UTC 2012
On 2012/12/01 04:26, Daniel P. Berrange wrote:
> From: "Daniel P. Berrange" <berrange at redhat.com>
>
> Wire up the attach/detach device drivers in LXC to support the
> hotplug/unplug of host misc devices.
>
> Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
> ---
> src/lxc/lxc_driver.c | 194 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 194 insertions(+)
>
> diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
> index 27ee3d7..17445a7 100644
> --- a/src/lxc/lxc_driver.c
> +++ b/src/lxc/lxc_driver.c
> @@ -3474,6 +3474,123 @@ cleanup:
>
>
> static int
> +lxcDomainAttachDeviceHostdevMiscLive(virLXCDriverPtr driver,
> + virDomainObjPtr vm,
> + virDomainDeviceDefPtr dev)
> +{
> + virLXCDomainObjPrivatePtr priv = vm->privateData;
> + virDomainHostdevDefPtr def = dev->data.hostdev;
> + virCgroupPtr group = NULL;
> + int ret = -1;
> + char *dst;
> + char *vroot;
> + struct stat sb;
> + bool created = false;
> + mode_t mode = 0;
> +
> + if (!priv->initpid) {
> + virReportError(VIR_ERR_OPERATION_INVALID, "%s",
> + _("Cannot attach disk until init PID is known"));
> + goto cleanup;
> + }
> +
> + if (!def->source.caps.u.misc.chardev) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> + _("Missing storage block path"));
> + goto cleanup;
> + }
> +
> + if (virDomainHostdevFind(vm->def, def, NULL) >= 0) {
> + virReportError(VIR_ERR_OPERATION_FAILED, "%s",
> + _("host device already exists"));
> + return -1;
> + }
> +
> + if (stat(def->source.caps.u.misc.chardev, &sb) < 0) {
> + virReportSystemError(errno,
> + _("Unable to access %s"),
> + def->source.caps.u.misc.chardev);
> + goto cleanup;
> + }
> +
> + if (!S_ISCHR(sb.st_mode)) {
> + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> + _("Hostdev source %s must be a block device"),
> + def->source.caps.u.misc.chardev);
> + goto cleanup;
> + }
> +
> + if (virAsprintf(&vroot, "/proc/%llu/root",
> + (unsigned long long)priv->initpid) < 0) {
> + virReportOOMError();
> + goto cleanup;
> + }
> +
> + if (virAsprintf(&dst, "%s/%s",
> + vroot,
> + def->source.caps.u.misc.chardev) < 0) {
> + virReportOOMError();
> + goto cleanup;
> + }
> +
> + if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0) {
> + virReportOOMError();
> + 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(dst, mode, sb.st_rdev) < 0) {
> + virReportSystemError(errno,
> + _("Unable to create device %s"),
> + dst);
> + goto cleanup;
> + }
> + created = true;
> +
> + if (virSecurityManagerSetHostdevLabel(driver->securityManager,
> + vm->def, def, vroot) < 0)
> + goto cleanup;
> +
> + if (!lxcCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
> + virReportError(VIR_ERR_OPERATION_INVALID, "%s",
> + _("devices cgroup isn't mounted"));
> + goto cleanup;
> + }
> +
> + if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("cannot find cgroup for domain %s"), vm->def->name);
> + goto cleanup;
> + }
> +
> + if (virCgroupAllowDevicePath(group, def->source.caps.u.misc.chardev,
> + VIR_CGROUP_DEVICE_RW |
> + VIR_CGROUP_DEVICE_MKNOD) != 0) {
VIR_CGROUP_DEVICE_RWM
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("cannot allow device %s for domain %s"),
> + def->source.caps.u.misc.chardev, vm->def->name);
> + goto cleanup;
> + }
> +
> + vm->def->hostdevs[vm->def->nhostdevs++] = def;
> +
> + ret = 0;
> +
> +cleanup:
> + virDomainAuditHostdev(vm, def, "attach", ret == 0);
> + if (group)
> + virCgroupFree(&group);
> + if (dst && created && ret < 0)
> + unlink(dst);
> + return ret;
> +}
> +
dst and vroot need be freed.
ACK
More information about the libvir-list
mailing list