From: Christian Brauner Date: Sun, 8 Dec 2019 00:17:33 +0000 (+0100) Subject: cgroups/cgfsng: replace lxc_write_file() X-Git-Tag: lxc-4.0.0~78^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c04a6d4e7f9fe980fe537b9641a3d4d430b12bd1;p=thirdparty%2Flxc.git cgroups/cgfsng: replace lxc_write_file() Signed-off-by: Christian Brauner --- diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c index fd5ab0cf1..01b6f5713 100644 --- a/src/lxc/cgroups/cgfsng.c +++ b/src/lxc/cgroups/cgfsng.c @@ -500,13 +500,11 @@ static bool cg_legacy_filter_and_set_cpus(char *path, bool am_initialized) copy_parent: if (!am_initialized) { - fpath = must_make_path(path, "cpuset.cpus", NULL); - ret = lxc_write_to_file(fpath, cpulist, strlen(cpulist), false, - 0666); - if (ret < 0) { - SYSERROR("Failed to write cpu list to \"%s\"", fpath); - return false; - } + ret = lxc_write_openat(path, "cpuset.cpus", cpulist, strlen(cpulist)); + if (ret < 0) + return log_error_errno(false, + errno, "Failed to write cpu list to \"%s/cpuset.cpus\"", + path); TRACE("Copied cpu settings of parent cgroup"); } @@ -517,7 +515,7 @@ copy_parent: /* Copy contents of parent(@path)/@file to @path/@file */ static bool copy_parent_file(char *path, char *file) { - __do_free char *child_path = NULL, *parent_path = NULL, *value = NULL; + __do_free char *parent_path = NULL, *value = NULL; int ret; char oldv; int len = 0; @@ -545,13 +543,17 @@ static bool copy_parent_file(char *path, char *file) } *lastslash = oldv; - child_path = must_make_path(path, file, NULL); - ret = lxc_write_to_file(child_path, value, len, false, 0666); + ret = lxc_write_openat(path, file, value, len); if (ret < 0) - SYSERROR("Failed to write \"%s\" to file \"%s\"", value, child_path); + SYSERROR("Failed to write \"%s\" to file \"%s/%s\"", value, path, file); return ret >= 0; } +static bool is_unified_hierarchy(const struct hierarchy *h) +{ + return h->version == CGROUP2_SUPER_MAGIC; +} + /* Initialize the cpuset hierarchy in first directory of @gname and set * cgroup.clone_children so that children inherit settings. Since the * h->base_path is populated by init or ourselves, we know it is already @@ -559,11 +561,15 @@ static bool copy_parent_file(char *path, char *file) */ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) { - __do_free char *cgpath = NULL, *clonechildrenpath = NULL; + __do_free char *cgpath = NULL; + __do_close_prot_errno int cgroup_fd = -EBADF; int ret; char v; char *slash; + if (is_unified_hierarchy(h)) + return true; + if (!string_in_list(h->controllers, "cpuset")) return true; @@ -585,14 +591,13 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) } } - clonechildrenpath = must_make_path(cgpath, "cgroup.clone_children", NULL); - /* unified hierarchy doesn't have clone_children */ - if (!file_exists(clonechildrenpath)) - return true; + cgroup_fd = lxc_open_dirfd(cgpath); + if (cgroup_fd < 0) + return false; - ret = lxc_read_from_file(clonechildrenpath, &v, 1); + ret = lxc_readat(cgroup_fd, "cgroup.clone_children", &v, 1); if (ret < 0) { - SYSERROR("Failed to read file \"%s\"", clonechildrenpath); + SYSERROR("Failed to read file \"%s/cgroup.clone_children\"", cgpath); return false; } @@ -612,10 +617,10 @@ static bool cg_legacy_handle_cpuset_hierarchy(struct hierarchy *h, char *cgname) return false; } - ret = lxc_write_to_file(clonechildrenpath, "1", 1, false, 0666); + ret = lxc_writeat(cgroup_fd, "cgroup.clone_children", "1", 1); if (ret < 0) { /* Set clone_children so children inherit our settings */ - SYSERROR("Failed to write 1 to \"%s\"", clonechildrenpath); + SYSERROR("Failed to write 1 to \"%s/cgroup.clone_children\"", cgpath); return false; } @@ -2016,15 +2021,14 @@ __cgfsng_ops static bool cgfsng_get_hierarchies(struct cgroup_ops *ops, int n, static bool cg_legacy_freeze(struct cgroup_ops *ops) { - __do_free char *path = NULL; struct hierarchy *h; h = get_hierarchy(ops, "freezer"); if (!h) return ret_set_errno(-1, ENOENT); - path = must_make_path(h->container_full_path, "freezer.state", NULL); - return lxc_write_to_file(path, "FROZEN", STRLITERALLEN("FROZEN"), false, 0666); + return lxc_write_openat(h->container_full_path, "freezer.state", + "FROZEN", STRLITERALLEN("FROZEN")); } static int freezer_cgroup_events_cb(int fd, uint32_t events, void *cbdata, @@ -2064,7 +2068,6 @@ static int freezer_cgroup_events_cb(int fd, uint32_t events, void *cbdata, static int cg_unified_freeze(struct cgroup_ops *ops, int timeout) { __do_close_prot_errno int fd = -EBADF; - __do_free char *path = NULL; __do_lxc_mainloop_close struct lxc_epoll_descr *descr_ptr = NULL; int ret; struct lxc_epoll_descr descr; @@ -2097,8 +2100,7 @@ static int cg_unified_freeze(struct cgroup_ops *ops, int timeout) return log_error_errno(-1, errno, "Failed to add cgroup.events fd handler to mainloop"); } - path = must_make_path(h->container_full_path, "cgroup.freeze", NULL); - ret = lxc_write_to_file(path, "1", 1, false, 0666); + ret = lxc_write_openat(h->container_full_path, "cgroup.freeze", "1", 1); if (ret < 0) return log_error_errno(-1, errno, "Failed to open cgroup.freeze file"); @@ -2121,21 +2123,19 @@ __cgfsng_ops static int cgfsng_freeze(struct cgroup_ops *ops, int timeout) static int cg_legacy_unfreeze(struct cgroup_ops *ops) { - __do_free char *path = NULL; struct hierarchy *h; h = get_hierarchy(ops, "freezer"); if (!h) return ret_set_errno(-1, ENOENT); - path = must_make_path(h->container_full_path, "freezer.state", NULL); - return lxc_write_to_file(path, "THAWED", STRLITERALLEN("THAWED"), false, 0666); + return lxc_write_openat(h->container_full_path, "freezer.state", + "THAWED", STRLITERALLEN("THAWED")); } static int cg_unified_unfreeze(struct cgroup_ops *ops, int timeout) { __do_close_prot_errno int fd = -EBADF; - __do_free char *path = NULL; __do_lxc_mainloop_close struct lxc_epoll_descr *descr_ptr = NULL; int ret; struct lxc_epoll_descr descr; @@ -2168,8 +2168,7 @@ static int cg_unified_unfreeze(struct cgroup_ops *ops, int timeout) return log_error_errno(-1, errno, "Failed to add cgroup.events fd handler to mainloop"); } - path = must_make_path(h->container_full_path, "cgroup.freeze", NULL); - ret = lxc_write_to_file(path, "0", 1, false, 0666); + ret = lxc_write_openat(h->container_full_path, "cgroup.freeze", "0", 1); if (ret < 0) return log_error_errno(-1, errno, "Failed to open cgroup.freeze file"); @@ -2638,12 +2637,10 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, const char *value) { __do_free char *controller = NULL; - __do_free char *fullpath = NULL; char *p; /* "b|c <2^64-1>:<2^64-1> r|w|m" = 47 chars max */ char converted_value[50]; struct hierarchy *h; - int ret = 0; controller = must_copy_string(filename); p = strchr(controller, '.'); @@ -2651,6 +2648,8 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, *p = '\0'; if (strcmp("devices.allow", filename) == 0 && value[0] == '/') { + int ret; + ret = convert_devpath(value, converted_value); if (ret < 0) return ret; @@ -2667,9 +2666,7 @@ static int cg_legacy_set_data(struct cgroup_ops *ops, const char *filename, return -ENOENT; } - fullpath = must_make_path(h->container_full_path, filename, NULL); - ret = lxc_write_to_file(fullpath, value, strlen(value), false, 0666); - return ret; + return lxc_write_openat(h->container_full_path, filename, value, strlen(value)); } __cgfsng_ops static bool cgfsng_setup_limits_legacy(struct cgroup_ops *ops, @@ -2782,18 +2779,16 @@ __cgfsng_ops static bool cgfsng_setup_limits(struct cgroup_ops *ops, h = ops->unified; lxc_list_for_each (iterator, cgroup_settings) { - __do_free char *fullpath = NULL; - int ret; struct lxc_cgroup *cg = iterator->elem; + int ret; if (strncmp("devices", cg->subsystem, 7) == 0) { ret = bpf_device_cgroup_prepare(ops, conf, cg->subsystem, cg->value); } else { - fullpath = must_make_path(h->container_full_path, - cg->subsystem, NULL); - ret = lxc_write_to_file(fullpath, cg->value, - strlen(cg->value), false, 0666); + ret = lxc_write_openat(h->container_full_path, + cg->subsystem, cg->value, + strlen(cg->value)); if (ret < 0) return log_error_errno(false, errno, "Failed to set \"%s\" to \"%s\"", diff --git a/src/lxc/file_utils.c b/src/lxc/file_utils.c index cd1b732a3..cb7e9c84f 100644 --- a/src/lxc/file_utils.c +++ b/src/lxc/file_utils.c @@ -18,6 +18,27 @@ #include "string_utils.h" #include "utils.h" +int lxc_open_dirfd(const char *dir) +{ + return open(dir, O_DIRECTORY | O_RDONLY | O_CLOEXEC); +} + +int lxc_readat(int dirfd, const char *filename, void *buf, size_t count) +{ + __do_close_prot_errno int fd = -EBADF; + ssize_t ret; + + fd = openat(dirfd, filename, O_RDONLY | O_CLOEXEC); + if (fd < 0) + return -1; + + ret = lxc_read_nointr(fd, buf, count); + if (ret < 0 || (size_t)ret != count) + return -1; + + return 0; +} + int lxc_writeat(int dirfd, const char *filename, const void *buf, size_t count) { __do_close_prot_errno int fd = -EBADF; @@ -34,6 +55,18 @@ int lxc_writeat(int dirfd, const char *filename, const void *buf, size_t count) return 0; } +int lxc_write_openat(const char *dir, const char *filename, const void *buf, + size_t count) +{ + __do_close_prot_errno int dirfd = -EBADF; + + dirfd = open(dir, O_DIRECTORY | O_RDONLY | O_CLOEXEC); + if (dirfd < 0) + return -1; + + return lxc_writeat(dirfd, filename, buf, count); +} + int lxc_write_to_file(const char *filename, const void *buf, size_t count, bool add_newline, mode_t mode) { diff --git a/src/lxc/file_utils.h b/src/lxc/file_utils.h index d27700532..9faf41d36 100644 --- a/src/lxc/file_utils.h +++ b/src/lxc/file_utils.h @@ -15,8 +15,11 @@ /* read and write whole files */ extern int lxc_write_to_file(const char *filename, const void *buf, size_t count, bool add_newline, mode_t mode); +extern int lxc_readat(int dirfd, const char *filename, void *buf, size_t count); extern int lxc_writeat(int dirfd, const char *filename, const void *buf, size_t count); +extern int lxc_write_openat(const char *dir, const char *filename, + const void *buf, size_t count); extern int lxc_read_from_file(const char *filename, void *buf, size_t count); /* send and receive buffers completely */ @@ -47,5 +50,6 @@ extern ssize_t lxc_sendfile_nointr(int out_fd, int in_fd, off_t *offset, size_t count); extern char *file_to_buf(char *path, size_t *length); extern int fd_to_fd(int from, int to); +extern int lxc_open_dirfd(const char *dir); #endif /* __LXC_FILE_UTILS_H */