The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxcfs/pull/321

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
…port

Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
From 560712b0c8d976e05f787e0a4166128edf6553ce Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brau...@ubuntu.com>
Date: Mon, 24 Feb 2020 10:35:50 +0100
Subject: [PATCH] bindings: port cpuset to new cgroup getters and implement
 cgroup2 support

Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
---
 bindings.c             |  9 +++--
 cgroups/cgfsng.c       | 75 +++++++++++++++++++++++++++++++++++++++++-
 cgroups/cgroup.h       |  4 +++
 cgroups/cgroup_utils.c | 53 +++++++++++++++++++++++++++++
 cgroups/cgroup_utils.h |  7 ++++
 memory_utils.h         |  8 +++++
 6 files changed, 152 insertions(+), 4 deletions(-)

diff --git a/bindings.c b/bindings.c
index 52fbb87..35c1e42 100644
--- a/bindings.c
+++ b/bindings.c
@@ -3543,11 +3543,14 @@ static int proc_meminfo_read(char *buf, size_t size, 
off_t offset,
  */
 char *get_cpuset(const char *cg)
 {
-       char *answer;
+       char *value = NULL;
+       int ret;
 
-       if (!cgroup_ops->get(cgroup_ops, "cpuset", cg, "cpuset.cpus", &answer))
+       ret = cgroup_ops->get_cpuset_cpus(cgroup_ops, cg, &value);
+       if (ret < 0)
                return NULL;
-       return answer;
+
+       return value;
 }
 
 bool cpu_in_cpuset(int cpu, const char *cpuset);
diff --git a/cgroups/cgfsng.c b/cgroups/cgfsng.c
index 426ad8a..558f0f5 100644
--- a/cgroups/cgfsng.c
+++ b/cgroups/cgfsng.c
@@ -666,6 +666,77 @@ static int cgfsng_get_memory_stats(struct cgroup_ops *ops, 
const char *cgroup,
        return cgfsng_get_memory(ops, cgroup, "memory.stat", value);
 }
 
+static char *readat_cpuset(int cgroup_fd)
+{
+       __do_free char *val = NULL;
+
+       val = readat_file(cgroup_fd, "cpuset.cpus");
+       if (val && strcmp(val, "") != 0)
+               return move_ptr(val);
+
+       free_disarm(val);
+       val = readat_file(cgroup_fd, "cpuset.cpus.effective");
+       if (val && strcmp(val, "") != 0)
+               return move_ptr(val);
+
+       return NULL;
+}
+
+static int cgfsng_get_cpuset_cpus(struct cgroup_ops *ops, const char *cgroup,
+                                 char **value)
+{
+       __do_close_prot_errno int cgroup_fd = -EBADF;
+       __do_free char *path = NULL;
+       char *v;
+       struct hierarchy *h;
+       int ret;
+
+       h = ops->get_hierarchy(ops, "cpuset");
+       if (!h)
+               return -1;
+
+       if (!is_unified_hierarchy(h))
+               ret = CGROUP_SUPER_MAGIC;
+       else
+               ret = CGROUP2_SUPER_MAGIC;
+
+       *value = NULL;
+       path = must_make_path(*cgroup == '/' ? "." : "", cgroup, NULL);
+       cgroup_fd = openat_safe(h->fd, path);
+       if (cgroup_fd < 0) {
+               return -1;
+       }
+       v = readat_cpuset(cgroup_fd);
+       if (v) {
+               *value = v;
+               return ret;
+       }
+
+       /*
+        * cpuset.cpus and cpuset.cpus.effective are empty so we need to look
+        * the nearest ancestor with a non-empty cpuset.cpus{.effective} file.
+        */
+       for (;;) {
+               int fd;
+
+               fd = openat_safe(cgroup_fd, "../");
+               if (fd < 0 || !is_cgroup_fd(fd)) {
+                       fprintf(stderr, "2222: %s\n", strerror(errno));
+                       return -1;
+               }
+
+               close_prot_errno_replace(cgroup_fd, fd);
+
+               v = readat_cpuset(fd);
+               if (v) {
+                       *value = v;
+                       return ret;
+               }
+       }
+
+       return -1;
+}
+
 /* At startup, parse_hierarchies finds all the info we need about cgroup
  * mountpoints and current cgroups, and stores it in @d.
  */
@@ -862,7 +933,6 @@ struct cgroup_ops *cgfsng_ops_init(void)
        cgfsng_ops->mount = cgfsng_mount;
        cgfsng_ops->nrtasks = cgfsng_nrtasks;
 
-
        /* memory */
        cgfsng_ops->get_memory_stats = cgfsng_get_memory_stats;
        cgfsng_ops->get_memory_max = cgfsng_get_memory_max;
@@ -870,5 +940,8 @@ struct cgroup_ops *cgfsng_ops_init(void)
        cgfsng_ops->get_memory_current = cgfsng_get_memory_current;
        cgfsng_ops->get_memory_swap_current = cgfsng_get_memory_swap_current;
 
+       /* cpuset */
+       cgfsng_ops->get_cpuset_cpus = cgfsng_get_cpuset_cpus;
+
        return move_ptr(cgfsng_ops);
 }
diff --git a/cgroups/cgroup.h b/cgroups/cgroup.h
index e367aff..29fe5ba 100644
--- a/cgroups/cgroup.h
+++ b/cgroups/cgroup.h
@@ -134,6 +134,10 @@ struct cgroup_ops {
                              char **value);
        int (*get_memory_swap_max)(struct cgroup_ops *ops, const char *cgroup,
                                   char **value);
+
+       /* cpuset */
+       int (*get_cpuset_cpus)(struct cgroup_ops *ops, const char *cgroup,
+                              char **value);
 };
 
 extern struct cgroup_ops *cgroup_init(void);
diff --git a/cgroups/cgroup_utils.c b/cgroups/cgroup_utils.c
index e5b2707..957d2e1 100644
--- a/cgroups/cgroup_utils.c
+++ b/cgroups/cgroup_utils.c
@@ -62,6 +62,23 @@ int unified_cgroup_hierarchy(void)
        return 0;
 }
 
+bool is_cgroup_fd(int fd)
+{
+
+       int ret;
+       struct statfs fs;
+
+       ret = fstatfs(fd, &fs);
+       if (ret)
+               return false;
+
+       if (is_fs_type(&fs, CGROUP2_SUPER_MAGIC) ||
+           is_fs_type(&fs, CGROUP_SUPER_MAGIC))
+               return true;
+
+       return false;
+}
+
 void *must_realloc(void *orig, size_t sz)
 {
        void *ret;
@@ -724,3 +741,39 @@ bool mkdir_p(const char *dir, mode_t mode)
 
        return true;
 }
+
+char *must_append_path(char *first, ...)
+{
+       char *cur;
+       size_t full_len;
+       va_list args;
+       char *dest = first;
+       size_t buf_len;
+       size_t cur_len;
+
+       full_len = strlen(first);
+       cur_len = full_len;
+
+       va_start(args, first);
+       while ((cur = va_arg(args, char *)) != NULL) {
+               buf_len = strlen(cur);
+
+               full_len += buf_len;
+               if (cur[0] != '/')
+                       full_len++;
+
+               dest = must_realloc(dest, full_len + 1);
+
+               if (cur[0] != '/') {
+                       memcpy(dest + cur_len, "/", 1);
+                       cur_len++;
+               }
+
+               memcpy(dest + cur_len, cur, buf_len);
+               cur_len += buf_len;
+       }
+       va_end(args);
+
+       dest[cur_len] = '\0';
+       return dest;
+}
diff --git a/cgroups/cgroup_utils.h b/cgroups/cgroup_utils.h
index 1db8a57..2a4cc17 100644
--- a/cgroups/cgroup_utils.h
+++ b/cgroups/cgroup_utils.h
@@ -69,5 +69,12 @@ extern char *cg_hybrid_get_current_cgroup(char *basecginfo,
                                          const char *controller, int type);
 extern char *cg_legacy_get_current_cgroup(pid_t pid, const char *controller);
 extern bool mkdir_p(const char *dir, mode_t mode);
+extern char *must_append_path(char *first, ...);
+extern bool is_cgroup_fd(int fd);
+
+static inline int openat_safe(int fd, const char *path)
+{
+       return openat(fd, path, O_DIRECTORY | O_RDONLY | O_CLOEXEC | 
O_NOFOLLOW);
+}
 
 #endif /* __LXC_CGROUP_UTILS_H */
diff --git a/memory_utils.h b/memory_utils.h
index ac00b10..a97c243 100644
--- a/memory_utils.h
+++ b/memory_utils.h
@@ -37,6 +37,14 @@ static inline void __auto_closedir__(DIR **d)
                fd = -EBADF;        \
        }
 
+#define close_prot_errno_replace(fd, new_fd) \
+       if (fd >= 0) {                       \
+               int _e_ = errno;             \
+               close(fd);                   \
+               errno = _e_;                 \
+               fd = new_fd;                 \
+       }
+
 #define free_disarm(ptr)       \
        ({                     \
                free(ptr);     \
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to