]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Ensure root filesystem is mounted if a file/block mount.
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 22 Mar 2013 14:09:41 +0000 (14:09 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 22 Mar 2013 17:27:01 +0000 (17:27 +0000)
For a root filesystem with type=file or type=block, the LXC
container was forgetting to actually mount it, before doing
the pivot root step.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
src/lxc/lxc_container.c

index be9bc6ce4caee62a6a71e045e9e0ec5a3bc21c02..002dba1834b733e3331cd560e20287d7122189b4 100644 (file)
@@ -105,6 +105,9 @@ struct __lxc_child_argv {
     int handshakefd;
 };
 
+static int lxcContainerMountFSBlock(virDomainFSDefPtr fs,
+                                    const char *srcprefix);
+
 
 /*
  * reboot(LINUX_REBOOT_CMD_CAD_ON) will return -EINVAL
@@ -406,6 +409,51 @@ static int lxcContainerChildMountSort(const void *a, const void *b)
 # define MS_SLAVE                (1<<19)
 #endif
 
+static int lxcContainerPrepareRoot(virDomainDefPtr def,
+                                   virDomainFSDefPtr root)
+{
+    char *dst;
+    char *tmp;
+
+    if (root->type == VIR_DOMAIN_FS_TYPE_MOUNT)
+        return 0;
+
+    if (root->type == VIR_DOMAIN_FS_TYPE_FILE) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Unexpected root filesystem without loop device"));
+        return -1;
+    }
+
+    if (root->type != VIR_DOMAIN_FS_TYPE_BLOCK) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Unsupported root filesystem type %s"),
+                       virDomainFSTypeToString(root->type));
+        return -1;
+    }
+
+    if (virAsprintf(&dst, "%s/%s.root",
+                    LXC_STATE_DIR, def->name) < 0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    tmp = root->dst;
+    root->dst = dst;
+
+    if (lxcContainerMountFSBlock(root, "") < 0) {
+        root->dst = tmp;
+        VIR_FREE(dst);
+        return -1;
+    }
+
+    root->dst = tmp;
+    root->type = VIR_DOMAIN_FS_TYPE_MOUNT;
+    VIR_FREE(root->src);
+    root->src = dst;
+
+    return 0;
+}
+
 static int lxcContainerPivotRoot(virDomainFSDefPtr root)
 {
     int ret;
@@ -1926,6 +1974,10 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
     if (lxcContainerIdentifyCGroups(&mounts, &nmounts, &cgroupRoot) < 0)
         goto cleanup;
 
+    /* Ensure the root filesystem is mounted */
+    if (lxcContainerPrepareRoot(vmDef, root) < 0)
+        goto cleanup;
+
     /* Gives us a private root, leaving all parent OS mounts on /.oldroot */
     if (lxcContainerPivotRoot(root) < 0)
         goto cleanup;