From: "Daniel P. Berrange" <berrange(a)redhat.com>
Currently the LXC container code has two codepaths, depending on
whether there is a <filesystem> element with a target path of '/'.
If we automatically add a <filesystem> device with src=/ and dst=/,
for any container which has not specified a root filesystem, then
we only need one codepath for setting up the filesystem.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/lxc/lxc_container.c | 113 +++---------------------------------------------
src/lxc/lxc_process.c | 38 ++++++++++++++++
2 files changed, 44 insertions(+), 107 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 002dba1..002ba9e 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -2049,92 +2049,6 @@ cleanup:
}
-/* Nothing mapped to /, we're using the main root,
- but with extra stuff mapped in */
-static int lxcContainerSetupExtraMounts(virDomainDefPtr vmDef,
- virDomainFSDefPtr root,
- virSecurityManagerPtr securityDriver)
-{
- int ret = -1;
- struct lxcContainerCGroup *mounts = NULL;
- size_t nmounts = 0;
- char *cgroupRoot = NULL;
- char *sec_mount_options;
-
- VIR_DEBUG("def=%p", vmDef);
-
- if (!(sec_mount_options = virSecurityManagerGetMountOptions(securityDriver, vmDef)))
- return -1;
-
- /*
- * This makes sure that any new filesystems in the
- * host OS propagate to the container, but any
- * changes in the container are private
- */
- if (mount("", "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) {
- virReportSystemError(errno, "%s",
- _("Failed to make / slave"));
- goto cleanup;
- }
-
- if (root && root->readonly) {
- if (mount("", "/", NULL, MS_BIND|MS_REC|MS_RDONLY|MS_REMOUNT,
NULL) < 0) {
- virReportSystemError(errno, "%s",
- _("Failed to make root readonly"));
- goto cleanup;
- }
- }
-
- VIR_DEBUG("Mounting config FS");
- if (lxcContainerMountAllFS(vmDef, "", false, sec_mount_options) < 0)
- goto cleanup;
-
- /* Before replacing /sys we need to identify any
- * cgroups controllers that are mounted */
- if (lxcContainerIdentifyCGroups(&mounts, &nmounts, &cgroupRoot) < 0)
- goto cleanup;
-
-#if WITH_SELINUX
- /* Some versions of Linux kernel don't let you overmount
- * the selinux filesystem, so make sure we kill it first
- */
- if (lxcContainerUnmountSubtree(SELINUX_MOUNT, false) < 0)
- goto cleanup;
-#endif
-
- /* Gets rid of any existing stuff under /proc, since we need new
- * namespace aware versions of those. We must do /proc second
- * otherwise we won't find /proc/mounts :-) */
- if (lxcContainerUnmountSubtree("/sys", false) < 0 ||
- lxcContainerUnmountSubtree("/proc", false) < 0)
- goto cleanup;
-
- /* Mounts the core /proc, /sys, etc filesystems */
- if (lxcContainerMountBasicFS(false, sec_mount_options) < 0)
- goto cleanup;
-
- /* Mounts /proc/meminfo etc sysinfo */
- if (lxcContainerMountProcFuse(vmDef, NULL) < 0)
- goto cleanup;
-
- /* Now we can re-mount the cgroups controllers in the
- * same configuration as before */
- if (lxcContainerMountCGroups(mounts, nmounts,
- cgroupRoot, sec_mount_options) < 0)
- goto cleanup;
-
- VIR_DEBUG("Mounting completed");
-
- ret = 0;
-
-cleanup:
- lxcContainerCGroupFree(mounts, nmounts);
- VIR_FREE(cgroupRoot);
- VIR_FREE(sec_mount_options);
- return ret;
-}
-
-
static int lxcContainerResolveSymlinks(virDomainDefPtr vmDef)
{
char *newroot;
@@ -2156,24 +2070,6 @@ static int lxcContainerResolveSymlinks(virDomainDefPtr vmDef)
return 0;
}
-static int lxcContainerSetupMounts(virDomainDefPtr vmDef,
- virDomainFSDefPtr root,
- char **ttyPaths,
- size_t nttyPaths,
- virSecurityManagerPtr securityDriver)
-{
- if (lxcContainerResolveSymlinks(vmDef) < 0)
- return -1;
-
- if (root && root->src)
- return lxcContainerSetupPivotRoot(vmDef, root, ttyPaths, nttyPaths,
- securityDriver);
- else
- return lxcContainerSetupExtraMounts(vmDef, root,
- securityDriver);
-}
-
-
/*
* This is running as the 'init' process insid the container.
* It removes some capabilities that could be dangerous to
@@ -2290,9 +2186,12 @@ static int lxcContainerChild(void *data)
goto cleanup;
}
- if (lxcContainerSetupMounts(vmDef, root,
- argv->ttyPaths, argv->nttyPaths,
- argv->securityDriver) < 0)
+ if (lxcContainerResolveSymlinks(vmDef) < 0)
+ goto cleanup;
+
+ if (lxcContainerSetupPivotRoot(vmDef, root,
+ argv->ttyPaths, argv->nttyPaths,
+ argv->securityDriver) < 0)
goto cleanup;
if (!virFileExists(vmDef->os.init)) {
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index 39a6ea2..c300bb2 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -981,6 +981,41 @@ virLXCProcessReadLogOutput(virDomainObjPtr vm,
return ret;
}
+
+static int
+virLXCProcessEnsureRootFS(virDomainObjPtr vm)
+{
+ virDomainFSDefPtr root = virDomainGetRootFilesystem(vm->def);
+
+ if (root)
+ return 0;
+
+ if (VIR_ALLOC(root) < 0)
+ goto no_memory;
+
+ root->type = VIR_DOMAIN_FS_TYPE_MOUNT;
+
+ if (!(root->src = strdup("/")) ||
+ !(root->dst = strdup("/")))
+ goto no_memory;
+
+ if (VIR_EXPAND_N(vm->def->fss,
+ vm->def->nfss, 1) < 0)
+ goto no_memory;
+
+ memmove(vm->def->fss + 1,
+ vm->def->fss,
+ vm->def->nfss * sizeof(virDomainFSDefPtr));
+ vm->def->fss[0] = root;
+
+ return 0;
+
+no_memory:
+ virReportOOMError();
+ virDomainFSDefFree(root);
+ return -1;
+}
+
/**
* virLXCProcessStart:
* @conn: pointer to connection
@@ -1078,6 +1113,9 @@ int virLXCProcessStart(virConnectPtr conn,
goto cleanup;
}
+ if (virLXCProcessEnsureRootFS(vm) < 0)
+ goto cleanup;
+
/* Must be run before security labelling */
VIR_DEBUG("Preparing host devices");
if (virLXCPrepareHostDevices(driver, vm->def) < 0)
--
1.7.11.7