]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
cgroups/cgfsng: replace lxc_write_file() 3217/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Sun, 8 Dec 2019 00:17:33 +0000 (01:17 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Sun, 8 Dec 2019 00:17:33 +0000 (01:17 +0100)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/cgroups/cgfsng.c
src/lxc/file_utils.c
src/lxc/file_utils.h

index fd5ab0cf13150336bd1c82c5638c77c2606eb1ba..01b6f57131def473bc3c8c7174d297ddaa4d6ece 100644 (file)
@@ -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\"",
index cd1b732a3a0593df1aef136ef9a3a0bf64551851..cb7e9c84f9e89ce4dfc53cf4c376c869ea452078 100644 (file)
 #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)
 {
index d277005328c25655999461d2e09ab85c2abcfb95..9faf41d36dadc93f8f351bfb5fe5779eededb3ad 100644 (file)
 /* 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 */