Auto-add a root <filesystem> element to LXC containers on startup

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@redhat.com>
This commit is contained in:
Daniel P. Berrange 2013-04-03 16:19:24 +01:00
parent f7e8653f7e
commit c131525bec
2 changed files with 41 additions and 107 deletions

View File

@ -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)) {

View File

@ -981,6 +981,38 @@ 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_INSERT_ELEMENT(vm->def->fss,
0,
vm->def->nfss,
root) < 0)
goto no_memory;
return 0;
no_memory:
virReportOOMError();
virDomainFSDefFree(root);
return -1;
}
/**
* virLXCProcessStart:
* @conn: pointer to connection
@ -1078,6 +1110,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)