The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxcfs/pull/374
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) === Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com>
From 05b7a16d12d149323932f6cd889b123a32f73dac Mon Sep 17 00:00:00 2001 From: Christian Brauner <christian.brau...@ubuntu.com> Date: Mon, 16 Mar 2020 14:05:11 +0100 Subject: [PATCH 1/2] tree-wide: memory utils improvements Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com> --- src/bindings.c | 8 +-- src/cgroups/cgfsng.c | 15 +----- src/cgroups/cgroup2_devices.c | 4 +- src/cgroups/cgroup_utils.c | 10 ++-- src/lxcfs.c | 5 +- src/macro.h | 14 ++++++ src/memory_utils.h | 95 +++++++++++++++++------------------ src/proc_fuse.c | 2 +- src/proc_loadavg.c | 2 +- src/utils.c | 6 +-- 10 files changed, 79 insertions(+), 82 deletions(-) diff --git a/src/bindings.c b/src/bindings.c index c297f70..115ea1f 100644 --- a/src/bindings.c +++ b/src/bindings.c @@ -259,7 +259,7 @@ static void prune_initpid_store(void) static void save_initpid(struct stat *sb, pid_t pid) { __do_free struct pidns_init_store *entry = NULL; - __do_close_prot_errno int pidfd = -EBADF; + __do_close int pidfd = -EBADF; char path[LXCFS_PROC_PID_LEN]; struct lxcfs_opts *opts = fuse_get_context()->private_data; struct stat st; @@ -371,7 +371,7 @@ static pid_t lxcfs_clone(int (*fn)(void *), void *arg, int flags) */ static void write_task_init_pid_exit(int sock, pid_t target) { - __do_close_prot_errno int fd = -EBADF; + __do_close int fd = -EBADF; char path[LXCFS_PROC_PID_NS_LEN]; pid_t pid; @@ -529,7 +529,7 @@ static bool is_on_ramfs(void) static int pivot_enter() { - __do_close_prot_errno int oldroot = -EBADF, newroot = -EBADF; + __do_close int oldroot = -EBADF, newroot = -EBADF; oldroot = open("/", O_DIRECTORY | O_RDONLY | O_CLOEXEC); if (oldroot < 0) @@ -756,7 +756,7 @@ static void sigusr2_toggle_virtualization(int signo, siginfo_t *info, void *extr static void __attribute__((constructor)) lxcfs_init(void) { - __do_close_prot_errno int init_ns = -EBADF, root_fd = -EBADF, + __do_close int init_ns = -EBADF, root_fd = -EBADF, pidfd = -EBADF; int i = 0; pid_t pid; diff --git a/src/cgroups/cgfsng.c b/src/cgroups/cgfsng.c index aba457b..6ae6c1c 100644 --- a/src/cgroups/cgfsng.c +++ b/src/cgroups/cgfsng.c @@ -46,19 +46,6 @@ #include "cgroup2_devices.h" #include "cgroup_utils.h" -static void free_string_list(char **clist) -{ - int i; - - if (!clist) - return; - - for (i = 0; clist[i]; i++) - free(clist[i]); - - free(clist); -} - /* Given a pointer to a null-terminated array of pointers, realloc to add one * entry, and point the new entry to NULL. Do not fail. Return the index to the * second-to-last entry - that is, the one which is now available for use @@ -656,7 +643,7 @@ static char *readat_cpuset(int cgroup_fd) static int cgfsng_get_cpuset_cpus(struct cgroup_ops *ops, const char *cgroup, char **value) { - __do_close_prot_errno int cgroup_fd = -EBADF; + __do_close int cgroup_fd = -EBADF; __do_free char *path = NULL; char *v; struct hierarchy *h; diff --git a/src/cgroups/cgroup2_devices.c b/src/cgroups/cgroup2_devices.c index d558b04..ad18dfb 100644 --- a/src/cgroups/cgroup2_devices.c +++ b/src/cgroups/cgroup2_devices.c @@ -345,7 +345,7 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type, const char *path, uint32_t flags) { __do_free char *copy = NULL; - __do_close_prot_errno int fd = -EBADF; + __do_close int fd = -EBADF; union bpf_attr attr; int ret; @@ -400,7 +400,7 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type, int bpf_program_cgroup_detach(struct bpf_program *prog) { int ret; - __do_close_prot_errno int fd = -EBADF; + __do_close int fd = -EBADF; if (!prog) return 0; diff --git a/src/cgroups/cgroup_utils.c b/src/cgroups/cgroup_utils.c index 7bdf65b..09bb0e6 100644 --- a/src/cgroups/cgroup_utils.c +++ b/src/cgroups/cgroup_utils.c @@ -289,7 +289,7 @@ static int check_symlink(int fd) */ static int open_if_safe(int dirfd, const char *nextpath) { - __do_close_prot_errno int newfd = -EBADF; + __do_close int newfd = -EBADF; newfd = openat(dirfd, nextpath, O_RDONLY | O_CLOEXEC | O_NOFOLLOW); if (newfd >= 0) /* Was not a symlink, all good. */ @@ -332,7 +332,7 @@ static int open_if_safe(int dirfd, const char *nextpath) */ static int open_without_symlink(const char *target, const char *prefix_skip) { - __do_close_prot_errno int dirfd = -EBADF; + __do_close int dirfd = -EBADF; __do_free char *dup = NULL; int curlen = 0, fulllen, i; @@ -399,7 +399,7 @@ static int open_without_symlink(const char *target, const char *prefix_skip) int safe_mount(const char *src, const char *dest, const char *fstype, unsigned long flags, const void *data, const char *rootfs) { - __do_close_prot_errno int destfd = -EBADF, srcfd = -EBADF; + __do_close int destfd = -EBADF, srcfd = -EBADF; int ret; /* Only needs enough for /proc/self/fd/<fd>. */ char srcbuf[50], destbuf[50]; @@ -464,7 +464,7 @@ size_t strlcat(char *d, const char *s, size_t n) FILE *fopen_cloexec(const char *path, const char *mode) { - __do_close_prot_errno int fd = -EBADF; + __do_close int fd = -EBADF; __do_fclose FILE *ret = NULL; int open_mode = 0; int step = 0; @@ -673,7 +673,7 @@ char *cg_legacy_get_current_cgroup(pid_t pid, const char *controller) char *readat_file(int dirfd, const char *path) { - __do_close_prot_errno int fd = -EBADF; + __do_close int fd = -EBADF; __do_free char *line = NULL; __do_fclose FILE *f = NULL; char *buf = NULL; diff --git a/src/lxcfs.c b/src/lxcfs.c index 041cd85..4dfb6b9 100644 --- a/src/lxcfs.c +++ b/src/lxcfs.c @@ -1025,7 +1025,7 @@ static bool swallow_option(int *argcp, char *argv[], char *opt, char **v) static int set_pidfile(char *pidfile) { - __do_close_prot_errno int fd = -EBADF; + __do_close int fd = -EBADF; char buf[INTTYPE_TO_STRLEN(long)]; int ret; struct flock fl = { @@ -1060,7 +1060,7 @@ static int set_pidfile(char *pidfile) int main(int argc, char *argv[]) { - __do_close_prot_errno int pidfile_fd = -EBADF; + int pidfile_fd = -EBADF; int ret = EXIT_FAILURE; char *pidfile = NULL, *saveptr = NULL, *token = NULL, *v = NULL; char pidfile_buf[STRLITERALLEN(RUNTIME_PATH) + STRLITERALLEN("/lxcfs.pid") + 1] = {}; @@ -1198,5 +1198,6 @@ int main(int argc, char *argv[]) dlclose(dlopen_handle); if (pidfile) unlink(pidfile); + close_prot_errno_disarm(pidfile_fd); exit(ret); } diff --git a/src/macro.h b/src/macro.h index 29b5ed7..aba00bf 100644 --- a/src/macro.h +++ b/src/macro.h @@ -83,6 +83,20 @@ ? 20 \ : sizeof(int[-2 * (sizeof(type) > 8)]))) +#define move_ptr(ptr) \ + ({ \ + typeof(ptr) __internal_ptr__ = (ptr); \ + (ptr) = NULL; \ + __internal_ptr__; \ + }) + +#define move_fd(fd) \ + ({ \ + int __internal_fd__ = (fd); \ + (fd) = -EBADF; \ + __internal_fd__; \ + }) + #define ret_errno(__errno__) \ ({ \ errno = __errno__; \ diff --git a/src/memory_utils.h b/src/memory_utils.h index 0328d18..87d9c6d 100644 --- a/src/memory_utils.h +++ b/src/memory_utils.h @@ -3,42 +3,24 @@ #ifndef __LXCFS_MEMORY_UTILS_H #define __LXCFS_MEMORY_UTILS_H -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif - -#ifndef FUSE_USE_VERSION -#define FUSE_USE_VERSION 26 -#endif - -#define _FILE_OFFSET_BITS 64 - #include <dirent.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <sys/types.h> #include <unistd.h> -#include "config.h" #include "macro.h" -static inline void __auto_free__(void *p) -{ - free(*(void **)p); -} - -static inline void __auto_fclose__(FILE **f) -{ - if (*f) - fclose(*f); -} +#define define_cleanup_function(type, cleaner) \ + static inline void cleaner##_function(type *ptr) \ + { \ + if (*ptr) \ + cleaner(*ptr); \ + } -static inline void __auto_closedir__(DIR **d) -{ - if (*d) - closedir(*d); -} +#define call_cleaner(cleaner) __attribute__((__cleanup__(cleaner##_function))) #define close_prot_errno_disarm(fd) \ if (fd >= 0) { \ @@ -49,12 +31,24 @@ static inline void __auto_closedir__(DIR **d) } #define close_prot_errno_replace(fd, new_fd) \ - if (fd >= 0) { \ - int _e_ = errno; \ - close(fd); \ - errno = _e_; \ - fd = new_fd; \ - } + if (fd >= 0) { \ + int _e_ = errno; \ + close(fd); \ + errno = _e_; \ + fd = new_fd; \ + } + +static inline void close_prot_errno_disarm_function(int *fd) +{ + close_prot_errno_disarm(*fd); +} +#define __do_close call_cleaner(close_prot_errno_disarm) + +define_cleanup_function(FILE *, fclose); +#define __do_fclose call_cleaner(fclose) + +define_cleanup_function(DIR *, closedir); +#define __do_closedir call_cleaner(closedir) #define free_disarm(ptr) \ ({ \ @@ -62,29 +56,30 @@ static inline void __auto_closedir__(DIR **d) move_ptr(ptr); \ }) -static inline void __auto_close__(int *fd) +static inline void free_disarm_function(void *ptr) { - close_prot_errno_disarm(*fd); + free_disarm(*(void **)ptr); } +#define __do_free call_cleaner(free_disarm) -#define __do_close_prot_errno __attribute__((__cleanup__(__auto_close__))) -#define __do_free __attribute__((__cleanup__(__auto_free__))) -#define __do_fclose __attribute__((__cleanup__(__auto_fclose__))) -#define __do_closedir __attribute__((__cleanup__(__auto_closedir__))) +static inline void free_string_list(char **list) +{ + if (list) { + for (int i = 0; list[i]; i++) + free(list[i]); + free_disarm(list); + } +} +define_cleanup_function(char **, free_string_list); +#define __do_free_string_list call_cleaner(free_string_list) -#define move_ptr(ptr) \ - ({ \ - typeof(ptr) __internal_ptr__ = (ptr); \ - (ptr) = NULL; \ - __internal_ptr__; \ - }) +static inline void *memdup(const void *data, size_t len) +{ + void *copy = NULL; -#define move_fd(fd) \ - ({ \ - int __internal_fd__ = (fd); \ - (fd) = -EBADF; \ - __internal_fd__; \ - }) + copy = len ? malloc(len) : NULL; + return copy ? memcpy(copy, data, len) : NULL; +} #define zalloc(__size__) (calloc(1, __size__)) diff --git a/src/proc_fuse.c b/src/proc_fuse.c index 728ddf0..c3870fb 100644 --- a/src/proc_fuse.c +++ b/src/proc_fuse.c @@ -965,7 +965,7 @@ static int proc_stat_read(char *buf, size_t size, off_t offset, /* Note that "memory.stat" in cgroup2 is hierarchical by default. */ static bool cgroup_parse_memory_stat(const char *cgroup, struct memory_stat *mstat) { - __do_close_prot_errno int fd = -EBADF; + __do_close int fd = -EBADF; __do_fclose FILE *f = NULL; __do_free char *line = NULL; __do_free void *fdopen_cache = NULL; diff --git a/src/proc_loadavg.c b/src/proc_loadavg.c index 0a4f6d6..37a8aa8 100644 --- a/src/proc_loadavg.c +++ b/src/proc_loadavg.c @@ -284,7 +284,7 @@ static int calc_pid(char ***pid_buf, char *dpath, int depth, int sum, int cfd) { __do_free char *path = NULL; __do_free void *fdopen_cache = NULL; - __do_close_prot_errno int fd = -EBADF; + __do_close int fd = -EBADF; __do_fclose FILE *f = NULL; __do_closedir DIR *dir = NULL; struct dirent *file; diff --git a/src/utils.c b/src/utils.c index 5b5e076..e54f202 100644 --- a/src/utils.c +++ b/src/utils.c @@ -87,7 +87,7 @@ char *must_strcat(char **src, size_t *sz, size_t *asz, const char *format, ...) */ static int in_same_namespace(pid_t pid1, pid_t pid2, const char *ns) { - __do_close_prot_errno int ns_fd1 = -1, ns_fd2 = -1; + __do_close int ns_fd1 = -1, ns_fd2 = -1; int ret = -1; struct stat ns_st1, ns_st2; @@ -176,7 +176,7 @@ void do_release_file_info(struct fuse_file_info *fi) bool wait_for_sock(int sock, int timeout) { - __do_close_prot_errno int epfd = -EBADF; + __do_close int epfd = -EBADF; struct epoll_event ev; int ret, now, starttime, deltatime; @@ -463,7 +463,7 @@ static char *fd_to_buf(int fd, size_t *length) static char *file_to_buf(const char *path, size_t *length) { - __do_close_prot_errno int fd = -EBADF; + __do_close int fd = -EBADF; if (!length) return NULL; From e7f9baee1dc6fe318b7ad5159dff90c0759ea7ab Mon Sep 17 00:00:00 2001 From: Christian Brauner <christian.brau...@ubuntu.com> Date: Mon, 16 Mar 2020 17:34:34 +0100 Subject: [PATCH 2/2] tree-wide: fix dot_or_empty() Signed-off-by: Christian Brauner <christian.brau...@ubuntu.com> --- src/cgroups/cgfsng.c | 29 ++++++++++++++++++++++++----- src/cgroups/cgroup_utils.h | 5 +++++ src/proc_cpuview.c | 6 +++++- src/proc_loadavg.c | 2 +- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/cgroups/cgfsng.c b/src/cgroups/cgfsng.c index 6ae6c1c..61916b8 100644 --- a/src/cgroups/cgfsng.c +++ b/src/cgroups/cgfsng.c @@ -543,7 +543,11 @@ static bool cgfsng_get(struct cgroup_ops *ops, const char *controller, if (!h) return false; - path = must_make_path(dot_or_empty(cgroup), cgroup, file, NULL); + if (is_relative(cgroup)) + path = must_make_path(cgroup, file, NULL); + else + path = must_make_path(".", cgroup, file, NULL); + *value = readat_file(h->fd, path); return *value != NULL; } @@ -573,7 +577,11 @@ static int cgfsng_get_memory(struct cgroup_ops *ops, const char *cgroup, ret = CGROUP2_SUPER_MAGIC; } - path = must_make_path(dot_or_empty(cgroup), cgroup, file, NULL); + if (is_relative(cgroup)) + path = must_make_path(cgroup, file, NULL); + else + path = must_make_path(".", cgroup, file, NULL); + *value = readat_file(h->fd, path); if (!*value) ret = -1; @@ -590,7 +598,11 @@ static int cgfsng_get_memory_stats_fd(struct cgroup_ops *ops, const char *cgroup if (!h) return -1; - path = must_make_path(dot_or_empty(cgroup), cgroup, "memory.stat", NULL); + if (is_relative(cgroup)) + path = must_make_path(cgroup, "memory.stat", NULL); + else + path = must_make_path(".", cgroup, "memory.stat", NULL); + return openat(h->fd, path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW); } @@ -659,7 +671,10 @@ static int cgfsng_get_cpuset_cpus(struct cgroup_ops *ops, const char *cgroup, ret = CGROUP2_SUPER_MAGIC; *value = NULL; - path = must_make_path(dot_or_empty(cgroup), cgroup, NULL); + if (is_relative(cgroup)) + path = must_make_path(cgroup, NULL); + else + path = must_make_path(".", cgroup, NULL); cgroup_fd = openat_safe(h->fd, path); if (cgroup_fd < 0) { return -1; @@ -709,7 +724,11 @@ static int cgfsng_get_io(struct cgroup_ops *ops, const char *cgroup, else ret = CGROUP2_SUPER_MAGIC; - path = must_make_path(dot_or_empty(cgroup), cgroup, file, NULL); + if (is_relative(cgroup)) + path = must_make_path(cgroup, file, NULL); + else + path = must_make_path(".", cgroup, file, NULL); + *value = readat_file(h->fd, path); if (!*value) { if (errno == ENOENT) diff --git a/src/cgroups/cgroup_utils.h b/src/cgroups/cgroup_utils.h index 483ef49..35e5a98 100644 --- a/src/cgroups/cgroup_utils.h +++ b/src/cgroups/cgroup_utils.h @@ -102,4 +102,9 @@ static inline const char *dot_or_empty(const char *s) return (*s == '/') ? dot : empty; } +static inline bool is_relative(const char *s) +{ + return s && *s != '/'; +} + #endif /* __LXC_CGROUP_UTILS_H */ diff --git a/src/proc_cpuview.c b/src/proc_cpuview.c index ed6bd77..a4e59e6 100644 --- a/src/proc_cpuview.c +++ b/src/proc_cpuview.c @@ -243,7 +243,11 @@ static bool cgfs_param_exist(const char *controller, const char *cgroup, if (cfd < 0) return false; - path = must_make_path(dot_or_empty(cgroup), cgroup, file, NULL); + if (is_relative(cgroup)) + path = must_make_path(cgroup, file, NULL); + else + path = must_make_path(".", cgroup, file, NULL); + return (faccessat(cfd, path, F_OK, 0) == 0); } diff --git a/src/proc_loadavg.c b/src/proc_loadavg.c index 37a8aa8..20b538e 100644 --- a/src/proc_loadavg.c +++ b/src/proc_loadavg.c @@ -523,7 +523,7 @@ static void *load_begin(void *arg) if (!path) goto out; - ret = snprintf(path, length, "%s%s", dot_or_empty(f->cg), f->cg); + ret = snprintf(path, length, "%s%s", !is_relative(f->cg) ? "." : "", f->cg); /* Ignore the node if snprintf fails.*/ if (ret < 0 || ret > length - 1) log_error(goto out, "Refresh node %s failed for snprintf()", f->cg);
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel