1 Star 0 Fork 44

jake/lxc

forked from src-openEuler/lxc 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0013-ensure-cpuset-cgroup-built-while-writing-cgroup.proc.patch 11.31 KB
一键复制 编辑 原始数据 按行查看 历史
From a17fa0f10ec2f0f0a19d080c2ffe258192fc6cc1 Mon Sep 17 00:00:00 2001
From: jikai <[email protected]>
Date: Mon, 5 Feb 2024 18:29:15 +0800
Subject: [PATCH] ensure cpuset cgroup built while writing cgroup.procs
Signed-off-by: jikai <[email protected]>
---
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
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/jikai11/lxc.git
[email protected]:jikai11/lxc.git
jikai11
lxc
lxc
master

搜索帮助