[libvirt] [PATCH] Add support for disks backed by plain files in LXC

Daniel P. Berrange berrange at redhat.com
Thu Mar 7 11:41:03 UTC 2013


From: "Daniel P. Berrange" <berrange at redhat.com>

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 <driver type="raw"/> is not set,
instead we unconditionally treat that as meaning raw. This
is to avoid the security issues inherant with format
auto-detection

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 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 a7e715e..176e1be 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;
 
-- 
1.7.11.7




More information about the libvir-list mailing list