mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-08 04:36:21 +00:00
cgfsng: enable "force" for "cgroup-full"
This enables cgroup-full:{mixed,ro,rw}:force and reworks the mount logic. When cgroup-full was specified we used to bind-mount the cgroups from the host. That is pretty weird thing to do given that you can simply mount them directly without going through bind-mounts. Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
This commit is contained in:
parent
becad0ec98
commit
6812d83301
@ -1993,56 +1993,6 @@ static bool cgfsng_chown(void *hdata, struct lxc_conf *conf)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We've safe-mounted a tmpfs as parent, so we don't need to protect against
|
|
||||||
* symlinks any more - just use mount.
|
|
||||||
*
|
|
||||||
* mount cgroup-full if requested
|
|
||||||
*/
|
|
||||||
static int mount_cgroup_full(int type, struct hierarchy *h, char *dest,
|
|
||||||
char *container_cgroup)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
char *rwpath, *source;
|
|
||||||
|
|
||||||
if (type < LXC_AUTO_CGROUP_FULL_RO || type > LXC_AUTO_CGROUP_FULL_MIXED)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ret = mount(h->mountpoint, dest, "cgroup", MS_BIND, NULL);
|
|
||||||
if (ret < 0) {
|
|
||||||
SYSERROR("Failed to bind mount cgroup \"%s\" onto \"%s\"",
|
|
||||||
h->mountpoint, dest);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type != LXC_AUTO_CGROUP_FULL_RW) {
|
|
||||||
unsigned long flags = MS_BIND | MS_NOSUID | MS_NOEXEC | MS_NODEV |
|
|
||||||
MS_REMOUNT | MS_RDONLY;
|
|
||||||
|
|
||||||
ret = mount(NULL, dest, "cgroup", flags, NULL);
|
|
||||||
if (ret < 0) {
|
|
||||||
SYSERROR("Failed to remount cgroup \"%s\" read-only", dest);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
INFO("Bind mounted \"%s\" onto \"%s\"", h->mountpoint, dest);
|
|
||||||
if (type != LXC_AUTO_CGROUP_FULL_MIXED)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* mount just the container path rw */
|
|
||||||
source = must_make_path(h->mountpoint, h->base_cgroup, container_cgroup, NULL);
|
|
||||||
rwpath = must_make_path(dest, h->base_cgroup, container_cgroup, NULL);
|
|
||||||
ret = mount(source, rwpath, "cgroup", MS_BIND, NULL);
|
|
||||||
if (ret < 0)
|
|
||||||
WARN("%s - Failed to mount cgroup \"%s\" read-write",
|
|
||||||
strerror(errno), rwpath);
|
|
||||||
|
|
||||||
TRACE("Mounted cgroup \"%s\" read-write", rwpath);
|
|
||||||
free(rwpath);
|
|
||||||
free(source);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* cgroup-full:* is done, no need to create subdirs */
|
/* cgroup-full:* is done, no need to create subdirs */
|
||||||
static bool cg_mount_needs_subdirs(int type)
|
static bool cg_mount_needs_subdirs(int type)
|
||||||
{
|
{
|
||||||
@ -2056,9 +2006,9 @@ static bool cg_mount_needs_subdirs(int type)
|
|||||||
* remount controller ro if needed and bindmount the cgroupfs onto
|
* remount controller ro if needed and bindmount the cgroupfs onto
|
||||||
* controll/the/cg/path.
|
* controll/the/cg/path.
|
||||||
*/
|
*/
|
||||||
static int do_secondstage_mounts_if_needed(int type, struct hierarchy *h,
|
static int cg_legacy_mount_controllers(int type, struct hierarchy *h,
|
||||||
char *controllerpath, char *cgpath,
|
char *controllerpath, char *cgpath,
|
||||||
const char *container_cgroup)
|
const char *container_cgroup)
|
||||||
{
|
{
|
||||||
int ret, remount_flags;
|
int ret, remount_flags;
|
||||||
char *sourcepath;
|
char *sourcepath;
|
||||||
@ -2115,8 +2065,14 @@ static int do_secondstage_mounts_if_needed(int type, struct hierarchy *h,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cg_mount_in_cgroup_namespace(int type, struct hierarchy *h,
|
/* __cg_mount_direct
|
||||||
const char *controllerpath)
|
*
|
||||||
|
* Mount cgroup hierarchies directly without using bind-mounts. The main
|
||||||
|
* uses-cases are mounting cgroup hierarchies in cgroup namespaces and mounting
|
||||||
|
* cgroups for the LXC_AUTO_CGROUP_FULL option.
|
||||||
|
*/
|
||||||
|
static int __cg_mount_direct(int type, struct hierarchy *h,
|
||||||
|
const char *controllerpath)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char *controllers = NULL;
|
char *controllers = NULL;
|
||||||
@ -2141,14 +2097,29 @@ static int cg_mount_in_cgroup_namespace(int type, struct hierarchy *h,
|
|||||||
ret = mount("cgroup", controllerpath, fstype, flags, controllers);
|
ret = mount("cgroup", controllerpath, fstype, flags, controllers);
|
||||||
free(controllers);
|
free(controllers);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
SYSERROR("Failed to mount %s with cgroup filesystem type %s", controllerpath, fstype);
|
SYSERROR("Failed to mount \"%s\" with cgroup filesystem type %s", controllerpath, fstype);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("Mounted %s with cgroup filesystem type %s", controllerpath, fstype);
|
DEBUG("Mounted \"%s\" with cgroup filesystem type %s", controllerpath, fstype);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int cg_mount_in_cgroup_namespace(int type, struct hierarchy *h,
|
||||||
|
const char *controllerpath)
|
||||||
|
{
|
||||||
|
return __cg_mount_direct(type, h, controllerpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int cg_mount_cgroup_full(int type, struct hierarchy *h,
|
||||||
|
const char *controllerpath)
|
||||||
|
{
|
||||||
|
if (type < LXC_AUTO_CGROUP_FULL_RO || type > LXC_AUTO_CGROUP_FULL_MIXED)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return __cg_mount_direct(type, h, controllerpath);
|
||||||
|
}
|
||||||
|
|
||||||
static bool cgfsng_mount(void *hdata, const char *root, int type)
|
static bool cgfsng_mount(void *hdata, const char *root, int type)
|
||||||
{
|
{
|
||||||
int i, ret;
|
int i, ret;
|
||||||
@ -2183,7 +2154,7 @@ static bool cgfsng_mount(void *hdata, const char *root, int type)
|
|||||||
|
|
||||||
/* Mount tmpfs */
|
/* Mount tmpfs */
|
||||||
tmpfspath = must_make_path(root, "/sys/fs/cgroup", NULL);
|
tmpfspath = must_make_path(root, "/sys/fs/cgroup", NULL);
|
||||||
ret = safe_mount("cgroup_root", tmpfspath, "tmpfs",
|
ret = safe_mount(NULL, tmpfspath, "tmpfs",
|
||||||
MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME,
|
MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME,
|
||||||
"size=10240k,mode=755", root);
|
"size=10240k,mode=755", root);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -2224,7 +2195,7 @@ static bool cgfsng_mount(void *hdata, const char *root, int type)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = mount_cgroup_full(type, h, controllerpath, d->container_cgroup);
|
ret = cg_mount_cgroup_full(type, h, controllerpath);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(controllerpath);
|
free(controllerpath);
|
||||||
goto on_error;
|
goto on_error;
|
||||||
@ -2244,8 +2215,8 @@ static bool cgfsng_mount(void *hdata, const char *root, int type)
|
|||||||
goto on_error;
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = do_secondstage_mounts_if_needed(type, h, controllerpath,
|
ret = cg_legacy_mount_controllers(type, h, controllerpath,
|
||||||
path2, d->container_cgroup);
|
path2, d->container_cgroup);
|
||||||
free(controllerpath);
|
free(controllerpath);
|
||||||
free(path2);
|
free(path2);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -1706,25 +1706,29 @@ static int set_config_mount_auto(const char *key, const char *value,
|
|||||||
int mask;
|
int mask;
|
||||||
int flag;
|
int flag;
|
||||||
} allowed_auto_mounts[] = {
|
} allowed_auto_mounts[] = {
|
||||||
{ "proc", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED },
|
{ "proc", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED },
|
||||||
{ "proc:mixed", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED },
|
{ "proc:mixed", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_MIXED },
|
||||||
{ "proc:rw", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_RW },
|
{ "proc:rw", LXC_AUTO_PROC_MASK, LXC_AUTO_PROC_RW },
|
||||||
{ "sys", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED },
|
{ "sys", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED },
|
||||||
{ "sys:ro", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RO },
|
{ "sys:ro", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RO },
|
||||||
{ "sys:mixed", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED },
|
{ "sys:mixed", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_MIXED },
|
||||||
{ "sys:rw", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RW },
|
{ "sys:rw", LXC_AUTO_SYS_MASK, LXC_AUTO_SYS_RW },
|
||||||
{ "cgroup", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_NOSPEC },
|
{ "cgroup", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_NOSPEC },
|
||||||
{ "cgroup:mixed", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_MIXED },
|
{ "cgroup:mixed", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_MIXED },
|
||||||
{ "cgroup:ro", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RO },
|
{ "cgroup:ro", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RO },
|
||||||
{ "cgroup:rw", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RW },
|
{ "cgroup:rw", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RW },
|
||||||
{ "cgroup:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_NOSPEC | LXC_AUTO_CGROUP_FORCE },
|
{ "cgroup:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_NOSPEC | LXC_AUTO_CGROUP_FORCE },
|
||||||
{ "cgroup:mixed:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_MIXED | LXC_AUTO_CGROUP_FORCE },
|
{ "cgroup:mixed:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_MIXED | LXC_AUTO_CGROUP_FORCE },
|
||||||
{ "cgroup:ro:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RO | LXC_AUTO_CGROUP_FORCE },
|
{ "cgroup:ro:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RO | LXC_AUTO_CGROUP_FORCE },
|
||||||
{ "cgroup:rw:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RW | LXC_AUTO_CGROUP_FORCE },
|
{ "cgroup:rw:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_RW | LXC_AUTO_CGROUP_FORCE },
|
||||||
{ "cgroup-full", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_NOSPEC },
|
{ "cgroup-full", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_NOSPEC },
|
||||||
{ "cgroup-full:mixed", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_MIXED },
|
{ "cgroup-full:mixed", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_MIXED },
|
||||||
{ "cgroup-full:ro", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RO },
|
{ "cgroup-full:ro", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RO },
|
||||||
{ "cgroup-full:rw", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RW },
|
{ "cgroup-full:rw", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RW },
|
||||||
|
{ "cgroup-full:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_NOSPEC | LXC_AUTO_CGROUP_FORCE },
|
||||||
|
{ "cgroup-full:mixed:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_MIXED | LXC_AUTO_CGROUP_FORCE },
|
||||||
|
{ "cgroup-full:ro:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RO | LXC_AUTO_CGROUP_FORCE },
|
||||||
|
{ "cgroup-full:rw:force", LXC_AUTO_CGROUP_MASK, LXC_AUTO_CGROUP_FULL_RW | LXC_AUTO_CGROUP_FORCE },
|
||||||
/* For adding anything that is just a single on/off, but has no
|
/* For adding anything that is just a single on/off, but has no
|
||||||
* options: keep mask and flag identical and just define the enum
|
* options: keep mask and flag identical and just define the enum
|
||||||
* value as an unused bit so far
|
* value as an unused bit so far
|
||||||
|
Loading…
Reference in New Issue
Block a user