Unverified Commit af949cc1 by Serge Hallyn Committed by GitHub

Merge pull request #1888 from brauner/2017-10-30/enable_cgfsng_cgroup_mounting

cgroups: enable container without CAP_SYS_ADMIN
parents cf13d107 b635e92d
......@@ -1418,11 +1418,12 @@ static bool cgroupfs_mount_cgroup(void *hdata, const char *root, int type)
struct cgfs_data *cgfs_d;
struct cgroup_process_info *info, *base_info;
int r, saved_errno = 0;
struct lxc_handler *handler = hdata;
if (cgns_supported())
return true;
cgfs_d = hdata;
cgfs_d = handler->cgroup_data;
if (!cgfs_d)
return false;
base_info = cgfs_d->info;
......
......@@ -50,6 +50,7 @@
#include <linux/types.h>
#include <linux/kdev_t.h>
#include "caps.h"
#include "cgroup.h"
#include "cgroup_utils.h"
#include "commands.h"
......@@ -815,7 +816,7 @@ static void add_controller(char **clist, char *mountpoint, char *base_cgroup)
new->fullcgpath = NULL;
/* record if this is the cgroup v2 hierarchy */
if (!strcmp(base_cgroup, "cgroup2"))
if (clist && !strcmp(*clist, "cgroup2"))
new->is_cgroup_v2 = true;
else
new->is_cgroup_v2 = false;
......@@ -1616,17 +1617,49 @@ do_secondstage_mounts_if_needed(int type, struct hierarchy *h,
return 0;
}
static int mount_cgroup_cgns_supported(struct hierarchy *h, const char *controllerpath)
{
int ret;
char *controllers = NULL;
char *type = "cgroup2";
if (!h->is_cgroup_v2) {
controllers = lxc_string_join(",", (const char **)h->controllers, false);
if (!controllers)
return -ENOMEM;
type = "cgroup";
}
ret = mount("cgroup", controllerpath, type, MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RELATIME, controllers);
free(controllers);
if (ret < 0) {
SYSERROR("Failed to mount %s with cgroup filesystem type %s", controllerpath, type);
return -1;
}
DEBUG("Mounted %s with cgroup filesystem type %s", controllerpath, type);
return 0;
}
static bool cgfsng_mount(void *hdata, const char *root, int type)
{
struct cgfsng_handler_data *d = hdata;
int i;
char *tmpfspath = NULL;
bool retval = false;
int i;
struct lxc_handler *handler = hdata;
struct cgfsng_handler_data *d = handler->cgroup_data;
bool has_cgns = false, has_sys_admin = true;
if ((type & LXC_AUTO_CGROUP_MASK) == 0)
return true;
if (cgns_supported())
has_cgns = cgns_supported();
if (!lxc_list_empty(&handler->conf->keepcaps))
has_sys_admin = in_caplist(CAP_SYS_ADMIN, &handler->conf->keepcaps);
else
has_sys_admin = !in_caplist(CAP_SYS_ADMIN, &handler->conf->caps);
if (has_cgns && has_sys_admin)
return true;
tmpfspath = must_make_path(root, "/sys/fs/cgroup", NULL);
......@@ -1662,6 +1695,19 @@ static bool cgfsng_mount(void *hdata, const char *root, int type)
free(controllerpath);
goto bad;
}
if (has_cgns && !has_sys_admin) {
/* If cgroup namespaces are supported but the container
* will not have CAP_SYS_ADMIN after it has started we
* need to mount the cgroups manually.
*/
r = mount_cgroup_cgns_supported(h, controllerpath);
free(controllerpath);
if (r < 0)
goto bad;
continue;
}
if (mount_cgroup_full(type, h, controllerpath, d->container_cgroup) < 0) {
free(controllerpath);
goto bad;
......
......@@ -166,7 +166,7 @@ bool cgroup_chown(struct lxc_handler *handler)
bool cgroup_mount(const char *root, struct lxc_handler *handler, int type)
{
if (ops)
return ops->mount_cgroup(handler->cgroup_data, root, type);
return ops->mount_cgroup(handler, root, type);
return false;
}
......
......@@ -210,9 +210,6 @@ __thread struct lxc_conf *current_config;
struct lxc_conf *current_config;
#endif
/* Declare this here, since we don't want to reshuffle the whole file. */
static int in_caplist(int cap, struct lxc_list *caps);
static struct mount_opt mount_opt[] = {
{ "async", 1, MS_SYNCHRONOUS },
{ "atime", 1, MS_NOATIME },
......
......@@ -402,5 +402,6 @@ extern unsigned long add_required_remount_flags(const char *s, const char *d,
unsigned long flags);
extern int run_script(const char *name, const char *section, const char *script,
...);
extern int in_caplist(int cap, struct lxc_list *caps);
#endif /* __LXC_CONF_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment