Projects
home:Eustace:branches:Eulaceura:Factory
lxc
_service:obs_scm:0013-ensure-cpuset-cgroup-buil...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:0013-ensure-cpuset-cgroup-built-while-writing-cgroup.proc.patch of Package lxc
From a17fa0f10ec2f0f0a19d080c2ffe258192fc6cc1 Mon Sep 17 00:00:00 2001 From: jikai <jikai11@huawei.com> Date: Mon, 5 Feb 2024 18:29:15 +0800 Subject: [PATCH] ensure cpuset cgroup built while writing cgroup.procs Signed-off-by: jikai <jikai11@huawei.com> --- src/lxc/cgroups/cgfsng.c | 433 +++++++++++++++++++++------------------ 1 file changed, 232 insertions(+), 201 deletions(-) diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index 5fd12ff..984e969 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -535,6 +535,207 @@ static int cgroup_tree_remove_wrapper(void *data) return cgroup_tree_remove(arg->hierarchies, arg->path_prune); } +#ifdef HAVE_ISULAD +#define BATCH_SIZE 50 +static void batch_realloc(char **mem, size_t oldlen, size_t newlen) +{ + int newbatches = (newlen / BATCH_SIZE) + 1; + int oldbatches = (oldlen / BATCH_SIZE) + 1; + + if (!*mem || newbatches > oldbatches) + *mem = must_realloc(*mem, newbatches * BATCH_SIZE); +} + +static void append_line(char **dest, size_t oldlen, char *new, size_t newlen) +{ + size_t full = oldlen + newlen; + + batch_realloc(dest, oldlen, full + 1); + + memcpy(*dest + oldlen, new, newlen + 1); +} + +/* Slurp in a whole file */ +static char *read_file(const char *fnam) +{ + __do_free char *buf = NULL, *line = NULL; + __do_fclose FILE *f = NULL; + size_t len = 0, fulllen = 0; + int linelen; + + f = fopen(fnam, "re"); + if (!f) + return NULL; + + while ((linelen = getline(&line, &len, f)) != -1) { + append_line(&buf, fulllen, line, linelen); + fulllen += linelen; + } + + return move_ptr(buf); +} + +static bool isulad_copy_parent_file(char *path, char *file) +{ + int ret; + int len = 0; + char *value = NULL; + char *current = NULL; + char *fpath = NULL; + char *lastslash = NULL; + char oldv; + + fpath = must_make_path(path, file, NULL); + current = read_file(fpath); + + if (current == NULL) { + SYSERROR("Failed to read file \"%s\"", fpath); + free(fpath); + return false; + } + + if (strcmp(current, "\n") != 0) { + free(fpath); + free(current); + return true; + } + + free(fpath); + free(current); + + lastslash = strrchr(path, '/'); + if (lastslash == NULL) { + ERROR("Failed to detect \"/\" in \"%s\"", path); + return false; + } + oldv = *lastslash; + *lastslash = '\0'; + fpath = must_make_path(path, file, NULL); + *lastslash = oldv; + len = lxc_read_from_file(fpath, NULL, 0); + if (len <= 0) + goto on_error; + + value = must_realloc(NULL, len + 1); + ret = lxc_read_from_file(fpath, value, len); + if (ret != len) + goto on_error; + free(fpath); + + fpath = must_make_path(path, file, NULL); + ret = lxc_write_to_file(fpath, value, len, false, 0666); + if (ret < 0) + SYSERROR("Failed to write \"%s\" to file \"%s\"", value, fpath); + free(fpath); + free(value); + return ret >= 0; + +on_error: + SYSERROR("Failed to read file \"%s\"", fpath); + free(fpath); + free(value); + return false; +} + +static bool build_sub_cpuset_cgroup_dir(char *cgpath) +{ + int ret; + + ret = mkdir_p(cgpath, 0755); + if (ret < 0) { + if (errno != EEXIST) { + SYSERROR("Failed to create directory \"%s\"", cgpath); + return false; + } + } + + /* copy parent's settings */ + if (!isulad_copy_parent_file(cgpath, "cpuset.cpus")) { + SYSERROR("Failed to copy \"cpuset.cpus\" settings"); + return false; + } + + /* copy parent's settings */ + if (!isulad_copy_parent_file(cgpath, "cpuset.mems")) { + SYSERROR("Failed to copy \"cpuset.mems\" settings"); + return false; + } + + return true; +} + +static bool isulad_cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) +{ + char *cgpath, *slash; + bool sub_mk_success = false; + + if (is_unified_hierarchy(h)) + return true; + + if (!string_in_list(h->controllers, "cpuset")) + return true; + + slash = strchr(cgname, '/'); + + if (slash != NULL) { + while (slash) { + *slash = '\0'; + cgpath = make_cgroup_path(h, h->at_base, cgname, NULL); + sub_mk_success = build_sub_cpuset_cgroup_dir(cgpath); + free(cgpath); + *slash = '/'; + if (!sub_mk_success) { + return false; + } + slash = strchr(slash + 1, '/'); + } + } + + cgpath = make_cgroup_path(h, h->at_base, cgname, NULL); + sub_mk_success = build_sub_cpuset_cgroup_dir(cgpath); + free(cgpath); + if (!sub_mk_success) { + return false; + } + + return true; +} + +static int isulad_mkdir_eexist_on_last(const char *dir, mode_t mode) +{ + const char *tmp = dir; + const char *orig = dir; + + do { + int ret; + size_t cur_len; + char *makeme; + + dir = tmp + strspn(tmp, "/"); + tmp = dir + strcspn(dir, "/"); + + errno = ENOMEM; + cur_len = dir - orig; + makeme = strndup(orig, cur_len); + if (!makeme) + return -1; + + ret = mkdir(makeme, mode); + if (ret < 0) { + if (errno != EEXIST) { + SYSERROR("Failed to create directory \"%s\"", makeme); + free(makeme); + return -1; + } + } + free(makeme); + + } while (tmp != dir); + + return 0; +} +#endif + #ifdef HAVE_ISULAD __cgfsng_ops static bool cgfsng_payload_destroy(struct cgroup_ops *ops, struct lxc_handler *handler) @@ -806,6 +1007,18 @@ static bool cgroup_tree_create(struct cgroup_ops *ops, struct lxc_conf *conf, */ cpuset_v1 = !is_unified_hierarchy(h) && string_in_list(h->controllers, "cpuset"); +#ifdef HAVE_ISULAD + /* ensure that cpuset cgroup was set in the whole cgroup path, though lxc does + * cpuset1_initialize(set cgroup.clone_children to 1 and cpuset.cpus and cpuset.mems) + * but it only does so for the first layer of the cgroup path. + * Since K8S could create the path already, so we need to ensure the cpuset cgroup was set + */ + if (cpuset_v1 && !isulad_cg_legacy_handle_cpuset_hierarchy(h, ops->container_cgroup)) { + ERROR("Failed to handle legacy cpuset controller"); + return false; + } +#endif + if (payload && cgroup_leaf) { /* With isolation both parts need to not already exist. */ fd_limit = __cgroup_tree_create(h->dfd_base, cgroup_limit_dir, 0755, cpuset_v1, false); @@ -1662,14 +1875,33 @@ __cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops, for (int i = 0; ops->hierarchies[i]; i++) { struct hierarchy *h = ops->hierarchies[i]; int ret; +#ifdef HAVE_ISULAD + int retry_count = 0; + int max_retry = 10; +#endif if (is_unified_hierarchy(h) && (handler->clone_flags & CLONE_INTO_CGROUP)) continue; +#ifdef HAVE_ISULAD +retry: + ret = lxc_writeat(h->dfd_con, "cgroup.procs", pidstr, len); + if (ret != 0) { + if (retry_count < max_retry) { + SYSERROR("Failed to enter cgroup \"%s/cgroup.procs\" with retry count:%d", h->path_con, retry_count); + (void)isulad_cg_legacy_handle_cpuset_hierarchy(h, ops->container_cgroup); + (void)isulad_mkdir_eexist_on_last(h->path_con, 0755); + usleep(100 * 1000); + retry_count++; + goto retry; + } + } +#else ret = lxc_writeat(h->dfd_con, "cgroup.procs", pidstr, len); if (ret != 0) return log_error_errno(false, errno, "Failed to enter cgroup \"%s\"", h->path_con); +#endif TRACE("Moved container into %s cgroup via %d", h->path_con, h->dfd_con); } @@ -3234,207 +3466,6 @@ static int convert_devpath(const char *invalue, char *dest) return 0; } -#ifdef HAVE_ISULAD -#define BATCH_SIZE 50 -static void batch_realloc(char **mem, size_t oldlen, size_t newlen) -{ - int newbatches = (newlen / BATCH_SIZE) + 1; - int oldbatches = (oldlen / BATCH_SIZE) + 1; - - if (!*mem || newbatches > oldbatches) - *mem = must_realloc(*mem, newbatches * BATCH_SIZE); -} - -static void append_line(char **dest, size_t oldlen, char *new, size_t newlen) -{ - size_t full = oldlen + newlen; - - batch_realloc(dest, oldlen, full + 1); - - memcpy(*dest + oldlen, new, newlen + 1); -} - -/* Slurp in a whole file */ -static char *read_file(const char *fnam) -{ - __do_free char *buf = NULL, *line = NULL; - __do_fclose FILE *f = NULL; - size_t len = 0, fulllen = 0; - int linelen; - - f = fopen(fnam, "re"); - if (!f) - return NULL; - - while ((linelen = getline(&line, &len, f)) != -1) { - append_line(&buf, fulllen, line, linelen); - fulllen += linelen; - } - - return move_ptr(buf); -} - -static bool isulad_copy_parent_file(char *path, char *file) -{ - int ret; - int len = 0; - char *value = NULL; - char *current = NULL; - char *fpath = NULL; - char *lastslash = NULL; - char oldv; - - fpath = must_make_path(path, file, NULL); - current = read_file(fpath); - - if (current == NULL) { - SYSERROR("Failed to read file \"%s\"", fpath); - free(fpath); - return false; - } - - if (strcmp(current, "\n") != 0) { - free(fpath); - free(current); - return true; - } - - free(fpath); - free(current); - - lastslash = strrchr(path, '/'); - if (lastslash == NULL) { - ERROR("Failed to detect \"/\" in \"%s\"", path); - return false; - } - oldv = *lastslash; - *lastslash = '\0'; - fpath = must_make_path(path, file, NULL); - *lastslash = oldv; - len = lxc_read_from_file(fpath, NULL, 0); - if (len <= 0) - goto on_error; - - value = must_realloc(NULL, len + 1); - ret = lxc_read_from_file(fpath, value, len); - if (ret != len) - goto on_error; - free(fpath); - - fpath = must_make_path(path, file, NULL); - ret = lxc_write_to_file(fpath, value, len, false, 0666); - if (ret < 0) - SYSERROR("Failed to write \"%s\" to file \"%s\"", value, fpath); - free(fpath); - free(value); - return ret >= 0; - -on_error: - SYSERROR("Failed to read file \"%s\"", fpath); - free(fpath); - free(value); - return false; -} - -static bool build_sub_cpuset_cgroup_dir(char *cgpath) -{ - int ret; - - ret = mkdir_p(cgpath, 0755); - if (ret < 0) { - if (errno != EEXIST) { - SYSERROR("Failed to create directory \"%s\"", cgpath); - return false; - } - } - - /* copy parent's settings */ - if (!isulad_copy_parent_file(cgpath, "cpuset.cpus")) { - SYSERROR("Failed to copy \"cpuset.cpus\" settings"); - return false; - } - - /* copy parent's settings */ - if (!isulad_copy_parent_file(cgpath, "cpuset.mems")) { - SYSERROR("Failed to copy \"cpuset.mems\" settings"); - return false; - } - - return true; -} - -static bool isulad_cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) -{ - char *cgpath, *slash; - bool sub_mk_success = false; - - if (is_unified_hierarchy(h)) - return true; - - if (!string_in_list(h->controllers, "cpuset")) - return true; - - slash = strchr(cgname, '/'); - - if (slash != NULL) { - while (slash) { - *slash = '\0'; - cgpath = must_make_path(h->at_mnt, h->at_base, cgname, NULL); - sub_mk_success = build_sub_cpuset_cgroup_dir(cgpath); - free(cgpath); - *slash = '/'; - if (!sub_mk_success) { - return false; - } - slash = strchr(slash + 1, '/'); - } - } - - cgpath = must_make_path(h->at_mnt, h->at_base, cgname, NULL); - sub_mk_success = build_sub_cpuset_cgroup_dir(cgpath); - free(cgpath); - if (!sub_mk_success) { - return false; - } - - return true; -} - -static int isulad_mkdir_eexist_on_last(const char *dir, mode_t mode) -{ - const char *tmp = dir; - const char *orig = dir; - - do { - int ret; - size_t cur_len; - char *makeme; - - dir = tmp + strspn(tmp, "/"); - tmp = dir + strcspn(dir, "/"); - - errno = ENOMEM; - cur_len = dir - orig; - makeme = strndup(orig, cur_len); - if (!makeme) - return -1; - - ret = mkdir(makeme, mode); - if (ret < 0) { - if (errno != EEXIST) { - SYSERROR("Failed to create directory \"%s\"", makeme); - free(makeme); - return -1; - } - } - free(makeme); - - } while (tmp != dir); - - return 0; -} -#endif - /* Called from setup_limits - here we have the container's cgroup_data because * we created the cgroups. */ -- 2.33.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2