mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
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:
parent
f7e8653f7e
commit
c131525bec
@ -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)) {
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user