}
}
+ for (i = 0 ; i < def->ndisks ; i++) {
+ if (def->disks[i]->type != VIR_DOMAIN_DISK_TYPE_BLOCK)
+ continue;
+
+ rc = virCgroupAllowDevicePath(cgroup,
+ def->disks[i]->src,
+ (def->disks[i]->readonly ?
+ VIR_CGROUP_DEVICE_READ :
+ VIR_CGROUP_DEVICE_RW) |
+ VIR_CGROUP_DEVICE_MKNOD);
+ if (rc != 0) {
+ virReportSystemError(-rc,
+ _("Unable to allow device %s for domain %s"),
+ def->disks[i]->src, def->name);
+ goto cleanup;
+ }
+ }
+
for (i = 0 ; i < def->nfss ; i++) {
if (def->fss[i]->type != VIR_DOMAIN_FS_TYPE_BLOCK)
continue;
}
+static int lxcContainerSetupDisk(virDomainDefPtr vmDef,
+ virDomainDiskDefPtr def,
+ const char *dstprefix,
+ virSecurityManagerPtr securityDriver)
+{
+ char *src = NULL;
+ char *dst = NULL;
+ int ret = -1;
+ struct stat sb;
+ mode_t mode;
+ char *tmpsrc = def->src;
+
+ if (def->type != VIR_DOMAIN_DISK_TYPE_BLOCK) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Can't setup disk for non-block device"));
+ goto cleanup;
+ }
+ if (def->src == NULL) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Can't setup disk without media"));
+ goto cleanup;
+ }
+
+ if (virAsprintf(&src, "%s/%s", dstprefix, def->src) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (virAsprintf(&dst, "/dev/%s", def->dst) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (stat(src, &sb) < 0) {
+ virReportSystemError(errno,
+ _("Unable to access %s"), def->src);
+ goto cleanup;
+ }
+
+ if (!S_ISCHR(sb.st_mode) && !S_ISBLK(sb.st_mode)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Disk source %s must be a character/block device"),
+ def->src);
+ goto cleanup;
+ }
+
+ mode = 0700;
+ if (S_ISCHR(sb.st_mode))
+ mode |= S_IFCHR;
+ else
+ mode |= S_IFBLK;
+
+ /* Yes, the device name we're creating may not
+ * actually correspond to the major:minor number
+ * we're using, but we've no other option at this
+ * time. Just have to hope that containerized apps
+ * don't get upset that the major:minor is different
+ * to that normally implied by the device name
+ */
+ VIR_DEBUG("Creating dev %s (%d,%d) from %s",
+ dst, major(sb.st_rdev), minor(sb.st_rdev), src);
+ if (mknod(dst, mode, sb.st_rdev) < 0) {
+ virReportSystemError(errno,
+ _("Unable to create device %s"),
+ dst);
+ goto cleanup;
+ }
+ /* Labelling normally operates on src, but we need
+ * to actally label the dst here, so hack the config */
+ def->src = dst;
+ if (virSecurityManagerSetImageLabel(securityDriver, vmDef, def) < 0)
+ goto cleanup;
+
+ ret = 0;
+
+cleanup:
+ def->src = tmpsrc;
+ VIR_FREE(src);
+ VIR_FREE(dst);
+ return ret;
+}
+
+static int lxcContainerSetupAllDisks(virDomainDefPtr vmDef,
+ const char *dstprefix,
+ virSecurityManagerPtr securityDriver)
+{
+ size_t i;
+ VIR_DEBUG("Setting up disks %s", dstprefix);
+
+ for (i = 0 ; i < vmDef->ndisks ; i++) {
+ if (lxcContainerSetupDisk(vmDef, vmDef->disks[i],
+ dstprefix, securityDriver) < 0)
+ return -1;
+ }
+
+ VIR_DEBUG("Setup all disks");
+ return 0;
+}
+
+
static int lxcContainerGetSubtree(const char *prefix,
char ***mountsret,
size_t *nmountsret)
if (lxcContainerMountAllFS(vmDef, "/.oldroot", true, sec_mount_options) < 0)
goto cleanup;
+ /* Sets up any extra disks from guest config */
+ if (lxcContainerSetupAllDisks(vmDef, "/.oldroot", securityDriver) < 0)
+ goto cleanup;
+
/* Gets rid of all remaining mounts from host OS, including /.oldroot itself */
if (lxcContainerUnmountSubtree("/.oldroot", true) < 0)
goto cleanup;