From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> 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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list