[lxc-devel] [lxc/master] cgroups: flatten hierarchy
brauner on Github
lxc-bot at linuxcontainers.org
Mon Dec 9 23:05:12 UTC 2019
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20191209/ffd576fb/attachment.bin>
-------------- next part --------------
From 1e7a32990b96f515bde3bcc4c6bc7cd7dfa5e83d Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 9 Dec 2019 23:14:37 +0100
Subject: [PATCH] cgroups: flatten hierarchy
Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
src/lxc/cgroups/cgfsng.c | 86 ++++++++++++++++++----------------------
src/lxc/cgroups/cgroup.h | 13 +++---
src/lxc/initutils.c | 2 +-
src/lxc/lsm/apparmor.c | 8 ++--
src/lxc/string_utils.c | 4 +-
src/lxc/string_utils.h | 2 +-
src/lxc/utils.h | 7 ----
7 files changed, 55 insertions(+), 67 deletions(-)
diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c
index 65e58b13ea..623720ac4f 100644
--- a/src/lxc/cgroups/cgfsng.c
+++ b/src/lxc/cgroups/cgfsng.c
@@ -1152,10 +1152,9 @@ __cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops,
for (int i = 0; ops->hierarchies[i]; i++) {
__do_free char *pivot_path = NULL;
- int ret;
- char *chop;
- char pivot_cgroup[] = PIVOT_CGROUP;
+ char pivot_cgroup[] = CGROUP_PIVOT;
struct hierarchy *h = ops->hierarchies[i];
+ int ret;
if (!h->monitor_full_path)
continue;
@@ -1164,20 +1163,14 @@ __cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops,
pivot_path = must_make_path(h->mountpoint,
h->container_base_path,
conf->cgroup_meta.dir,
- PIVOT_CGROUP,
- "cgroup.procs", NULL);
+ CGROUP_PIVOT, NULL);
else
pivot_path = must_make_path(h->mountpoint,
h->container_base_path,
- PIVOT_CGROUP,
- "cgroup.procs", NULL);
-
- chop = strrchr(pivot_path, '/');
- if (chop)
- *chop = '\0';
+ CGROUP_PIVOT, NULL);
/*
- * Make sure not to pass in the ro string literal PIVOT_CGROUP
+ * Make sure not to pass in the ro string literal CGROUP_PIVOT
* here.
*/
if (!cg_legacy_handle_cpuset_hierarchy(h, pivot_cgroup))
@@ -1190,13 +1183,11 @@ __cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops,
"Failed to create cgroup \"%s\"\n",
pivot_path);
- if (chop)
- *chop = '/';
-
- /* Move ourselves into the pivot cgroup to delete our own
+ /*
+ * Move ourselves into the pivot cgroup to delete our own
* cgroup.
*/
- ret = lxc_write_to_file(pivot_path, pidstr, len, false, 0666);
+ ret = lxc_write_openat(pivot_path, "cgroup.procs", pidstr, len);
if (ret != 0)
log_warn_errno(continue, errno,
"Failed to move monitor %s to \"%s\"\n",
@@ -1305,9 +1296,10 @@ __cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops,
struct lxc_handler *handler)
{
__do_free char *monitor_cgroup = NULL;
- char *offset, *tmp;
- int i, idx = 0;
+ int idx = 0;
+ int i;
size_t len;
+ char *suffix;
struct lxc_conf *conf;
if (!ops)
@@ -1325,24 +1317,22 @@ __cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops,
conf = handler->conf;
if (conf->cgroup_meta.dir)
- tmp = lxc_string_join("/",
- (const char *[]){conf->cgroup_meta.dir,
- ops->monitor_pattern,
- handler->name, NULL},
- false);
+ monitor_cgroup = must_concat(&len, conf->cgroup_meta.dir, "/",
+ DEFAULT_MONITOR_CGROUP_PREFIX,
+ handler->name,
+ CGROUP_CREATE_RETRY, NULL);
else
- tmp = must_make_path(ops->monitor_pattern, handler->name, NULL);
- if (!tmp)
+ monitor_cgroup = must_concat(&len, DEFAULT_MONITOR_CGROUP_PREFIX,
+ handler->name,
+ CGROUP_CREATE_RETRY, NULL);
+ if (!monitor_cgroup)
return ret_set_errno(false, ENOMEM);
- len = strlen(tmp) + 5; /* leave room for -NNN\0 */
- monitor_cgroup = must_realloc(tmp, len);
- offset = monitor_cgroup + len - 5;
- *offset = 0;
-
+ suffix = monitor_cgroup + len - CGROUP_CREATE_RETRY_LEN;
+ *suffix = '\0';
do {
if (idx)
- sprintf(offset, "-%d", idx);
+ sprintf(suffix, "-%d", idx);
for (i = 0; ops->hierarchies[i]; i++) {
if (!monitor_create_path_for_hierarchy(ops->hierarchies[i],
@@ -1373,11 +1363,11 @@ __cgfsng_ops static inline bool cgfsng_monitor_create(struct cgroup_ops *ops,
__cgfsng_ops static inline bool cgfsng_payload_create(struct cgroup_ops *ops,
struct lxc_handler *handler)
{
- __do_free char *container_cgroup = NULL, *tmp = NULL;
+ __do_free char *container_cgroup = NULL;
int idx = 0;
- int i, ret;
+ int i;
size_t len;
- char *offset;
+ char *suffix;
struct lxc_conf *conf;
if (!ops)
@@ -1395,21 +1385,22 @@ __cgfsng_ops static inline bool cgfsng_payload_create(struct cgroup_ops *ops,
conf = handler->conf;
if (conf->cgroup_meta.dir)
- tmp = lxc_string_join("/", (const char *[]){conf->cgroup_meta.dir, handler->name, NULL}, false);
+ container_cgroup = must_concat(&len, conf->cgroup_meta.dir, "/",
+ DEFAULT_PAYLOAD_CGROUP_PREFIX,
+ handler->name,
+ CGROUP_CREATE_RETRY, NULL);
else
- tmp = lxc_string_replace("%n", handler->name, ops->cgroup_pattern);
- if (!tmp)
- return log_error_errno(false, ENOMEM,
- "Failed expanding cgroup name pattern");
-
- len = strlen(tmp) + 5; /* leave room for -NNN\0 */
- container_cgroup = must_realloc(NULL, len);
- (void)strlcpy(container_cgroup, tmp, len);
- offset = container_cgroup + len - 5;
+ container_cgroup = must_concat(&len, DEFAULT_PAYLOAD_CGROUP_PREFIX,
+ handler->name,
+ CGROUP_CREATE_RETRY, NULL);
+ if (!container_cgroup)
+ return ret_set_errno(false, ENOMEM);
+ suffix = container_cgroup + len - CGROUP_CREATE_RETRY_LEN;
+ *suffix = '\0';
do {
if (idx)
- sprintf(offset, "-%d", idx);
+ sprintf(suffix, "-%d", idx);
for (i = 0; ops->hierarchies[i]; i++) {
if (!container_create_path_for_hierarchy(ops->hierarchies[i],
@@ -1433,6 +1424,8 @@ __cgfsng_ops static inline bool cgfsng_payload_create(struct cgroup_ops *ops,
ops->container_cgroup = move_ptr(container_cgroup);
if (ops->unified && ops->unified->container_full_path) {
+ int ret;
+
ret = open(ops->unified->container_full_path,
O_DIRECTORY | O_RDONLY | O_CLOEXEC);
if (ret < 0)
@@ -3300,7 +3293,6 @@ __cgfsng_ops static int cgfsng_data_init(struct cgroup_ops *ops)
return ret_set_errno(-1, ENOMEM);
}
ops->cgroup_pattern = must_copy_string(cgroup_pattern);
- ops->monitor_pattern = MONITOR_CGROUP;
return 0;
}
diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h
index dce506aa20..ea33223570 100644
--- a/src/lxc/cgroups/cgroup.h
+++ b/src/lxc/cgroups/cgroup.h
@@ -7,10 +7,14 @@
#include <stddef.h>
#include <sys/types.h>
+#include "macro.h"
+
#define DEFAULT_CGROUP_MOUNTPOINT "/sys/fs/cgroup"
-#define PAYLOAD_CGROUP "lxc.payload"
-#define MONITOR_CGROUP "lxc.monitor"
-#define PIVOT_CGROUP "lxc.pivot"
+#define DEFAULT_PAYLOAD_CGROUP_PREFIX "lxc.payload."
+#define DEFAULT_MONITOR_CGROUP_PREFIX "lxc.monitor."
+#define CGROUP_CREATE_RETRY "-NNNN"
+#define CGROUP_CREATE_RETRY_LEN STRLITERALLEN(CGROUP_CREATE_RETRY)
+#define CGROUP_PIVOT "lxc.pivot"
struct lxc_handler;
struct lxc_conf;
@@ -90,9 +94,6 @@ struct cgroup_ops {
char *container_cgroup;
char *monitor_cgroup;
- /* Static memory, do not free.*/
- const char *monitor_pattern;
-
/* @hierarchies
* - A NULL-terminated array of struct hierarchy, one per legacy
* hierarchy. No duplicates. First sufficient, writeable mounted
diff --git a/src/lxc/initutils.c b/src/lxc/initutils.c
index 9751954013..41ed9e9425 100644
--- a/src/lxc/initutils.c
+++ b/src/lxc/initutils.c
@@ -84,7 +84,7 @@ const char *lxc_global_config_value(const char *option_name)
sprintf(user_config_path, "%s/.config/lxc/lxc.conf", user_home);
sprintf(user_default_config_path, "%s/.config/lxc/default.conf", user_home);
sprintf(user_lxc_path, "%s/.local/share/lxc/", user_home);
- user_cgroup_pattern = strdup("lxc.payload/%n");
+ user_cgroup_pattern = strdup("%n");
}
else {
user_config_path = strdup(LXC_GLOBAL_CONF);
diff --git a/src/lxc/lsm/apparmor.c b/src/lxc/lsm/apparmor.c
index 33b3343cea..e34d999a19 100644
--- a/src/lxc/lsm/apparmor.c
+++ b/src/lxc/lsm/apparmor.c
@@ -510,7 +510,7 @@ static inline char *apparmor_dir(const char *ctname, const char *lxcpath)
static inline char *apparmor_profile_full(const char *ctname, const char *lxcpath)
{
- return shorten_apparmor_name(must_concat("lxc-", ctname, "_<", lxcpath, ">", NULL));
+ return shorten_apparmor_name(must_concat(NULL, "lxc-", ctname, "_<", lxcpath, ">", NULL));
}
/* Like apparmor_profile_full() but with slashes replaced by hyphens */
@@ -639,7 +639,7 @@ static char *get_apparmor_profile_content(struct lxc_conf *conf, const char *lxc
profile_name_full = apparmor_profile_full(conf->name, lxcpath);
- profile = must_concat(
+ profile = must_concat(NULL,
"#include <tunables/global>\n"
"profile \"", profile_name_full, "\" flags=(attach_disconnected,mediate_deleted) {\n",
NULL);
@@ -663,7 +663,7 @@ static char *get_apparmor_profile_content(struct lxc_conf *conf, const char *lxc
STRARRAYLEN(AA_PROFILE_STACKING_BASE));
namespace = apparmor_namespace(conf->name, lxcpath);
- temp = must_concat(" change_profile -> \":", namespace, ":*\",\n"
+ temp = must_concat(NULL, " change_profile -> \":", namespace, ":*\",\n"
" change_profile -> \":", namespace, "://*\",\n",
NULL);
free(namespace);
@@ -682,7 +682,7 @@ static char *get_apparmor_profile_content(struct lxc_conf *conf, const char *lxc
if (!aa_can_stack || aa_is_stacked) {
char *temp;
- temp = must_concat(" change_profile -> \"",
+ temp = must_concat(NULL, " change_profile -> \"",
profile_name_full, "\",\n", NULL);
must_append_sized(&profile, &size, temp, strlen(temp));
free(temp);
diff --git a/src/lxc/string_utils.c b/src/lxc/string_utils.c
index 4e8fc21811..dcb1160e4c 100644
--- a/src/lxc/string_utils.c
+++ b/src/lxc/string_utils.c
@@ -730,7 +730,7 @@ int lxc_safe_long_long(const char *numstr, long long int *converted)
return 0;
}
-char *must_concat(const char *first, ...)
+char *must_concat(size_t *len, const char *first, ...)
{
va_list args;
char *cur, *dest;
@@ -751,6 +751,8 @@ char *must_concat(const char *first, ...)
va_end(args);
dest[cur_len] = '\0';
+ if (len)
+ *len = cur_len;
return dest;
}
diff --git a/src/lxc/string_utils.h b/src/lxc/string_utils.h
index f55d9ee019..ec0c1acef7 100644
--- a/src/lxc/string_utils.h
+++ b/src/lxc/string_utils.h
@@ -79,7 +79,7 @@ extern int parse_byte_size_string(const char *s, int64_t *converted);
* Concatenate all passed-in strings into one path. Do not fail. If any piece
* is not prefixed with '/', add a '/'.
*/
-__attribute__((sentinel)) extern char *must_concat(const char *first, ...);
+__attribute__((sentinel)) extern char *must_concat(size_t *len, const char *first, ...);
__attribute__((sentinel)) extern char *must_make_path(const char *first, ...);
__attribute__((sentinel)) extern char *must_append_path(char *first, ...);
diff --git a/src/lxc/utils.h b/src/lxc/utils.h
index 2382038fea..5f07150dbc 100644
--- a/src/lxc/utils.h
+++ b/src/lxc/utils.h
@@ -199,13 +199,6 @@ extern int run_command(char *buf, size_t buf_size, int (*child_fn)(void *),
extern int run_command_status(char *buf, size_t buf_size, int (*child_fn)(void *),
void *args);
-/* Concatenate all passed-in strings into one path. Do not fail. If any piece
- * is not prefixed with '/', add a '/'.
- */
-__attribute__((sentinel)) extern char *must_concat(const char *first, ...);
-__attribute__((sentinel)) extern char *must_make_path(const char *first, ...);
-__attribute__((sentinel)) extern char *must_append_path(char *first, ...);
-
/* return copy of string @entry; do not fail. */
extern char *must_copy_string(const char *entry);
More information about the lxc-devel
mailing list