[lxc-devel] [lxcfs/master] bindings: port cpuview to new cgroup getters & cleanup macro expansion

brauner on Github lxc-bot at linuxcontainers.org
Mon Feb 24 12:14:33 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 365 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200224/1c358999/attachment-0001.bin>
-------------- next part --------------
From 77f4399a76b3b3730d561e1efcecb7d5f3346e27 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 24 Feb 2020 12:01:07 +0100
Subject: [PATCH 1/2] bindings: port cpuview to new cgroup getters

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 bindings.c       | 25 +++----------------------
 bindings.h       |  1 -
 cgroups/cgfsng.c | 19 +++++++++++++++++++
 cgroups/cgroup.h |  3 +++
 sysfs_fuse.c     |  6 +++---
 5 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/bindings.c b/bindings.c
index 7ac3ff1..ce9a511 100644
--- a/bindings.c
+++ b/bindings.c
@@ -412,7 +412,7 @@ static void lock_mutex(pthread_mutex_t *l)
 	}
 }
 
-static struct cgroup_ops *cgroup_ops;
+struct cgroup_ops *cgroup_ops;
 
 static int cgroup_mount_ns_fd = -1;
 
@@ -3667,24 +3667,6 @@ static double exact_cpu_count(const char *cg)
 	return rv;
 }
 
-/*
- * Determine whether CPU views should be used or not.
- */
-bool use_cpuview(const char *cg)
-{
-	int cfd;
-
-	cfd = find_mounted_controller("cpu");
-	if (cfd < 0)
-		return false;
-
-	cfd = find_mounted_controller("cpuacct");
-	if (cfd < 0)
-		return false;
-
-	return true;
-}
-
 /*
  * check whether this is a '^processor" line in /proc/cpuinfo
  */
@@ -3736,8 +3718,7 @@ static int proc_cpuinfo_read(char *buf, size_t size, off_t offset,
 	if (!cpuset)
 		goto err;
 
-	use_view = use_cpuview(cg);
-
+	use_view = cgroup_ops->can_use_cpuview(cgroup_ops);
 	if (use_view)
 		max_cpus = max_cpu_count(cg);
 
@@ -4865,7 +4846,7 @@ static int proc_stat_read(char *buf, size_t size, off_t offset,
 		goto err;
 	}
 
-	if (use_cpuview(cg) && cg_cpu_usage) {
+	if (cgroup_ops->can_use_cpuview(cgroup_ops) && cg_cpu_usage) {
 		total_len = cpuview_proc_stat(cg, cpuset, cg_cpu_usage, cg_cpu_usage_size,
 				f, d->buf, d->buflen);
 		goto out;
diff --git a/bindings.h b/bindings.h
index 229d64c..d41994f 100644
--- a/bindings.h
+++ b/bindings.h
@@ -79,7 +79,6 @@ extern int read_file_fuse(const char *path, char *buf, size_t size,
 			  struct file_info *d);
 extern void prune_init_slice(char *cg);
 extern char *get_cpuset(const char *cg);
-extern bool use_cpuview(const char *cg);
 extern int max_cpu_count(const char *cg);
 extern void do_release_file_info(struct fuse_file_info *fi);
 extern int cpu_number_in_cpuset(const char *cpuset);
diff --git a/cgroups/cgfsng.c b/cgroups/cgfsng.c
index 60ac136..8d972b7 100644
--- a/cgroups/cgfsng.c
+++ b/cgroups/cgfsng.c
@@ -794,6 +794,24 @@ static int cgfsng_get_io_wait_time(struct cgroup_ops *ops, const char *cgroup,
 	return cgfsng_get_io(ops, cgroup, "blkio.io_wait_time_recursive", value);
 }
 
+static bool cgfsng_can_use_cpuview(struct cgroup_ops *ops)
+{
+	struct hierarchy *cpu, *cpuacct;
+
+	if (pure_unified_layout(ops))
+		return false;
+
+	cpu = ops->get_hierarchy(ops, "cpu");
+	if (!cpu || is_unified_hierarchy(cpu))
+		return false;
+
+	cpuacct = ops->get_hierarchy(ops, "cpuacct");
+	if (!cpuacct || is_unified_hierarchy(cpuacct))
+		return false;
+
+	return true;
+}
+
 /* At startup, parse_hierarchies finds all the info we need about cgroup
  * mountpoints and current cgroups, and stores it in @d.
  */
@@ -999,6 +1017,7 @@ struct cgroup_ops *cgfsng_ops_init(void)
 
 	/* cpuset */
 	cgfsng_ops->get_cpuset_cpus = cgfsng_get_cpuset_cpus;
+	cgfsng_ops->can_use_cpuview = cgfsng_can_use_cpuview;
 
 	/* blkio */
 	cgfsng_ops->get_io_service_bytes	= cgfsng_get_io_service_bytes;
diff --git a/cgroups/cgroup.h b/cgroups/cgroup.h
index 4221221..e955e75 100644
--- a/cgroups/cgroup.h
+++ b/cgroups/cgroup.h
@@ -138,6 +138,7 @@ struct cgroup_ops {
 	/* cpuset */
 	int (*get_cpuset_cpus)(struct cgroup_ops *ops, const char *cgroup,
 			       char **value);
+	bool (*can_use_cpuview)(struct cgroup_ops *ops);
 
 	/* io */
 	int (*get_io_service_bytes)(struct cgroup_ops *ops, const char *cgroup,
@@ -152,6 +153,8 @@ struct cgroup_ops {
 				char **value);
 };
 
+extern struct cgroup_ops *cgroup_ops;
+
 extern struct cgroup_ops *cgroup_init(void);
 extern void cgroup_exit(struct cgroup_ops *ops);
 
diff --git a/sysfs_fuse.c b/sysfs_fuse.c
index d2b187b..f6bf203 100644
--- a/sysfs_fuse.c
+++ b/sysfs_fuse.c
@@ -31,7 +31,8 @@
 #include <sys/vfs.h>
 
 #include "bindings.h"
-#include "config.h" // for VERSION
+#include "cgroups/cgroup.h"
+#include "config.h"
 #include "sysfs_fuse.h"
 
 static int sys_devices_system_cpu_online_read(char *buf, size_t size,
@@ -72,8 +73,7 @@ static int sys_devices_system_cpu_online_read(char *buf, size_t size,
 	if (!cpuset)
 		goto err;
 
-	use_view = use_cpuview(cg);
-
+	use_view = cgroup_ops->can_use_cpuview(cgroup_ops);
 	if (use_view)
 		max_cpus = max_cpu_count(cg);
 

From 54a6d46a8e9e33cbbc9fa380ff9e5954a4fb088d Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Mon, 24 Feb 2020 12:56:05 +0100
Subject: [PATCH 2/2] bindings: use more cleanup macros

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 bindings.c | 530 +++++++++++++++++++++++------------------------------
 1 file changed, 226 insertions(+), 304 deletions(-)

diff --git a/bindings.c b/bindings.c
index ce9a511..9561b8c 100644
--- a/bindings.c
+++ b/bindings.c
@@ -214,6 +214,7 @@ static struct load_node *locate_node(char *cg, int locate)
 		f = f->next;
 	return f;
 }
+
 /* Delete the load_node n and return the next node of it. */
 static struct load_node *del_node(struct load_node *n, int locate)
 {
@@ -227,18 +228,17 @@ static struct load_node *del_node(struct load_node *n, int locate)
 		n->next->pre = n->pre;
 	}
 	g = n->next;
-	free(n->cg);
-	free(n);
+	free_disarm(n->cg);
+	free_disarm(n);
 	pthread_rwlock_unlock(&load_hash[locate].rdlock);
 	return g;
 }
 
 static void load_free(void)
 {
-	int i;
 	struct load_node *f, *p;
 
-	for (i = 0; i < LOAD_SIZE; i++) {
+	for (int i = 0; i < LOAD_SIZE; i++) {
 		pthread_mutex_lock(&load_hash[i].lock);
 		pthread_rwlock_wrlock(&load_hash[i].rilock);
 		pthread_rwlock_wrlock(&load_hash[i].rdlock);
@@ -251,12 +251,14 @@ static void load_free(void)
 			pthread_rwlock_destroy(&load_hash[i].rdlock);
 			continue;
 		}
-		for (f = load_hash[i].next; f; ) {
-			free(f->cg);
+
+		for (f = load_hash[i].next; f;) {
+			free_disarm(f->cg);
 			p = f->next;
-			free(f);
+			free_disarm(f);
 			f = p;
 		}
+
 		pthread_mutex_unlock(&load_hash[i].lock);
 		pthread_mutex_destroy(&load_hash[i].lock);
 		pthread_rwlock_unlock(&load_hash[i].rilock);
@@ -302,7 +304,7 @@ static bool cpuview_init_head(struct cg_proc_stat_head **head)
 
 	if (pthread_rwlock_init(&(*head)->lock, NULL) != 0) {
 		lxcfs_error("%s\n", "Failed to initialize list lock");
-		free(*head);
+		free_disarm(*head);
 		return false;
 	}
 
@@ -325,10 +327,8 @@ static bool init_cpuview()
 
 err:
 	for (i = 0; i < CPUVIEW_HASH_SIZE; i++) {
-		if (proc_stat_history[i]) {
-			free(proc_stat_history[i]);
-			proc_stat_history[i] = NULL;
-		}
+		if (proc_stat_history[i])
+			free_disarm(proc_stat_history[i]);
 	}
 
 	return false;
@@ -337,10 +337,10 @@ static bool init_cpuview()
 static void free_proc_stat_node(struct cg_proc_stat *node)
 {
 	pthread_mutex_destroy(&node->lock);
-	free(node->cg);
-	free(node->usage);
-	free(node->view);
-	free(node);
+	free_disarm(node->cg);
+	free_disarm(node->usage);
+	free_disarm(node->view);
+	free_disarm(node);
 }
 
 static void cpuview_free_head(struct cg_proc_stat_head *head)
@@ -361,7 +361,7 @@ static void cpuview_free_head(struct cg_proc_stat_head *head)
 	}
 
 	pthread_rwlock_destroy(&head->lock);
-	free(head);
+	free_disarm(head);
 }
 
 static void free_cpuview()
@@ -465,7 +465,7 @@ static void remove_initpid(struct pidns_init_store *e)
 	h = HASH(e->ino);
 	if (pidns_hash_table[h] == e) {
 		pidns_hash_table[h] = e->next;
-		free(e);
+		free_disarm(e);
 		return;
 	}
 
@@ -473,7 +473,7 @@ static void remove_initpid(struct pidns_init_store *e)
 	while (tmp) {
 		if (tmp->next == e) {
 			tmp->next = e->next;
-			free(e);
+			free_disarm(e);
 			return;
 		}
 		tmp = tmp->next;
@@ -514,7 +514,7 @@ static void prune_initpid_store(void)
 				else
 					pidns_hash_table[i] = e->next;
 				e = e->next;
-				free(delme);
+				free_disarm(delme);
 			} else {
 				prev = e;
 				e = e->next;
@@ -1086,8 +1086,8 @@ void free_key(struct cgfs_files *k)
 {
 	if (!k)
 		return;
-	free(k->name);
-	free(k);
+	free_disarm(k->name);
+	free_disarm(k);
 }
 
 void free_keys(struct cgfs_files **keys)
@@ -1099,7 +1099,7 @@ void free_keys(struct cgfs_files **keys)
 	for (i = 0; keys[i]; i++) {
 		free_key(keys[i]);
 	}
-	free(keys);
+	free_disarm(keys);
 }
 
 bool cgfs_param_exist(const char *controller, const char *cgroup, const char *file)
@@ -2057,16 +2057,11 @@ void do_release_file_info(struct fuse_file_info *fi)
 
 	fi->fh = 0;
 
-	free(f->controller);
-	f->controller = NULL;
-	free(f->cgroup);
-	f->cgroup = NULL;
-	free(f->file);
-	f->file = NULL;
-	free(f->buf);
-	f->buf = NULL;
-	free(f);
-	f = NULL;
+	free_disarm(f->controller);
+	free_disarm(f->cgroup);
+	free_disarm(f->file);
+	free_disarm(f->buf);
+	free_disarm(f);
 }
 
 int cg_releasedir(const char *path, struct fuse_file_info *fi)
@@ -3259,11 +3254,13 @@ static void get_blkio_io_value(char *str, unsigned major, unsigned minor, char *
 
 int read_file_fuse(const char *path, char *buf, size_t size, struct file_info *d)
 {
-	size_t linelen = 0, total_len = 0, rv = 0;
-	char *line = NULL;
+	__do_free char *line = NULL;
+	__do_fclose FILE *f = NULL;
+	size_t linelen = 0, total_len = 0;
 	char *cache = d->buf;
 	size_t cache_size = d->buflen;
-	FILE *f = fopen(path, "r");
+
+	f = fopen(path, "r");
 	if (!f)
 		return 0;
 
@@ -3271,13 +3268,11 @@ int read_file_fuse(const char *path, char *buf, size_t size, struct file_info *d
 		ssize_t l = snprintf(cache, cache_size, "%s", line);
 		if (l < 0) {
 			perror("Error writing to cache");
-			rv = 0;
-			goto err;
+			return 0;
 		}
 		if (l >= cache_size) {
 			lxcfs_error("%s\n", "Internal error: truncated write to cache.");
-			rv = 0;
-			goto err;
+			return 0;
 		}
 		cache += l;
 		cache_size -= l;
@@ -3290,13 +3285,10 @@ int read_file_fuse(const char *path, char *buf, size_t size, struct file_info *d
 
 	/* read from off 0 */
 	memcpy(buf, d->buf, total_len);
-	rv = total_len;
-  err:
-	fclose(f);
-	free(line);
-	if (d->size > rv)
-		d->cached = d->size - rv;
-	return rv;
+
+	if (d->size > total_len)
+		d->cached = d->size - total_len;
+	return total_len;
 }
 
 /*
@@ -3570,24 +3562,18 @@ static bool cpuline_in_cpuset(const char *line, const char *cpuset)
  */
 static bool read_cpu_cfs_param(const char *cg, const char *param, int64_t *value)
 {
-	bool rv = false;
-	char file[11 + 6 + 1]; // cpu.cfs__us + quota/period + \0
-	char *str = NULL;
+	__do_free char *str = NULL;
+	char file[11 + 6 + 1]; /* cpu.cfs__us + quota/period + \0 */
 
-	sprintf(file, "cpu.cfs_%s_us", param);
+	snprintf(file, sizeof(file), "cpu.cfs_%s_us", param);
 
 	if (!cgroup_ops->get(cgroup_ops, "cpu", cg, file, &str))
-		goto err;
+		return false;
 
 	if (sscanf(str, "%ld", value) != 1)
-		goto err;
-
-	rv = true;
+		return false;
 
-err:
-	if (str)
-		free(str);
-	return rv;
+	return true;
 }
 
 /*
@@ -3680,29 +3666,32 @@ static bool is_processor_line(const char *line)
 }
 
 static int proc_cpuinfo_read(char *buf, size_t size, off_t offset,
-		struct fuse_file_info *fi)
+			     struct fuse_file_info *fi)
 {
+	__do_free char *cg = NULL, *cpuset = NULL, *line = NULL;
+	__do_fclose FILE *f = NULL;
 	struct fuse_context *fc = fuse_get_context();
 	struct file_info *d = (struct file_info *)fi->fh;
-	char *cg;
-	char *cpuset = NULL;
-	char *line = NULL;
-	size_t linelen = 0, total_len = 0, rv = 0;
+	size_t linelen = 0, total_len = 0;
 	bool am_printing = false, firstline = true, is_s390x = false;
 	int curcpu = -1, cpu, max_cpus = 0;
 	bool use_view;
 	char *cache = d->buf;
 	size_t cache_size = d->buflen;
-	FILE *f = NULL;
 
 	if (offset){
+		int left;
+
 		if (offset > d->size)
 			return -EINVAL;
+
 		if (!d->cached)
 			return 0;
-		int left = d->size - offset;
+
+		left = d->size - offset;
 		total_len = left > size ? size: left;
 		memcpy(buf, cache + offset, total_len);
+
 		return total_len;
 	}
 
@@ -3716,7 +3705,7 @@ static int proc_cpuinfo_read(char *buf, size_t size, off_t offset,
 
 	cpuset = get_cpuset(cg);
 	if (!cpuset)
-		goto err;
+		return 0;
 
 	use_view = cgroup_ops->can_use_cpuview(cgroup_ops);
 	if (use_view)
@@ -3724,7 +3713,7 @@ static int proc_cpuinfo_read(char *buf, size_t size, off_t offset,
 
 	f = fopen("/proc/cpuinfo", "r");
 	if (!f)
-		goto err;
+		return 0;
 
 	while (getline(&line, &linelen, f) != -1) {
 		ssize_t l;
@@ -3747,13 +3736,11 @@ static int proc_cpuinfo_read(char *buf, size_t size, off_t offset,
 				l = snprintf(cache, cache_size, "processor	: %d\n", curcpu);
 				if (l < 0) {
 					perror("Error writing to cache");
-					rv = 0;
-					goto err;
+					return 0;
 				}
 				if (l >= cache_size) {
 					lxcfs_error("%s\n", "Internal error: truncated write to cache.");
-					rv = 0;
-					goto err;
+					return 0;
 				}
 				cache += l;
 				cache_size -= l;
@@ -3769,18 +3756,16 @@ static int proc_cpuinfo_read(char *buf, size_t size, off_t offset,
 			curcpu ++;
 			p = strchr(line, ':');
 			if (!p || !*p)
-				goto err;
+				return 0;
 			p++;
 			l = snprintf(cache, cache_size, "processor %d:%s", curcpu, p);
 			if (l < 0) {
 				perror("Error writing to cache");
-				rv = 0;
-				goto err;
+				return 0;
 			}
 			if (l >= cache_size) {
 				lxcfs_error("%s\n", "Internal error: truncated write to cache.");
-				rv = 0;
-				goto err;
+				return 0;
 			}
 			cache += l;
 			cache_size -= l;
@@ -3792,13 +3777,11 @@ static int proc_cpuinfo_read(char *buf, size_t size, off_t offset,
 			l = snprintf(cache, cache_size, "%s", line);
 			if (l < 0) {
 				perror("Error writing to cache");
-				rv = 0;
-				goto err;
+				return 0;
 			}
 			if (l >= cache_size) {
 				lxcfs_error("%s\n", "Internal error: truncated write to cache.");
-				rv = 0;
-				goto err;
+				return 0;
 			}
 			cache += l;
 			cache_size -= l;
@@ -3807,34 +3790,35 @@ static int proc_cpuinfo_read(char *buf, size_t size, off_t offset,
 	}
 
 	if (is_s390x) {
-		char *origcache = d->buf;
+		__do_free char *origcache = d->buf;
 		ssize_t l;
-		do {
-			d->buf = malloc(d->buflen);
-		} while (!d->buf);
+
+		d->buf = malloc(d->buflen);
+		if (!d->buf) {
+			d->buf = move_ptr(origcache);
+			return 0;
+		}
+
 		cache = d->buf;
 		cache_size = d->buflen;
 		total_len = 0;
 		l = snprintf(cache, cache_size, "vendor_id       : IBM/S390\n");
-		if (l < 0 || l >= cache_size) {
-			free(origcache);
-			goto err;
-		}
+		if (l < 0 || l >= cache_size)
+			return 0;
+
 		cache_size -= l;
 		cache += l;
 		total_len += l;
 		l = snprintf(cache, cache_size, "# processors    : %d\n", curcpu + 1);
-		if (l < 0 || l >= cache_size) {
-			free(origcache);
-			goto err;
-		}
+		if (l < 0 || l >= cache_size)
+			return 0;
+
 		cache_size -= l;
 		cache += l;
 		total_len += l;
 		l = snprintf(cache, cache_size, "%s", origcache);
-		free(origcache);
 		if (l < 0 || l >= cache_size)
-			goto err;
+			return 0;
 		total_len += l;
 	}
 
@@ -3844,14 +3828,7 @@ static int proc_cpuinfo_read(char *buf, size_t size, off_t offset,
 
 	/* read from off 0 */
 	memcpy(buf, d->buf, total_len);
-	rv = total_len;
-err:
-	if (f)
-		fclose(f);
-	free(line);
-	free(cpuset);
-	free(cg);
-	return rv;
+	return total_len;
 }
 
 static uint64_t get_reaper_start_time(pid_t pid)
@@ -3996,13 +3973,14 @@ static double get_reaper_age(pid_t pid)
  */
 static int read_cpuacct_usage_all(char *cg, char *cpuset, struct cpuacct_usage **return_usage, int *size)
 {
+	__do_free char *usage_str = NULL;
+	__do_free struct cpuacct_usage *cpu_usage = NULL;
 	int cpucount = get_nprocs_conf();
-	struct cpuacct_usage *cpu_usage;
-	int rv = 0, i, j, ret;
+	int read_pos = 0, read_cnt=0;
+	int i, j, ret;
 	int cg_cpu;
 	uint64_t cg_user, cg_system;
 	int64_t ticks_per_sec;
-	char *usage_str = NULL;
 
 	ticks_per_sec = sysconf(_SC_CLK_TCK);
 
@@ -4020,23 +3998,21 @@ static int read_cpuacct_usage_all(char *cg, char *cpuset, struct cpuacct_usage *
 
 	memset(cpu_usage, 0, sizeof(struct cpuacct_usage) * cpucount);
 	if (!cgroup_ops->get(cgroup_ops, "cpuacct", cg, "cpuacct.usage_all", &usage_str)) {
-		// read cpuacct.usage_percpu instead
+		char *data = NULL;
+		int i = 0, read_pos = 0, read_cnt=0;
+		size_t sz = 0, asz = 0;
+
+		/* read cpuacct.usage_percpu instead. */
 		lxcfs_v("failed to read cpuacct.usage_all. reading cpuacct.usage_percpu instead\n%s", "");
-		if (!cgroup_ops->get(cgroup_ops, "cpuacct", cg, "cpuacct.usage_percpu", &usage_str)) {
-			rv = -1;
-			goto err;
-		}
+		if (!cgroup_ops->get(cgroup_ops, "cpuacct", cg, "cpuacct.usage_percpu", &usage_str))
+			return -1;
 		lxcfs_v("usage_str: %s\n", usage_str);
 
-		// convert cpuacct.usage_percpu into cpuacct.usage_all
+		/* convert cpuacct.usage_percpu into cpuacct.usage_all. */
 		lxcfs_v("converting cpuacct.usage_percpu into cpuacct.usage_all\n%s", "");
 
-		char *data = NULL;
-		size_t sz = 0, asz = 0;
-
 		must_strcat(&data, &sz, &asz, "cpu user system\n");
 
-		int i = 0, read_pos = 0, read_cnt=0;
 		while (sscanf(usage_str + read_pos, "%lu %n", &cg_user, &read_cnt) > 0) {
 			lxcfs_debug("i: %d, cg_user: %lu, read_pos: %d, read_cnt: %d\n", i, cg_user, read_pos, read_cnt);
 			must_strcat(&data, &sz, &asz, "%d %lu 0\n", i, cg_user);
@@ -4044,18 +4020,15 @@ static int read_cpuacct_usage_all(char *cg, char *cpuset, struct cpuacct_usage *
 			read_pos += read_cnt;
 		}
 
-		free(usage_str);
 		usage_str = data;
 
 		lxcfs_v("usage_str: %s\n", usage_str);
 	}
 
-	int read_pos = 0, read_cnt=0;
 	if (sscanf(usage_str, "cpu user system\n%n", &read_cnt) != 0) {
 		lxcfs_error("read_cpuacct_usage_all reading first line from "
 				"%s/cpuacct.usage_all failed.\n", cg);
-		rv = -1;
-		goto err;
+		return -1;
 	}
 
 	read_pos += read_cnt;
@@ -4070,8 +4043,7 @@ static int read_cpuacct_usage_all(char *cg, char *cpuset, struct cpuacct_usage *
 		if (ret != 3) {
 			lxcfs_error("read_cpuacct_usage_all reading from %s/cpuacct.usage_all "
 					"failed.\n", cg);
-			rv = -1;
-			goto err;
+			return -1;
 		}
 
 		read_pos += read_cnt;
@@ -4082,20 +4054,9 @@ static int read_cpuacct_usage_all(char *cg, char *cpuset, struct cpuacct_usage *
 		j++;
 	}
 
-	rv = 0;
-	*return_usage = cpu_usage;
+	*return_usage = move_ptr(cpu_usage);
 	*size = cpucount;
-
-err:
-	if (usage_str)
-		free(usage_str);
-
-	if (rv != 0) {
-		free(cpu_usage);
-		*return_usage = NULL;
-	}
-
-	return rv;
+	return 0;
 }
 
 static unsigned long diff_cpu_usage(struct cpuacct_usage *older, struct cpuacct_usage *newer, struct cpuacct_usage *diff, int cpu_count)
@@ -4323,8 +4284,7 @@ static struct cg_proc_stat *add_proc_stat_node(struct cg_proc_stat *new_node)
 
 static bool expand_proc_stat_node(struct cg_proc_stat *node, int cpu_count)
 {
-	struct cpuacct_usage *new_usage, *new_view;
-	int i;
+	__do_free struct cpuacct_usage *new_usage = NULL, *new_view = NULL;
 
 	/* Allocate new memory */
 	new_usage = malloc(sizeof(struct cpuacct_usage) * cpu_count);
@@ -4332,13 +4292,11 @@ static bool expand_proc_stat_node(struct cg_proc_stat *node, int cpu_count)
 		return false;
 
 	new_view = malloc(sizeof(struct cpuacct_usage) * cpu_count);
-	if (!new_view) {
-		free(new_usage);
+	if (!new_view)
 		return false;
-	}
 
 	/* Copy existing data & initialize new elements */
-	for (i = 0; i < cpu_count; i++) {
+	for (int i = 0; i < cpu_count; i++) {
 		if (i < node->cpu_count) {
 			new_usage[i].user = node->usage[i].user;
 			new_usage[i].system = node->usage[i].system;
@@ -4359,10 +4317,10 @@ static bool expand_proc_stat_node(struct cg_proc_stat *node, int cpu_count)
 	}
 
 	free(node->usage);
-	free(node->view);
+	node->usage = move_ptr(new_usage);
 
-	node->usage = new_usage;
-	node->view = new_view;
+	free(node->view);
+	node->view = move_ptr(new_view);
 	node->cpu_count = cpu_count;
 
 	return true;
@@ -4420,19 +4378,23 @@ static void reset_proc_stat_node(struct cg_proc_stat *node, struct cpuacct_usage
 	node->cpu_count = cpu_count;
 }
 
-static int cpuview_proc_stat(const char *cg, const char *cpuset, struct cpuacct_usage *cg_cpu_usage, int cg_cpu_usage_size, FILE *f, char *buf, size_t buf_size)
+static int cpuview_proc_stat(const char *cg, const char *cpuset,
+			     struct cpuacct_usage *cg_cpu_usage,
+			     int cg_cpu_usage_size, FILE *f, char *buf,
+			     size_t buf_size)
 {
-	char *line = NULL;
-	size_t linelen = 0, total_len = 0, rv = 0, l;
+	__do_free char *line = NULL;
+	__do_free struct cpuacct_usage *diff = NULL;
+	size_t linelen = 0, total_len = 0, l;
 	int curcpu = -1; /* cpu numbering starts at 0 */
 	int physcpu, i;
 	int max_cpus = max_cpu_count(cg), cpu_cnt = 0;
-	unsigned long user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0, steal = 0, guest = 0, guest_nice = 0;
+	unsigned long user = 0, nice = 0, system = 0, idle = 0, iowait = 0,
+		      irq = 0, softirq = 0, steal = 0, guest = 0, guest_nice = 0;
 	unsigned long user_sum = 0, system_sum = 0, idle_sum = 0;
 	unsigned long user_surplus = 0, system_surplus = 0;
 	unsigned long total_sum, threshold;
 	struct cg_proc_stat *stat_node;
-	struct cpuacct_usage *diff = NULL;
 	int nprocs = get_nprocs_conf();
 
 	if (cg_cpu_usage_size < nprocs)
@@ -4446,10 +4408,10 @@ static int cpuview_proc_stat(const char *cg, const char *cpuset, struct cpuacct_
 
 		if (strlen(line) == 0)
 			continue;
-		if (sscanf(line, "cpu%9[^ ]", cpu_char) != 1) {
-			/* not a ^cpuN line containing a number N */
+
+		/* not a ^cpuN line containing a number N */
+		if (sscanf(line, "cpu%9[^ ]", cpu_char) != 1)
 			break;
-		}
 
 		if (sscanf(cpu_char, "%d", &physcpu) != 1)
 			continue;
@@ -4461,9 +4423,8 @@ static int cpuview_proc_stat(const char *cg, const char *cpuset, struct cpuacct_
 		cpu_cnt ++;
 
 		if (!cpu_in_cpuset(physcpu, cpuset)) {
-			for (i = curcpu; i <= physcpu; i++) {
+			for (i = curcpu; i <= physcpu; i++)
 				cg_cpu_usage[i].online = false;
-			}
 			continue;
 		}
 
@@ -4514,14 +4475,12 @@ static int cpuview_proc_stat(const char *cg, const char *cpuset, struct cpuacct_
 
 	if (!stat_node) {
 		lxcfs_error("unable to find/create stat node for %s\n", cg);
-		rv = 0;
-		goto err;
+		return 0;
 	}
 
 	diff = malloc(sizeof(struct cpuacct_usage) * nprocs);
 	if (!diff) {
-		rv = 0;
-		goto err;
+		return 0;
 	}
 
 	/*
@@ -4560,6 +4519,13 @@ static int cpuview_proc_stat(const char *cg, const char *cpuset, struct cpuacct_
 
 	/* Calculate usage counters of visible CPUs */
 	if (max_cpus > 0) {
+		unsigned long diff_user = 0;
+		unsigned long diff_system = 0;
+		unsigned long diff_idle = 0;
+		unsigned long max_diff_idle = 0;
+		unsigned long max_diff_idle_index = 0;
+		double exact_cpus;
+
 		/* threshold = maximum usage per cpu, including idle */
 		threshold = total_sum / cpu_cnt * max_cpus;
 
@@ -4576,21 +4542,15 @@ static int cpuview_proc_stat(const char *cg, const char *cpuset, struct cpuacct_
 				continue;
 
 			/* Add user */
-			add_cpu_usage(
-					&user_surplus,
-					&diff[curcpu],
-					&diff[curcpu].user,
-					threshold);
+			add_cpu_usage(&user_surplus, &diff[curcpu],
+				      &diff[curcpu].user, threshold);
 
 			if (diff[curcpu].user + diff[curcpu].system >= threshold)
 				continue;
 
 			/* If there is still room, add system */
-			add_cpu_usage(
-					&system_surplus,
-					&diff[curcpu],
-					&diff[curcpu].system,
-					threshold);
+			add_cpu_usage(&system_surplus, &diff[curcpu],
+				      &diff[curcpu].system, threshold);
 		}
 
 		if (user_surplus > 0)
@@ -4598,11 +4558,6 @@ static int cpuview_proc_stat(const char *cg, const char *cpuset, struct cpuacct_
 		if (system_surplus > 0)
 			lxcfs_debug("leftover system: %lu for %s\n", system_surplus, cg);
 
-		unsigned long diff_user = 0;
-		unsigned long diff_system = 0;
-		unsigned long diff_idle = 0;
-		unsigned long max_diff_idle = 0;
-		unsigned long max_diff_idle_index = 0;
 		for (curcpu = 0, i = -1; curcpu < nprocs; curcpu++) {
 			if (!stat_node->usage[curcpu].online)
 				continue;
@@ -4632,11 +4587,12 @@ static int cpuview_proc_stat(const char *cg, const char *cpuset, struct cpuacct_
 		}
 		lxcfs_v("total. diff_user: %lu, diff_system: %lu, diff_idle: %lu\n", diff_user, diff_system, diff_idle);
 
-		// revise cpu usage view to support partial cpu case
-		double exact_cpus = exact_cpu_count(cg);
+		/* revise cpu usage view to support partial cpu case. */
+		exact_cpus = exact_cpu_count(cg);
 		if (exact_cpus < (double)max_cpus){
-			lxcfs_v("revising cpu usage view to match the exact cpu count [%f]\n", exact_cpus);
 			unsigned long delta = (unsigned long)((double)(diff_user + diff_system + diff_idle) * (1 - exact_cpus / (double)max_cpus));
+
+			lxcfs_v("revising cpu usage view to match the exact cpu count [%f]\n", exact_cpus);
 			lxcfs_v("delta: %lu\n", delta);
 			lxcfs_v("idle_sum before: %lu\n", idle_sum);
 			idle_sum = idle_sum > delta ? idle_sum - delta : 0;
@@ -4672,13 +4628,11 @@ static int cpuview_proc_stat(const char *cg, const char *cpuset, struct cpuacct_
 
 	if (l < 0) {
 		perror("Error writing to cache");
-		rv = 0;
-		goto err;
+		return 0;
 	}
 	if (l >= buf_size) {
 		lxcfs_error("%s\n", "Internal error: truncated write to cache.");
-		rv = 0;
-		goto err;
+		return 0;
 	}
 
 	buf += l;
@@ -4704,14 +4658,12 @@ static int cpuview_proc_stat(const char *cg, const char *cpuset, struct cpuacct_
 
 		if (l < 0) {
 			perror("Error writing to cache");
-			rv = 0;
-			goto err;
+			return 0;
 
 		}
 		if (l >= buf_size) {
 			lxcfs_error("%s\n", "Internal error: truncated write to cache.");
-			rv = 0;
-			goto err;
+			return 0;
 		}
 
 		buf += l;
@@ -4724,14 +4676,12 @@ static int cpuview_proc_stat(const char *cg, const char *cpuset, struct cpuacct_
 
 	if (l < 0) {
 		perror("Error writing to cache");
-		rv = 0;
-		goto err;
+		return 0;
 
 	}
 	if (l >= buf_size) {
 		lxcfs_error("%s\n", "Internal error: truncated write to cache.");
-		rv = 0;
-		goto err;
+		return 0;
 	}
 
 	buf += l;
@@ -4743,52 +4693,43 @@ static int cpuview_proc_stat(const char *cg, const char *cpuset, struct cpuacct_
 		l = snprintf(buf, buf_size, "%s", line);
 		if (l < 0) {
 			perror("Error writing to cache");
-			rv = 0;
-			goto err;
+			return 0;
 		}
 		if (l >= buf_size) {
 			lxcfs_error("%s\n", "Internal error: truncated write to cache.");
-			rv = 0;
-			goto err;
+			return 0;
 		}
 		buf += l;
 		buf_size -= l;
 		total_len += l;
 	}
 
-	rv = total_len;
-
-err:
 	if (stat_node)
 		pthread_mutex_unlock(&stat_node->lock);
-	if (line)
-		free(line);
-	if (diff)
-		free(diff);
-	return rv;
+	return total_len;
 }
 
 #define CPUALL_MAX_SIZE (BUF_RESERVE_SIZE / 2)
 static int proc_stat_read(char *buf, size_t size, off_t offset,
-		struct fuse_file_info *fi)
+			  struct fuse_file_info *fi)
 {
+	__do_free char *cg = NULL, *cpuset = NULL, *line = NULL;
+	__do_free struct cpuacct_usage *cg_cpu_usage = NULL;
+	__do_fclose FILE *f = NULL;
 	struct fuse_context *fc = fuse_get_context();
 	struct file_info *d = (struct file_info *)fi->fh;
-	char *cg;
-	char *cpuset = NULL;
-	char *line = NULL;
-	size_t linelen = 0, total_len = 0, rv = 0;
+	size_t linelen = 0, total_len = 0;
 	int curcpu = -1; /* cpu numbering starts at 0 */
 	int physcpu = 0;
-	unsigned long user = 0, nice = 0, system = 0, idle = 0, iowait = 0, irq = 0, softirq = 0, steal = 0, guest = 0, guest_nice = 0;
-	unsigned long user_sum = 0, nice_sum = 0, system_sum = 0, idle_sum = 0, iowait_sum = 0,
-					irq_sum = 0, softirq_sum = 0, steal_sum = 0, guest_sum = 0, guest_nice_sum = 0;
+	unsigned long user = 0, nice = 0, system = 0, idle = 0, iowait = 0,
+		      irq = 0, softirq = 0, steal = 0, guest = 0, guest_nice = 0;
+	unsigned long user_sum = 0, nice_sum = 0, system_sum = 0, idle_sum = 0,
+		      iowait_sum = 0, irq_sum = 0, softirq_sum = 0,
+		      steal_sum = 0, guest_sum = 0, guest_nice_sum = 0;
 	char cpuall[CPUALL_MAX_SIZE];
 	/* reserve for cpu all */
 	char *cache = d->buf + CPUALL_MAX_SIZE;
 	size_t cache_size = d->buflen - CPUALL_MAX_SIZE;
-	FILE *f = NULL;
-	struct cpuacct_usage *cg_cpu_usage = NULL;
 	int cg_cpu_usage_size = 0;
 
 	if (offset){
@@ -4824,7 +4765,7 @@ static int proc_stat_read(char *buf, size_t size, off_t offset,
 
 	cpuset = get_cpuset(cg);
 	if (!cpuset)
-		goto err;
+		return 0;
 
 	/*
 	 * Read cpuacct.usage_all for all CPUs.
@@ -4838,12 +4779,12 @@ static int proc_stat_read(char *buf, size_t size, off_t offset,
 
 	f = fopen("/proc/stat", "r");
 	if (!f)
-		goto err;
+		return 0;
 
 	//skip first line
 	if (getline(&line, &linelen, f) < 0) {
 		lxcfs_error("%s\n", "proc_stat_read read first line failed.");
-		goto err;
+		return 0;
 	}
 
 	if (cgroup_ops->can_use_cpuview(cgroup_ops) && cg_cpu_usage) {
@@ -4866,13 +4807,11 @@ static int proc_stat_read(char *buf, size_t size, off_t offset,
 			l = snprintf(cache, cache_size, "%s", line);
 			if (l < 0) {
 				perror("Error writing to cache");
-				rv = 0;
-				goto err;
+				return 0;
 			}
 			if (l >= cache_size) {
 				lxcfs_error("%s\n", "Internal error: truncated write to cache.");
-				rv = 0;
-				goto err;
+				return 0;
 			}
 			cache += l;
 			cache_size -= l;
@@ -4905,14 +4844,12 @@ static int proc_stat_read(char *buf, size_t size, off_t offset,
 			l = snprintf(cache, cache_size, "cpu%d%s", curcpu, c);
 			if (l < 0) {
 				perror("Error writing to cache");
-				rv = 0;
-				goto err;
+				return 0;
 
 			}
 			if (l >= cache_size) {
 				lxcfs_error("%s\n", "Internal error: truncated write to cache.");
-				rv = 0;
-				goto err;
+				return 0;
 			}
 
 			cache += l;
@@ -4946,14 +4883,12 @@ static int proc_stat_read(char *buf, size_t size, off_t offset,
 
 			if (l < 0) {
 				perror("Error writing to cache");
-				rv = 0;
-				goto err;
+				return 0;
 
 			}
 			if (l >= cache_size) {
 				lxcfs_error("%s\n", "Internal error: truncated write to cache.");
-				rv = 0;
-				goto err;
+				return 0;
 			}
 
 			cache += l;
@@ -5010,17 +4945,7 @@ static int proc_stat_read(char *buf, size_t size, off_t offset,
 		total_len = size;
 
 	memcpy(buf, d->buf, total_len);
-	rv = total_len;
-
-err:
-	if (f)
-		fclose(f);
-	if (cg_cpu_usage)
-		free(cg_cpu_usage);
-	free(line);
-	free(cpuset);
-	free(cg);
-	return rv;
+	return total_len;
 }
 
 /* This function retrieves the busy time of a group of tasks by looking at
@@ -5032,27 +4957,24 @@ static int proc_stat_read(char *buf, size_t size, off_t offset,
  */
 static double get_reaper_busy(pid_t task)
 {
-	pid_t initpid = lookup_initpid_in_store(task);
-	char *cgroup = NULL, *usage_str = NULL;
+	__do_free char *cgroup = NULL, *usage_str = NULL;
 	unsigned long usage = 0;
-	double res = 0;
+	pid_t initpid;
 
+	initpid = lookup_initpid_in_store(task);
 	if (initpid <= 0)
 		return 0;
 
 	cgroup = get_pid_cgroup(initpid, "cpuacct");
 	if (!cgroup)
-		goto out;
+		return 0;
 	prune_init_slice(cgroup);
-	if (!cgroup_ops->get(cgroup_ops, "cpuacct", cgroup, "cpuacct.usage", &usage_str))
-		goto out;
-	usage = strtoul(usage_str, NULL, 10);
-	res = (double)usage / 1000000000;
+	if (!cgroup_ops->get(cgroup_ops, "cpuacct", cgroup, "cpuacct.usage",
+			     &usage_str))
+		return 0;
 
-out:
-	free(cgroup);
-	free(usage_str);
-	return res;
+	usage = strtoul(usage_str, NULL, 10);
+	return ((double)usage / 1000000000);
 }
 
 #if RELOADTEST
@@ -5370,81 +5292,79 @@ static int proc_swaps_read(char *buf, size_t size, off_t offset,
  */
 static int calc_pid(char ***pid_buf, char *dpath, int depth, int sum, int cfd)
 {
-	DIR *dir;
-	int fd;
+	__do_free char *path = NULL;
+	__do_close_prot_errno int fd = -EBADF;
+	__do_fclose FILE *f = NULL;
+	__do_closedir DIR *dir = NULL;
 	struct dirent *file;
-	FILE *f = NULL;
 	size_t linelen = 0;
 	char *line = NULL;
 	int pd;
-	char *path_dir, *path;
 	char **pid;
 
 	/* path = dpath + "/cgroup.procs" + /0 */
-	do {
-		path = malloc(strlen(dpath) + 20);
-	} while (!path);
+	path = malloc(strlen(dpath) + 20);
+	if (!path)
+		return sum;
 
 	strcpy(path, dpath);
-	fd = openat(cfd, path, O_RDONLY);
+	fd = openat(cfd, path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
 	if (fd < 0)
-		goto out;
+		return sum;
 
-	dir = fdopendir(fd);
-	if (dir == NULL) {
-		close(fd);
-		goto out;
-	}
+	dir = fdopendir(move_fd(fd));
+	if (!dir)
+		return sum;
 
 	while (((file = readdir(dir)) != NULL) && depth > 0) {
-		if (strncmp(file->d_name, ".", 1) == 0)
+		if (strcmp(file->d_name, ".") == 0)
 			continue;
-		if (strncmp(file->d_name, "..", 1) == 0)
+
+		if (strcmp(file->d_name, "..") == 0)
 			continue;
+
 		if (file->d_type == DT_DIR) {
+			__do_free char *path_dir = NULL;
+
 			/* path + '/' + d_name +/0 */
-			do {
-				path_dir = malloc(strlen(path) + 2 + sizeof(file->d_name));
-			} while (!path_dir);
+			path_dir = malloc(strlen(path) + 2 + sizeof(file->d_name));
+			if (!path_dir)
+				return sum;
+
 			strcpy(path_dir, path);
 			strcat(path_dir, "/");
 			strcat(path_dir, file->d_name);
 			pd = depth - 1;
 			sum = calc_pid(pid_buf, path_dir, pd, sum, cfd);
-			free(path_dir);
 		}
 	}
-	closedir(dir);
 
 	strcat(path, "/cgroup.procs");
 	fd = openat(cfd, path, O_RDONLY);
 	if (fd < 0)
-		goto out;
+		return sum;
 
-	f = fdopen(fd, "r");
-	if (!f) {
-		close(fd);
-		goto out;
-	}
+	f = fdopen(move_fd(fd), "r");
+	if (!f)
+		return sum;
 
 	while (getline(&line, &linelen, f) != -1) {
-		do {
-			pid = realloc(*pid_buf, sizeof(char *) * (sum + 1));
-		} while (!pid);
+		pid = realloc(*pid_buf, sizeof(char *) * (sum + 1));
+		if (!pid)
+			return sum;
 		*pid_buf = pid;
-		do {
-			*(*pid_buf + sum) = malloc(strlen(line) + 1);
-		} while (*(*pid_buf + sum) == NULL);
+
+		*(*pid_buf + sum) = malloc(strlen(line) + 1);
+		if (!*(*pid_buf + sum))
+			return sum;
+
 		strcpy(*(*pid_buf + sum), line);
 		sum++;
 	}
-	fclose(f);
-out:
-	if (line)
-		free(line);
-	free(path);
+
 	return sum;
 }
+
 /*
  * calc_load calculates the load according to the following formula:
  * load1 = load0 * exp + active * (1 - exp)
@@ -5474,25 +5394,26 @@ calc_load(unsigned long load, unsigned long exp, unsigned long active)
  */
 static int refresh_load(struct load_node *p, char *path)
 {
-	FILE *f = NULL;
+	__do_free char *line = NULL;
 	char **idbuf;
 	char proc_path[256];
 	int i, ret, run_pid = 0, total_pid = 0, last_pid = 0;
-	char *line = NULL;
 	size_t linelen = 0;
 	int sum, length;
-	DIR *dp;
 	struct dirent *file;
 
-	do {
-		idbuf = malloc(sizeof(char *));
-	} while (!idbuf);
+	idbuf = malloc(sizeof(char *));
+	if (!idbuf)
+		return -1;
+
 	sum = calc_pid(&idbuf, path, DEPTH_DIR, 0, p->cfd);
 	/*  normal exit  */
 	if (sum == 0)
 		goto out;
 
 	for (i = 0; i < sum; i++) {
+		__do_closedir DIR *dp = NULL;
+
 		/*clean up '\n' */
 		length = strlen(idbuf[i])-1;
 		idbuf[i][length] = '\0';
@@ -5510,6 +5431,8 @@ static int refresh_load(struct load_node *p, char *path)
 			continue;
 		}
 		while ((file = readdir(dp)) != NULL) {
+			__do_fclose FILE *f = NULL;
+
 			if (strncmp(file->d_name, ".", 1) == 0)
 				continue;
 			if (strncmp(file->d_name, "..", 1) == 0)
@@ -5524,9 +5447,9 @@ static int refresh_load(struct load_node *p, char *path)
 				lxcfs_error("%s\n", "snprintf() failed in refresh_load.");
 				i = sum;
 				sum = -1;
-				closedir(dp);
 				goto err_out;
 			}
+
 			f = fopen(proc_path, "r");
 			if (f != NULL) {
 				while (getline(&line, &linelen, f) != -1) {
@@ -5534,12 +5457,11 @@ static int refresh_load(struct load_node *p, char *path)
 					if ((line[0] == 'S') && (line[1] == 't'))
 						break;
 				}
+
 			if ((line[7] == 'R') || (line[7] == 'D'))
 				run_pid++;
-			fclose(f);
 			}
 		}
-		closedir(dp);
 	}
 	/*Calculate the loadavg.*/
 	p->avenrun[0] = calc_load(p->avenrun[0], EXP_1, run_pid);
@@ -5549,7 +5471,6 @@ static int refresh_load(struct load_node *p, char *path)
 	p->total_pid = total_pid;
 	p->last_pid = last_pid;
 
-	free(line);
 err_out:
 	for (; i > 0; i--)
 		free(idbuf[i-1]);
@@ -5557,13 +5478,13 @@ static int refresh_load(struct load_node *p, char *path)
 	free(idbuf);
 	return sum;
 }
+
 /*
  * Traverse the hash table and update it.
  */
 void *load_begin(void *arg)
 {
 
-	char *path = NULL;
 	int i, sum, length, ret;
 	struct load_node *f;
 	int first_node;
@@ -5583,11 +5504,13 @@ void *load_begin(void *arg)
 			f = load_hash[i].next;
 			first_node = 1;
 			while (f) {
+				__do_free char *path = NULL;
+
 				length = strlen(f->cg) + 2;
-				do {
 					/* strlen(f->cg) + '.' or '' + \0 */
-					path = malloc(length);
-				} while (!path);
+				path = malloc(length);
+				if  (!path)
+					goto out;
 
 				ret = snprintf(path, length, "%s%s", dot_or_empty(f->cg), f->cg);
 				if (ret < 0 || ret > length - 1) {
@@ -5595,13 +5518,12 @@ void *load_begin(void *arg)
 					lxcfs_error("Refresh node %s failed for snprintf().\n", f->cg);
 					goto out;
 				}
+
 				sum = refresh_load(f, path);
-				if (sum == 0) {
+				if (sum == 0)
 					f = del_node(f, i);
-				} else {
+				else
 out:					f = f->next;
-				}
-				free(path);
 				/* load_hash[i].lock locks only on the first node.*/
 				if (first_node == 1) {
 					first_node = 0;


More information about the lxc-devel mailing list