[lxc-devel] [PATCH 1/3] cgroup: add cgroup_escape() call

Serge Hallyn serge.hallyn at ubuntu.com
Wed Dec 9 02:58:20 UTC 2015


Quoting Tycho Andersen (tycho.andersen at canonical.com):
> We'll use this in the next patch to escape to the root cgroup before we
> exec criu.
> 
> Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
> ---
>  src/lxc/cgfs.c      | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/lxc/cgmanager.c | 19 ++++++++++++++++---
>  src/lxc/cgroup.c    |  7 +++++++
>  src/lxc/cgroup.h    |  2 ++
>  4 files changed, 75 insertions(+), 3 deletions(-)
> 
> diff --git a/src/lxc/cgfs.c b/src/lxc/cgfs.c
> index d65f2d7..94b3d87 100644
> --- a/src/lxc/cgfs.c
> +++ b/src/lxc/cgfs.c
> @@ -2343,6 +2343,55 @@ static const char *cgfs_canonical_path(void *hdata)
>  	return path;
>  }
>  
> +static bool cgfs_escape(void)
> +{
> +	struct cgroup_meta_data *md;
> +	int i;
> +	bool ret = false;
> +
> +	md = lxc_cgroup_load_meta();
> +	if (!md)
> +		return false;
> +
> +	for (i = 1; i <= md->maximum_hierarchy; i++) {
> +		struct cgroup_hierarchy *h = md->hierarchies[i];
> +		struct cgroup_mount_point *mp;
> +		char *tasks;
> +		FILE *f;
> +		int written;
> +
> +		if (!h) {
> +			WARN("not escaping hierarchy %d", i);
> +			continue;
> +		}
> +
> +		mp = lxc_cgroup_find_mount_point(h, "/", true);
> +		if (!mp)
> +			goto out;
> +
> +		tasks = cgroup_to_absolute_path(mp, "/", "tasks");
> +		if (!tasks)
> +			goto out;
> +
> +		f = fopen(tasks, "a");
> +		free(tasks);
> +		if (!f)
> +			goto out;
> +
> +		written = fprintf(f, "%d\n", getpid());
> +		fclose(f);
> +		if (written < 0) {
> +			SYSERROR("writing tasks failed\n");
> +			goto out;
> +		}
> +	}
> +
> +	ret = true;
> +out:
> +	lxc_cgroup_put_meta(md);
> +	return ret;
> +}
> +
>  static bool cgfs_unfreeze(void *hdata)
>  {
>  	struct cgfs_data *d = hdata;
> @@ -2408,6 +2457,7 @@ static struct cgroup_ops cgfs_ops = {
>  	.create_legacy = cgfs_create_legacy,
>  	.get_cgroup = cgfs_get_cgroup,
>  	.canonical_path = cgfs_canonical_path,
> +	.escape = cgfs_escape,
>  	.get = lxc_cgroupfs_get,
>  	.set = lxc_cgroupfs_set,
>  	.unfreeze = cgfs_unfreeze,
> diff --git a/src/lxc/cgmanager.c b/src/lxc/cgmanager.c
> index 05df0da..04adc69 100644
> --- a/src/lxc/cgmanager.c
> +++ b/src/lxc/cgmanager.c
> @@ -312,13 +312,22 @@ static bool lxc_cgmanager_create(const char *controller, const char *cgroup_path
>   * be in "/lxc/c1" rather than "/user/..../c1"
>   * called internally with connection already open
>   */
> -static bool lxc_cgmanager_escape(void)
> +static bool cgm_escape(void)
>  {
> -	bool ret = true;
> +	bool ret = true, cgm_connected = false;

Sorry, can you rename this disconnect_cgm or cgm_needs_disconnect ?

Other than that,

Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.com>


>  	pid_t me = getpid();
>  	char **slist = subsystems;
>  	int i;
>  
> +	if (!cgroup_manager) {
> +		if (!cgm_dbus_connect()) {
> +			ERROR("Error connecting to cgroup manager");
> +			return false;
> +		}
> +		cgm_connected = true;
> +	}
> +
> +
>  	if (cgm_all_controllers_same)
>  		slist = subsystems_inone;
>  
> @@ -335,6 +344,9 @@ static bool lxc_cgmanager_escape(void)
>  		}
>  	}
>  
> +	if (cgm_connected)
> +		cgm_dbus_disconnect();
> +
>  	return ret;
>  }
>  
> @@ -1307,7 +1319,7 @@ struct cgroup_ops *cgm_ops_init(void)
>  		goto err1;
>  
>  	// root;  try to escape to root cgroup
> -	if (geteuid() == 0 && !lxc_cgmanager_escape())
> +	if (geteuid() == 0 && !cgm_escape())
>  		goto err2;
>  	cgm_dbus_disconnect();
>  
> @@ -1524,6 +1536,7 @@ static struct cgroup_ops cgmanager_ops = {
>  	.create_legacy = NULL,
>  	.get_cgroup = cgm_get_cgroup,
>  	.canonical_path = cgm_canonical_path,
> +	.escape = cgm_escape,
>  	.get = cgm_get,
>  	.set = cgm_set,
>  	.unfreeze = cgm_unfreeze,
> diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c
> index b1c764f..aeb8a58 100644
> --- a/src/lxc/cgroup.c
> +++ b/src/lxc/cgroup.c
> @@ -109,6 +109,13 @@ const char *cgroup_get_cgroup(struct lxc_handler *handler, const char *subsystem
>  	return NULL;
>  }
>  
> +bool cgroup_escape(void)
> +{
> +	if (ops)
> +		return ops->escape();
> +	return false;
> +}
> +
>  const char *cgroup_canonical_path(struct lxc_handler *handler)
>  {
>  	if (geteuid()) {
> diff --git a/src/lxc/cgroup.h b/src/lxc/cgroup.h
> index 7704c04..e3d3ce4 100644
> --- a/src/lxc/cgroup.h
> +++ b/src/lxc/cgroup.h
> @@ -47,6 +47,7 @@ struct cgroup_ops {
>  	bool (*create_legacy)(void *hdata, pid_t pid);
>  	const char *(*get_cgroup)(void *hdata, const char *subsystem);
>  	const char *(*canonical_path)(void *hdata);
> +	bool (*escape)(void);
>  	int (*set)(const char *filename, const char *value, const char *name, const char *lxcpath);
>  	int (*get)(const char *filename, char *value, size_t len, const char *name, const char *lxcpath);
>  	bool (*unfreeze)(void *hdata);
> @@ -71,6 +72,7 @@ extern void cgroup_cleanup(struct lxc_handler *handler);
>  extern bool cgroup_create_legacy(struct lxc_handler *handler);
>  extern int cgroup_nrtasks(struct lxc_handler *handler);
>  extern const char *cgroup_get_cgroup(struct lxc_handler *handler, const char *subsystem);
> +extern bool cgroup_escape(void);
>  
>  /*
>   * Currently, this call  only makes sense for privileged containers.
> -- 
> 2.6.2
> 
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel


More information about the lxc-devel mailing list