From eaf7d4ddffe5c51c21422ad50ab6e90840c5d373 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Mon, 4 Mar 2013 18:09:23 +0000 Subject: [PATCH] Add support for disks backed by plain files in LXC By using a loopback device, disks backed by plain files can be made available to LXC containers. We make no attempt to auto-detect format if is not set, instead we unconditionally treat that as meaning raw. This is to avoid the security issues inherent with format auto-detection Signed-off-by: Daniel P. Berrange --- src/lxc/lxc_controller.c | 67 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 3634194386..ce4607094d 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -356,7 +356,7 @@ static int virLXCControllerValidateConsoles(virLXCControllerPtr ctrl) } -static int virLXCControllerSetupLoopDevice(virDomainFSDefPtr fs) +static int virLXCControllerSetupLoopDeviceFS(virDomainFSDefPtr fs) { int lofd; char *loname = NULL; @@ -377,6 +377,27 @@ static int virLXCControllerSetupLoopDevice(virDomainFSDefPtr fs) } +static int virLXCControllerSetupLoopDeviceDisk(virDomainDiskDefPtr disk) +{ + int lofd; + char *loname = NULL; + + if ((lofd = virFileLoopDeviceAssociate(disk->src, &loname)) < 0) + return -1; + + /* + * We now change it into a block device type, so that + * the rest of container setup 'just works' + */ + disk->type = VIR_DOMAIN_DISK_TYPE_BLOCK; + VIR_FREE(disk->src); + disk->src = loname; + loname = NULL; + + return lofd; +} + + static int virLXCControllerSetupLoopDevices(virLXCControllerPtr ctrl) { size_t i; @@ -389,7 +410,7 @@ static int virLXCControllerSetupLoopDevices(virLXCControllerPtr ctrl) if (fs->type != VIR_DOMAIN_FS_TYPE_FILE) continue; - fd = virLXCControllerSetupLoopDevice(fs); + fd = virLXCControllerSetupLoopDeviceFS(fs); if (fd < 0) goto cleanup; @@ -402,6 +423,48 @@ static int virLXCControllerSetupLoopDevices(virLXCControllerPtr ctrl) ctrl->loopDevFds[ctrl->nloopDevs - 1] = fd; } + for (i = 0 ; i < ctrl->def->ndisks ; i++) { + virDomainDiskDefPtr disk = ctrl->def->disks[i]; + int fd; + + if (disk->type != VIR_DOMAIN_DISK_TYPE_FILE) + continue; + + switch (disk->format) { + /* We treat 'none' as meaning 'raw' since we + * don't want to go into the auto-probing + * business for security reasons + */ + case VIR_STORAGE_FILE_RAW: + case VIR_STORAGE_FILE_NONE: + if (disk->driverName && + STRNEQ(disk->driverName, "loop")) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("disk driver %s is not supported"), + disk->driverName); + goto cleanup; + } + + fd = virLXCControllerSetupLoopDeviceDisk(disk); + if (fd < 0) + goto cleanup; + + default: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("disk format %s is not supported"), + virStorageFileFormatTypeToString(disk->format)); + goto cleanup; + } + + VIR_DEBUG("Saving loop fd %d", fd); + if (VIR_EXPAND_N(ctrl->loopDevFds, ctrl->nloopDevs, 1) < 0) { + VIR_FORCE_CLOSE(fd); + virReportOOMError(); + goto cleanup; + } + ctrl->loopDevFds[ctrl->nloopDevs - 1] = fd; + } + VIR_DEBUG("Setup all loop devices"); ret = 0; -- GitLab