Projects
home:Eustace:branches:Eulaceura:Factory
lxc
_service:obs_scm:0007-fix-run-container-failed-...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:0007-fix-run-container-failed-when-enable-isulad.patch of Package lxc
From d743d299c37b71d0990d0a68ad492a0ec76a7886 Mon Sep 17 00:00:00 2001 From: zhangxiaoyu <zhangxiaoyu58@huawei.com> Date: Wed, 18 Oct 2023 11:01:49 +0800 Subject: [PATCH] fix run container failed when enable isulad Signed-off-by: zhangxiaoyu <zhangxiaoyu58@huawei.com> --- src/lxc/attach.c | 11 +- src/lxc/cgroups/cgfsng.c | 581 +++++++++++++++++++++++++++++++++++++++ src/lxc/cgroups/cgroup.h | 4 + src/lxc/conf.c | 17 +- src/lxc/confile.c | 34 ++- src/lxc/meson.build | 4 +- src/lxc/start.c | 11 +- 7 files changed, 628 insertions(+), 34 deletions(-) diff --git a/src/lxc/attach.c b/src/lxc/attach.c index 066eb5c..ae12da3 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c @@ -1454,18 +1454,17 @@ __noreturn static void do_attach(struct attach_payload *ap) goto on_error; } } else { -#else - ret = lxc_terminal_prepare_login(ap->terminal_pts_fd); -#endif -#ifdef HAVE_ISULAD - } #endif + ret = lxc_terminal_prepare_login(ap->terminal_pts_fd); if (ret < 0) { SYSERROR("Failed to prepare terminal file descriptor %d", ap->terminal_pts_fd); goto on_error; } TRACE("Prepared terminal file descriptor %d", ap->terminal_pts_fd); +#ifdef HAVE_ISULAD + } +#endif } /* Avoid unnecessary syscalls. */ @@ -2264,7 +2263,7 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, if (options->attach_flags & LXC_ATTACH_TERMINAL) { #ifdef HAVE_ISULAD - ret = isulad_safe_mainloop(&descr, -1); + ret = isulad_safe_mainloop(&descr, -1); #else ret = lxc_mainloop(&descr, -1); #endif diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index 4e4ae0c..0aaafa8 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -528,32 +528,64 @@ static int cgroup_tree_remove_wrapper(void *data) return cgroup_tree_remove(arg->hierarchies, arg->path_prune); } +#ifdef HAVE_ISULAD +__cgfsng_ops static bool cgfsng_payload_destroy(struct cgroup_ops *ops, + struct lxc_handler *handler) +#else __cgfsng_ops static void cgfsng_payload_destroy(struct cgroup_ops *ops, struct lxc_handler *handler) +#endif { int ret; if (!ops) { ERROR("Called with uninitialized cgroup operations"); +#ifdef HAVE_ISULAD + return false; +#else return; +#endif + } + +#ifdef HAVE_ISULAD + if (ops->no_controller) { + DEBUG("no controller found, ignore isulad_cgfsng_payload_destroy"); + return true; } +#endif if (!ops->hierarchies) +#ifdef HAVE_ISULAD + return true; +#else return; +#endif if (!handler) { ERROR("Called with uninitialized handler"); +#ifdef HAVE_ISULAD + return false; +#else return; +#endif } if (!handler->conf) { ERROR("Called with uninitialized conf"); +#ifdef HAVE_ISULAD + return false; +#else return; +#endif } if (!ops->container_limit_cgroup) { WARN("Uninitialized limit cgroup"); +#ifdef HAVE_ISULAD + return true; +#else return; +#endif } ret = bpf_program_cgroup_detach(handler->cgroup_ops->cgroup2_devices); @@ -579,6 +611,9 @@ __cgfsng_ops static void cgfsng_payload_destroy(struct cgroup_ops *ops, } if (ret < 0) SYSWARN("Failed to destroy cgroups"); +#ifdef HAVE_ISULAD + return ret >= 0; +#endif } #define __ISOL_CPUS "/sys/devices/system/cpu/isolated" @@ -854,6 +889,10 @@ static void cgroup_tree_prune_leaf(struct hierarchy *h, const char *path_prune, __cgfsng_ops static void cgfsng_monitor_destroy(struct cgroup_ops *ops, struct lxc_handler *handler) { +#ifdef HAVE_ISULAD + // ignore destroy monitor cgroup + return; +#endif int len; char pidstr[INTTYPE_TO_STRLEN(pid_t)]; const struct lxc_conf *conf; @@ -1311,6 +1350,10 @@ static char *cgroup_relpath(char *cg) __cgfsng_ops static bool cgfsng_monitor_create(struct cgroup_ops *ops, struct lxc_handler *handler) { +#ifdef HAVE_ISULAD + // skip create monitor cgroup + return true; +#endif __do_free char *monitor_cgroup = NULL; int idx = 0; int i; @@ -1411,6 +1454,17 @@ __cgfsng_ops static bool cgfsng_payload_create(struct cgroup_ops *ops, struct lx if (!ops->hierarchies) return true; +#ifdef HAVE_ISULAD + if (ops->no_controller) { + DEBUG("no controller found, isgnore isulad_cgfsng_payload_create"); + return true; + } + if (ops->container_cgroup) { + free(ops->container_cgroup); + ops->container_cgroup = NULL; + } +#endif + if (ops->container_cgroup || ops->container_limit_cgroup) return ret_set_errno(false, EEXIST); @@ -1504,6 +1558,10 @@ __cgfsng_ops static bool cgfsng_payload_create(struct cgroup_ops *ops, struct lx __cgfsng_ops static bool cgfsng_monitor_enter(struct cgroup_ops *ops, struct lxc_handler *handler) { +#ifdef HAVE_ISULAD + // ignore enter monitor cgroup + return true; +#endif int monitor_len, transient_len = 0; char monitor[INTTYPE_TO_STRLEN(pid_t)], transient[INTTYPE_TO_STRLEN(pid_t)]; @@ -1577,6 +1635,13 @@ __cgfsng_ops static bool cgfsng_payload_enter(struct cgroup_ops *ops, if (!ops) return ret_set_errno(false, ENOENT); +#ifdef HAVE_ISULAD + if (ops->no_controller) { + DEBUG("no controller found, isgnore isulad_cgfsng_payload_enter"); + return true; + } +#endif + if (!ops->hierarchies) return true; @@ -1728,6 +1793,13 @@ __cgfsng_ops static void cgfsng_finalize(struct cgroup_ops *ops) if (!ops) return; +#ifdef HAVE_ISULAD + if (ops->no_controller) { + DEBUG("no controller found, isgnore isulad_cgfsng_payload_finalize"); + return; + } +#endif + if (!ops->hierarchies) return; @@ -1900,7 +1972,11 @@ static int __cgroupfs_mount(int cgroup_automount_type, struct hierarchy *h, return log_error_errno(-EINVAL, EINVAL, "Unsupported mount properties specified"); target = must_make_path(rootfs_mnt, DEFAULT_CGROUP_MOUNTPOINT, hierarchy_mnt, NULL); +#ifdef HAVE_ISULAD + ret = safe_mount(NULL, target, fstype, old_flags, controllers, rootfs_mnt, NULL); +#else ret = safe_mount(NULL, target, fstype, old_flags, controllers, rootfs_mnt); +#endif } if (ret < 0) return log_error_errno(ret, errno, "Failed to mount %s filesystem onto %d(%s)", @@ -1950,6 +2026,9 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, struct lxc_rootfs *rootfs = &conf->rootfs; const char *rootfs_mnt = get_rootfs_mnt(rootfs); int ret; +#ifdef HAVE_ISULAD + __do_free_string_list char **merged = NULL; +#endif if (!ops) return ret_set_errno(false, ENOENT); @@ -2116,9 +2195,15 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, MOUNT_ATTR_NOEXEC | MOUNT_ATTR_RELATIME); } else { cgroup_root = must_make_path(rootfs_mnt, DEFAULT_CGROUP_MOUNTPOINT, NULL); +#ifdef HAVE_ISULAD + ret = safe_mount(NULL, cgroup_root, "tmpfs", + MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME, + "size=10240k,mode=755", rootfs_mnt, NULL); +#else ret = safe_mount(NULL, cgroup_root, "tmpfs", MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME, "size=10240k,mode=755", rootfs_mnt); +#endif } if (ret < 0) return log_error_errno(false, errno, "Failed to mount tmpfs on %s", @@ -2134,6 +2219,16 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, __do_free char *hierarchy_mnt = NULL, *path2 = NULL; struct hierarchy *h = ops->hierarchies[i]; +#ifdef HAVE_ISULAD + // isulad: symlink subcgroup + if (strchr(h->at_mnt, ',') != NULL) { + int pret; + pret = lxc_append_string(&merged, h->at_mnt); + if (pret < 0) + return false; + } +#endif + ret = mkdirat(dfd_mnt_tmpfs, h->at_mnt, 0000); if (ret < 0) return syserror_ret(false, "Failed to create cgroup at_mnt %d(%s)", dfd_mnt_tmpfs, h->at_mnt); @@ -2165,8 +2260,14 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, cgroup_root = must_make_path(rootfs_mnt, DEFAULT_CGROUP_MOUNTPOINT, NULL); hierarchy_mnt = must_make_path(cgroup_root, h->at_mnt, NULL); +#ifdef HAVE_ISULAD + // isulad: ignore ops->container_cgroup so we will not see directory lxc after /sys/fs/cgroup/xxx in container, + // isulad: ignore h->container_base_path so we will not see subgroup of /sys/fs/cgroup/xxx/subgroup in container + path2 = must_make_path(h->at_mnt, NULL); +#else path2 = must_make_path(hierarchy_mnt, h->at_base, ops->container_cgroup, NULL); +#endif ret = mkdir_p(path2, 0755); if (ret < 0 && (errno != EEXIST)) return false; @@ -2178,6 +2279,64 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, return false; } + +#ifdef HAVE_ISULAD + // isulad: symlink subcgroup + // create symlink if no merged cgroup link + // like cpu -> cpu,cpuacct + if (merged) { + char **mc = NULL; + for (mc = merged; *mc; mc++) { + char *token = NULL; + __do_free char *copy = must_copy_string(*mc); + lxc_iterate_parts(token, copy, ",") { + int mret; + __do_free char *link = must_make_path(cgroup_root, token, NULL); + mret = symlink(*mc, link); + if (mret < 0 && errno != EEXIST) { + SYSERROR("Failed to create link %s for target %s", link, *mc); + return false; + } + } + } + } + + // isulad: remount /sys/fs/cgroup to readonly + if (cg_flags == LXC_AUTO_CGROUP_FULL_RO || cg_flags == LXC_AUTO_CGROUP_RO) { + ret = mount(cgroup_root, cgroup_root, "bind", + MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_RELATIME|MS_RDONLY|MS_BIND|MS_REMOUNT, NULL); + if (ret < 0) { + SYSERROR("Failed to remount /sys/fs/cgroup."); + return false; + } + } + + // isulad: remount /sys/fs/cgroup/systemd to readwrite for system container + if (handler->conf->systemd != NULL && strcmp(handler->conf->systemd, "true") == 0) { + __do_free char *systemdpath = NULL; + __do_free char *unifiedpath = NULL; + unifiedpath = must_make_path(get_rootfs_mnt(rootfs), "/sys/fs/cgroup/unified", NULL); + if (dir_exists(unifiedpath)) + { + ret = umount2(unifiedpath, MNT_DETACH); + if (ret < 0) + { + SYSERROR("Failed to umount /sys/fs/cgroup/unified."); + return false; + } + } + + systemdpath = must_make_path(get_rootfs_mnt(rootfs), "/sys/fs/cgroup/systemd", NULL); + ret = mount(systemdpath, systemdpath, "bind", + MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME | MS_BIND | MS_REMOUNT, NULL); + if (ret < 0) + { + SYSERROR("Failed to remount /sys/fs/cgroup/systemd."); + return false; + } + } +#endif + return true; } @@ -2724,6 +2883,13 @@ __cgfsng_ops static bool cgfsng_attach(struct cgroup_ops *ops, if (!ops) return ret_set_errno(false, ENOENT); +#ifdef HAVE_ISULAD + if (ops->no_controller) { + DEBUG("no controller found, isgnore isulad_cgfsng_attach"); + return true; + } +#endif + if (!ops->hierarchies) return true; @@ -3064,6 +3230,209 @@ 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; + + cgname += strspn(cgname, "/"); + + 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. */ @@ -3075,6 +3444,13 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, /* "b|c <2^64-1>:<2^64-1> r|w|m" = 47 chars max */ char converted_value[50]; struct hierarchy *h; +#ifdef HAVE_ISULAD + int nret = 0; + int retry_count = 0; + int max_retry = 10; + char *fullpath; + char *container_cgroup = ops->container_cgroup; +#endif controller = strdup(filename); if (!controller) @@ -3097,6 +3473,27 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, if (!h) return log_error_errno(-ENOENT, ENOENT, "Failed to setup limits for the \"%s\" controller. The controller seems to be unused by \"cgfsng\" cgroup driver or not enabled on the cgroup hierarchy", controller); +#ifdef HAVE_ISULAD + fullpath = must_make_path(h->path_con, filename, NULL); +retry: + nret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666); + if (nret != 0) { + if (retry_count < max_retry) { + SYSERROR("setting cgroup config for ready process caused \"failed to write %s to %s\".", value, fullpath); + (void)isulad_cg_legacy_handle_cpuset_hierarchy(h, container_cgroup); + (void)isulad_mkdir_eexist_on_last(h->path_con, 0755); + usleep(100 * 1000); /* 100 millisecond */ + retry_count++; + goto retry; + } + lxc_write_error_message(ops->errfd, + "%s:%d: setting cgroup config for ready process caused failed to write %s to %s: %s", + __FILE__, __LINE__, value, fullpath, strerror(errno)); + } + free(fullpath); + return nret; +#endif + if (is_cpuset) { int ret = lxc_write_openat(h->path_con, filename, value, strlen(value)); if (ret) @@ -3131,12 +3528,76 @@ static void sort_cgroup_settings(struct lxc_conf *conf) } +#ifdef HAVE_ISULAD +/* Called from setup_limits - here we have the container's cgroup_data because + * we created the cgroups. + */ +static int isulad_cg_legacy_get_data(struct cgroup_ops *ops, const char *filename, + char *value, size_t len) +{ + char *fullpath = NULL; + char *p = NULL; + struct hierarchy *h = NULL; + int ret = 0; + char *controller = NULL; + + len = strlen(filename); + if (SIZE_MAX - 1 < len) { + errno = EINVAL; + return -1; + } + controller = calloc(1, len + 1); + if (controller == NULL) { + errno = ENOMEM; + return -1; + } + (void)strlcpy(controller, filename, len + 1); + + p = strchr(controller, '.'); + if (p) + *p = '\0'; + + + h = get_hierarchy(ops, controller); + if (!h) { + ERROR("Failed to setup limits for the \"%s\" controller. " + "The controller seems to be unused by \"cgfsng\" cgroup " + "driver or not enabled on the cgroup hierarchy", + controller); + errno = ENOENT; + free(controller); + return -ENOENT; + } + + fullpath = must_make_path(h->path_con, filename, NULL); + ret = lxc_read_from_file(fullpath, value, len); + free(fullpath); + free(controller); + return ret; +} + +static char *trim(char *s) +{ + size_t len; + + len = strlen(s); + while ((len > 1) && (s[len - 1] == '\n')) + s[--len] = '\0'; + + return s; +} +#endif + __cgfsng_ops static bool cgfsng_setup_limits_legacy(struct cgroup_ops *ops, struct lxc_conf *conf, bool do_devices) { struct list_head *cgroup_settings; struct lxc_cgroup *cgroup; +#ifdef HAVE_ISULAD + char value[21 + 1] = { 0 }; + long long int readvalue, setvalue; +#endif if (!ops) return ret_set_errno(false, ENOENT); @@ -3157,6 +3618,27 @@ __cgfsng_ops static bool cgfsng_setup_limits_legacy(struct cgroup_ops *ops, sort_cgroup_settings(conf); list_for_each_entry(cgroup, cgroup_settings, head) { if (do_devices == strnequal("devices", cgroup->subsystem, 7)) { +#ifdef HAVE_ISULAD + const char *cgvalue = cgroup->value; + if (strcmp("files.limit", cgroup->subsystem) == 0) { + if (lxc_safe_long_long(cgvalue, &setvalue) != 0) { + SYSERROR("Invalid integer value %s", cgvalue); + return false; + } + if (setvalue <= 0) { + cgvalue = "max"; + } + } + if (cg_legacy_set_data(ops, cgroup->subsystem, cgvalue, strnequal("cpuset", cgroup->subsystem, 6))) { + if (do_devices && (errno == EACCES || errno == EPERM)) { + SYSWARN("Failed to set \"%s\" to \"%s\"", cgroup->subsystem, cgvalue); + continue; + } + SYSERROR("Failed to set \"%s\" to \"%s\"", cgroup->subsystem, cgvalue); + return false; + } + DEBUG("Set controller \"%s\" set to \"%s\"", cgroup->subsystem, cgvalue); +#else if (cg_legacy_set_data(ops, cgroup->subsystem, cgroup->value, strnequal("cpuset", cgroup->subsystem, 6))) { if (do_devices && (errno == EACCES || errno == EPERM)) { SYSWARN("Failed to set \"%s\" to \"%s\"", cgroup->subsystem, cgroup->value); @@ -3166,7 +3648,40 @@ __cgfsng_ops static bool cgfsng_setup_limits_legacy(struct cgroup_ops *ops, return false; } DEBUG("Set controller \"%s\" set to \"%s\"", cgroup->subsystem, cgroup->value); +#endif } + +#ifdef HAVE_ISULAD + // isulad: check cpu shares + if (strcmp(cgroup->subsystem, "cpu.shares") == 0) { + if (isulad_cg_legacy_get_data(ops, cgroup->subsystem, value, sizeof(value) - 1) < 0) { + SYSERROR("Error get %s", cgroup->subsystem); + return false; + } + trim(value); + if (lxc_safe_long_long(cgroup->value, &setvalue) != 0) { + SYSERROR("Invalid value %s", cgroup->value); + return false; + } + if (lxc_safe_long_long(value, &readvalue) != 0) { + SYSERROR("Invalid value %s", value); + return false; + } + if (setvalue > readvalue) { + ERROR("The maximum allowed cpu-shares is %s", value); + lxc_write_error_message(ops->errfd, + "%s:%d: setting cgroup config for ready process caused \"The maximum allowed cpu-shares is %s\".", + __FILE__, __LINE__, value); + return false; + } else if (setvalue < readvalue) { + ERROR("The minimum allowed cpu-shares is %s", value); + lxc_write_error_message(ops->errfd, + "%s:%d: setting cgroup config for ready process caused \"The minimum allowed cpu-shares is %s\".", + __FILE__, __LINE__, value); + return false; + } + } +#endif } INFO("Limits for the legacy cgroup hierarchies have been setup"); @@ -3359,6 +3874,10 @@ static bool __cgfsng_delegate_controllers(struct cgroup_ops *ops, const char *cg __cgfsng_ops static bool cgfsng_monitor_delegate_controllers(struct cgroup_ops *ops) { +#ifdef HAVE_ISULAD + // ignore monitor cgroup delegate controllers + return true; +#endif if (!ops) return ret_set_errno(false, ENOENT); @@ -3370,6 +3889,13 @@ __cgfsng_ops static bool cgfsng_payload_delegate_controllers(struct cgroup_ops * if (!ops) return ret_set_errno(false, ENOENT); +#ifdef HAVE_ISULAD + if (ops->no_controller) { + DEBUG("no controller found, isgnore isulad_cgfsng_payload_delegate_controllers"); + return true; + } +#endif + return __cgfsng_delegate_controllers(ops, ops->container_cgroup); } @@ -3635,7 +4161,9 @@ static int __initialize_cgroups(struct cgroup_ops *ops, bool relative, if (!controller_list) { TRACE("No controllers are enabled for delegation in the unified hierarchy"); #ifdef HAVE_ISULAD + if (fhas_fs_type(ops->dfd_mnt, CGROUP2_SUPER_MAGIC)) { ops->no_controller = true; + } #endif controller_list = list_new(); if (!controller_list) @@ -3839,9 +4367,18 @@ static int initialize_cgroups(struct cgroup_ops *ops, struct lxc_conf *conf) return 0; } +#ifdef HAVE_ISULAD +__cgfsng_ops static int cgfsng_data_init(struct cgroup_ops *ops, struct lxc_conf *conf) +#else __cgfsng_ops static int cgfsng_data_init(struct cgroup_ops *ops) +#endif { const char *cgroup_pattern; +#ifdef HAVE_ISULAD + const char *cgroup_tree; + __do_free char *container_cgroup = NULL, *__cgroup_tree = NULL; + size_t len; +#endif if (!ops) return ret_set_errno(-1, ENOENT); @@ -3854,9 +4391,48 @@ __cgfsng_ops static int cgfsng_data_init(struct cgroup_ops *ops) return ret_errno(ENOMEM); } +#ifdef HAVE_ISULAD + if (conf->cgroup_meta.dir) { + cgroup_tree = conf->cgroup_meta.dir; + container_cgroup = must_concat(&len, cgroup_tree, "/", conf->name, NULL); + } else if (ops->cgroup_pattern) { + __cgroup_tree = lxc_string_replace("%n", conf->name, ops->cgroup_pattern); + if (!__cgroup_tree) + return ret_set_errno(-1, ENOMEM); + + cgroup_tree = __cgroup_tree; + container_cgroup = must_concat(&len, cgroup_tree, NULL); + } else { + cgroup_tree = NULL; + container_cgroup = must_concat(&len, conf->name, NULL); + } + if (!container_cgroup) + return ret_set_errno(-1, ENOMEM); + + ops->container_cgroup = move_ptr(container_cgroup); +#endif + return 0; } +#ifdef HAVE_ISULAD +__cgfsng_ops static const char *isulad_cgfsng_get_cgroup_full_path(struct cgroup_ops *ops, + const char *controller) +{ + struct hierarchy *h; + + h = get_hierarchy(ops, controller); + if (!h) + return log_warn_errno(NULL, ENOENT, "Failed to find hierarchy for controller \"%s\"", + controller ? controller : "(null)"); + + if (!h->path_con) + h->path_con = must_make_path(h->at_mnt, h->at_base, ops->container_cgroup, NULL); + + return h->path_con; +} +#endif + struct cgroup_ops *cgroup_ops_init(struct lxc_conf *conf) { __cleanup_cgroup_ops struct cgroup_ops *cgfsng_ops = NULL; @@ -3888,7 +4464,12 @@ struct cgroup_ops *cgroup_ops_init(struct lxc_conf *conf) cgfsng_ops->unfreeze = cgfsng_unfreeze; cgfsng_ops->setup_limits_legacy = cgfsng_setup_limits_legacy; cgfsng_ops->setup_limits = cgfsng_setup_limits; +#ifdef HAVE_ISULAD + cgfsng_ops->driver = "isulad_cgfsng"; + cgfsng_ops->get_cgroup_full_path = isulad_cgfsng_get_cgroup_full_path; +#else cgfsng_ops->driver = "cgfsng"; +#endif cgfsng_ops->version = "1.0.0"; cgfsng_ops->attach = cgfsng_attach; cgfsng_ops->chown = cgfsng_chown; diff --git a/src/lxc/cgroups/cgroup.h b/src/lxc/cgroups/cgroup.h index d9159f4..0a4ce64 100644 --- a/src/lxc/cgroups/cgroup.h +++ b/src/lxc/cgroups/cgroup.h @@ -18,7 +18,11 @@ #define DEFAULT_CGROUP_MOUNTPOINT_RELATIVE "sys/fs/cgroup" #define DEFAULT_CGROUP_MOUNTPOINT "/sys/fs/cgroup" +#ifdef HAVE_ISULAD +#define DEFAULT_PAYLOAD_CGROUP_PREFIX "" +#else #define DEFAULT_PAYLOAD_CGROUP_PREFIX "lxc.payload." +#endif #define DEFAULT_MONITOR_CGROUP_PREFIX "lxc.monitor." #define DEFAULT_PAYLOAD_CGROUP "payload" #define DEFAULT_MONITOR_CGROUP "monitor" diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 34cf90a..ff5cefc 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -4814,13 +4814,12 @@ int lxc_setup(struct lxc_handler *handler) return log_error(-1, "Failed to verify start hooks"); #ifdef HAVE_ISULAD - if (setup_proc) -#endif - ret = lxc_create_tmp_proc_mount(lxc_conf); - if (ret < 0) - return log_error(-1, "Failed to mount transient procfs instance for LSMs"); + if (setup_proc) { + ret = lxc_create_tmp_proc_mount(lxc_conf); + if (ret < 0) + return log_error(-1, "Failed to mount transient procfs instance for LSMs"); + } -#ifdef HAVE_ISULAD if (setup_rootfs_mountopts(&lxc_conf->rootfs)) { return log_error(-1, "failed to set rootfs for '%s'", name); } @@ -4831,6 +4830,10 @@ int lxc_setup(struct lxc_handler *handler) } } #else + ret = lxc_create_tmp_proc_mount(lxc_conf); + if (ret < 0) + return log_error(-1, "Failed to mount transient procfs instance for LSMs"); + ret = lxc_setup_devpts_child(handler); if (ret < 0) return log_error(-1, "Failed to prepare new devpts instance"); @@ -4855,7 +4858,7 @@ int lxc_setup(struct lxc_handler *handler) #ifdef HAVE_ISULAD /* Ask father to run oci prestart hooks and wait for him to finish. */ - if (lxc_sync_barrier_parent(handler, START_SYNC_OCI_PRESTART_HOOK)) { + if (!lxc_sync_barrier_parent(handler, START_SYNC_OCI_PRESTART_HOOK)) { return log_error(-1, "Failed to sync parent to start host hook"); } #endif diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 0d0d66c..ae1a264 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -287,16 +287,18 @@ static struct lxc_config_t config_jump_table[] = { { "lxc.sysctl", false, set_config_sysctl, get_config_sysctl, clr_config_sysctl, }, { "lxc.proc", false, set_config_proc, get_config_proc, clr_config_proc, }, #ifdef HAVE_ISULAD - { "lxc.isulad.init.args", true, set_config_init_args, get_config_init_args, clr_config_init_args, }, - { "lxc.isulad.populate.device", true, set_config_populate_device, get_config_populate_device, clr_config_populate_device, }, - { "lxc.isulad.umask", true, set_config_umask, get_config_umask, clr_config_umask, }, - { "lxc.isulad.rootfs.maskedpaths", true, set_config_rootfs_masked_paths, get_config_rootfs_masked_paths, clr_config_rootfs_masked_paths, }, - { "lxc.isulad.rootfs.ropaths", true, set_config_rootfs_ro_paths, get_config_rootfs_ro_paths, clr_config_rootfs_ro_paths, }, - { "lxc.isulad.systemd", true, set_config_systemd, get_config_systemd, clr_config_systemd, }, - { "lxc.console.logdriver", true, set_config_console_log_driver, get_config_console_log_driver, clr_config_console_log_driver, }, - { "lxc.console.syslog_tag", true, set_config_console_syslog_tag, get_config_console_syslog_tag, clr_config_console_syslog_tag, }, - { "lxc.console.syslog_facility", true, set_config_console_syslog_facility, get_config_console_syslog_facility, clr_config_console_syslog_facility, }, - { "lxc.selinux.mount_context", true, set_config_selinux_mount_context, get_config_selinux_mount_context, clr_config_selinux_mount_context, }, + { "lxc.isulad.init.args", true, set_config_init_args, get_config_init_args, clr_config_init_args, }, + { "lxc.isulad.populate.device", true, set_config_populate_device, get_config_populate_device, clr_config_populate_device, }, + { "lxc.isulad.umask", true, set_config_umask, get_config_umask, clr_config_umask, }, + { "lxc.isulad.rootfs.maskedpaths", true, set_config_rootfs_masked_paths, get_config_rootfs_masked_paths, clr_config_rootfs_masked_paths, }, + { "lxc.isulad.rootfs.ropaths", true, set_config_rootfs_ro_paths, get_config_rootfs_ro_paths, clr_config_rootfs_ro_paths, }, + { "lxc.isulad.systemd", true, set_config_systemd, get_config_systemd, clr_config_systemd, }, + { "lxc.console.logdriver", true, set_config_console_log_driver, get_config_console_log_driver, clr_config_console_log_driver, }, + { "lxc.console.syslog_tag", true, set_config_console_syslog_tag, get_config_console_syslog_tag, clr_config_console_syslog_tag, }, + { "lxc.console.syslog_facility", true, set_config_console_syslog_facility, get_config_console_syslog_facility, clr_config_console_syslog_facility, }, + { "lxc.selinux.mount_context", true, set_config_selinux_mount_context, get_config_selinux_mount_context, clr_config_selinux_mount_context, }, + // same to lxc.init.groups + { "lxc.isulad.init.groups", true, set_config_init_groups, get_config_init_groups, clr_config_init_groups, }, #endif }; @@ -1343,7 +1345,11 @@ static int set_config_init_groups(const char *key, const char *value, if (!value_dup) return -ENOMEM; +#ifdef HAVE_ISULAD + lxc_iterate_parts(token, value_dup, " \t") +#else lxc_iterate_parts(token, value_dup, ",") +#endif num_groups++; if (num_groups == INT_MAX) @@ -1368,7 +1374,11 @@ static int set_config_init_groups(const char *key, const char *value, /* Restore duplicated value so we can call lxc_iterate_parts() again. */ strcpy(value_dup, value); +#ifdef HAVE_ISULAD + lxc_iterate_parts(token, value_dup, " \t") { +#else lxc_iterate_parts(token, value_dup, ",") { +#endif int ret; gid_t group; @@ -2000,13 +2010,13 @@ static int set_config_cgroup_dir(const char *key, const char *value, if (lxc_config_value_empty(value)) return clr_config_cgroup_dir(key, lxc_conf, NULL); - +#ifndef HAVE_ISULAD if (abspath(value)) return syserror_set(-EINVAL, "%s paths may not be absolute", key); if (dotdot(value)) return syserror_set(-EINVAL, "%s paths may not walk upwards via \"../\"", key); - +#endif return set_config_path_item(&lxc_conf->cgroup_meta.dir, value); } diff --git a/src/lxc/meson.build b/src/lxc/meson.build index 3166401..6c4ba6a 100644 --- a/src/lxc/meson.build +++ b/src/lxc/meson.build @@ -25,6 +25,7 @@ liblxcfs_version_file = configure_file( ) liblxc_sources = files( + 'cgroups/cgfsng.c', 'cgroups/cgroup.c', 'cgroups/cgroup.h', 'cgroups/cgroup2_devices.c', @@ -140,7 +141,6 @@ liblxc_sources = files( if want_isulad liblxc_sources += files( - 'cgroups/isulad_cgfsng.c', 'exec_commands.c', 'exec_commands.h', 'isulad_utils.c', @@ -159,8 +159,6 @@ if want_isulad 'json/oci_runtime_spec.h', 'json/read-file.c', 'json/read-file.h') -else - liblxc_sources += files('cgroups/cgfsng.c') endif if want_apparmor and libapparmor.found() diff --git a/src/lxc/start.c b/src/lxc/start.c index ff9a3fa..a7bc2e6 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -2384,13 +2384,12 @@ static int lxc_spawn(struct lxc_handler *handler) goto out_delete_net; } - /* Tell the child to continue its initialization. We'll get - * START_SYNC_POST_OCI_PRESTART_HOOK when it is ready for us to run oci prestart hooks. - */ - if (lxc_sync_wake_child(handler, START_SYNC_POST_OCI_PRESTART_HOOK)) - goto out_delete_net; + /* Tell the child to continue its initialization. We'll get + * START_SYNC_POST_OCI_PRESTART_HOOK when it is ready for us to run oci prestart hooks. + */ + if (!lxc_sync_wake_child(handler, START_SYNC_POST_OCI_PRESTART_HOOK)) + goto out_delete_net; #endif - if (!lxc_sync_wait_child(handler, START_SYNC_CGROUP_LIMITS)) goto out_delete_net; -- 2.25.1
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