On 2012/12/01 04:26, Daniel P. Berrange wrote: > From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> > > Wire up the attach/detach device drivers in LXC to support the > hotplug/unplug of host storage devices. > > Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> > --- > src/lxc/lxc_driver.c | 237 +++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 237 insertions(+) > > diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c > index 50050cf..27ee3d7 100644 > --- a/src/lxc/lxc_driver.c > +++ b/src/lxc/lxc_driver.c > @@ -3224,6 +3224,12 @@ lxcDomainAttachDeviceHostdevSubsysUSBLive(virLXCDriverPtr driver, > usbDevice *usb = NULL; > virCgroupPtr group = NULL; > > + if (virDomainHostdevFind(vm->def, def, NULL) >= 0) { > + virReportError(VIR_ERR_OPERATION_FAILED, "%s", > + _("host USB device already exists")); > + return -1; > + } > + It shouldn't be in patch [19/23]? > if (virAsprintf(&vroot, "/proc/%llu/root", > (unsigned long long)priv->initpid) < 0) { > virReportOOMError(); > @@ -3351,6 +3357,123 @@ cleanup: > > > static int > +lxcDomainAttachDeviceHostdevStorageLive(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.storage.block) { > + 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.storage.block, &sb) < 0) { > + virReportSystemError(errno, > + _("Unable to access %s"), > + def->source.caps.u.storage.block); > + goto cleanup; > + } > + > + if (!S_ISBLK(sb.st_mode)) { > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, > + _("Hostdev source %s must be a block device"), > + def->source.caps.u.storage.block); > + 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.storage.block) < 0) { > + virReportOOMError(); > + goto cleanup; > + } > + > + if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0) { > + virReportOOMError(); > + goto cleanup; > + } > + > + mode = 0700 | S_IFBLK; > + > + VIR_DEBUG("Creating dev %s (%d,%d)", > + def->source.caps.u.storage.block, > + 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.storage.block, > + VIR_CGROUP_DEVICE_RW | > + VIR_CGROUP_DEVICE_MKNOD) != 0) { > + virReportError(VIR_ERR_INTERNAL_ERROR, > + _("cannot allow device %s for domain %s"), > + def->source.caps.u.storage.block, 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); dst and vroot should be freed. And I wonder vm->def->hostdevs shouldn't be restored when attaching failed? > + return ret; > +} > + > + [...] > + > +static int > +lxcDomainDetachDeviceHostdevStorageLive(virLXCDriverPtr driver, > + virDomainObjPtr vm, > + virDomainDeviceDefPtr dev) > +{ > + virLXCDomainObjPrivatePtr priv = vm->privateData; > + virDomainHostdevDefPtr def = NULL; > + virCgroupPtr group = NULL; > + int i, ret = -1; > + char *dst = NULL; > + > + if (!priv->initpid) { > + virReportError(VIR_ERR_OPERATION_INVALID, "%s", > + _("Cannot attach disk until init PID is known")); Need proper error msg here. ACK -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list