[lxc-devel] [lxcfs/master] performance tweaks and leak fixes

brauner on Github lxc-bot at linuxcontainers.org
Fri Jun 5 11:51:48 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/20200605/f5ff8cc1/attachment-0001.bin>
-------------- next part --------------
From 8a07696e042fa5a3aa258bdce4ffb9f7cff66d9a Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 4 Jun 2020 20:14:49 +0200
Subject: [PATCH 01/15] bindings: s/get_init_pid_for_task()/scm_init_pid()/g

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/bindings.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/bindings.c b/src/bindings.c
index b2a5991..3c298b7 100644
--- a/src/bindings.c
+++ b/src/bindings.c
@@ -391,7 +391,7 @@ static void write_task_init_pid_exit(int sock, pid_t target)
 	}
 }
 
-static pid_t get_init_pid_for_task(pid_t task)
+static pid_t scm_init_pid(pid_t task)
 {
 	char v = '0';
 	pid_t pid_ret = -1;
@@ -447,7 +447,7 @@ pid_t lookup_initpid_in_store(pid_t pid)
 		/* release the mutex as the following call is expensive */
 		store_unlock();
 
-		hashed_pid = get_init_pid_for_task(pid);
+		hashed_pid = scm_init_pid(pid);
 
 		store_lock();
 

From 61ef3c5ce5675a43b2a982797025647bdcf02d94 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Jun 2020 11:42:31 +0200
Subject: [PATCH 02/15] proc_loadavg: don't leak getline() memory in calc_pid()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/proc_loadavg.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/proc_loadavg.c b/src/proc_loadavg.c
index a8c01d0..77ce2cc 100644
--- a/src/proc_loadavg.c
+++ b/src/proc_loadavg.c
@@ -282,14 +282,13 @@ int proc_loadavg_read(char *buf, size_t size, off_t offset,
  */
 static int calc_pid(char ***pid_buf, const char *dpath, int depth, int sum, int cfd)
 {
-	__do_free char *path = NULL;
+	__do_free char *line = NULL, *path = NULL;
 	__do_free void *fdopen_cache = NULL;
 	__do_close int fd = -EBADF;
 	__do_fclose FILE *f = NULL;
 	__do_closedir DIR *dir = NULL;
 	struct dirent *file;
 	size_t linelen = 0;
-	char *line = NULL;
 	int pd;
 	char **pid;
 

From bef38939a63eb60fca311a9dddc5159edde15ac1 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Jun 2020 11:43:10 +0200
Subject: [PATCH 03/15] proc_loadavg: ensure pointer is NULL when passing to
 calc_pid()

We passed down an uninitialized pointer that we then pass to realloc()
which is problematic since it contains garbage.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/proc_loadavg.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/proc_loadavg.c b/src/proc_loadavg.c
index 77ce2cc..d1b61e5 100644
--- a/src/proc_loadavg.c
+++ b/src/proc_loadavg.c
@@ -385,8 +385,7 @@ static uint64_t calc_load(uint64_t load, uint64_t exp, uint64_t active)
  */
 static int refresh_load(struct load_node *p, const char *path)
 {
-	__do_free char *line = NULL;
-	char **idbuf;
+	char **idbuf = NULL;
 	char proc_path[STRLITERALLEN("/proc//task//status") +
 		       2 * INTTYPE_TO_STRLEN(pid_t) + 1];
 	int i, ret, run_pid = 0, total_pid = 0, last_pid = 0;

From c0e081ce68aca219346a7933bba137ad9e4cbee2 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Jun 2020 11:44:37 +0200
Subject: [PATCH 04/15] proc_loadavg: don't leak getline() memory

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/proc_loadavg.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/proc_loadavg.c b/src/proc_loadavg.c
index d1b61e5..0bc58dd 100644
--- a/src/proc_loadavg.c
+++ b/src/proc_loadavg.c
@@ -420,6 +420,7 @@ static int refresh_load(struct load_node *p, const char *path)
 		}
 
 		while ((file = readdir(dp)) != NULL) {
+			__do_free char *line = NULL;
 			__do_fclose FILE *f = NULL;
 
 			if (strcmp(file->d_name, ".") == 0)

From 12cf83f46e89337d7425a8a30876d8c81334e1d6 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Jun 2020 11:44:56 +0200
Subject: [PATCH 05/15] proc_loadavg: replace malloc() with asprintf() in
 calc_pid()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/proc_loadavg.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/proc_loadavg.c b/src/proc_loadavg.c
index 0bc58dd..ab420c9 100644
--- a/src/proc_loadavg.c
+++ b/src/proc_loadavg.c
@@ -317,15 +317,15 @@ static int calc_pid(char ***pid_buf, const char *dpath, int depth, int sum, int
 
 		if (file->d_type == DT_DIR) {
 			__do_free char *path_dir = NULL;
+			int ret;
 
 			/* path + '/' + d_name +/0 */
-			path_dir = malloc(strlen(path) + 2 + sizeof(file->d_name));
-			if (!path_dir)
+			ret = asprintf(&path_dir, "%s/%s", path, file->d_name);
+			if (ret < 0) {
+				path_dir = NULL;
 				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);
 		}

From 0d64d47406ca4ff5aa01d54708d9a4523676ff75 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Jun 2020 12:12:32 +0200
Subject: [PATCH 06/15] macro: use ISO C compatible __typeof__

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/macro.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/macro.h b/src/macro.h
index aba00bf..da7936a 100644
--- a/src/macro.h
+++ b/src/macro.h
@@ -85,7 +85,7 @@
 
 #define move_ptr(ptr)                                 \
 	({                                            \
-		typeof(ptr) __internal_ptr__ = (ptr); \
+		__typeof__(ptr) __internal_ptr__ = (ptr); \
 		(ptr) = NULL;                         \
 		__internal_ptr__;                     \
 	})

From 1f342679fcde66ef9fd7355660bd5655c02244b4 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Jun 2020 12:13:01 +0200
Subject: [PATCH 07/15] proc_loadavg(): use strdup() in calc_pid()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/proc_loadavg.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/src/proc_loadavg.c b/src/proc_loadavg.c
index ab420c9..8bd0901 100644
--- a/src/proc_loadavg.c
+++ b/src/proc_loadavg.c
@@ -290,7 +290,6 @@ static int calc_pid(char ***pid_buf, const char *dpath, int depth, int sum, int
 	struct dirent *file;
 	size_t linelen = 0;
 	int pd;
-	char **pid;
 
 	/* path = dpath + "/cgroup.procs" + /0 */
 	path = malloc(strlen(dpath) + 20);
@@ -341,16 +340,18 @@ static int calc_pid(char ***pid_buf, const char *dpath, int depth, int sum, int
 		return sum;
 
 	while (getline(&line, &linelen, f) != -1) {
+		__do_free char *task_pid = NULL;
+		char **pid;
+
+		task_pid = strdup(line);
+		if (!task_pid)
+			return sum;
+
 		pid = realloc(*pid_buf, sizeof(char *) * (sum + 1));
 		if (!pid)
 			return sum;
 		*pid_buf = pid;
-
-		*(*pid_buf + sum) = malloc(strlen(line) + 1);
-		if (!*(*pid_buf + sum))
-			return sum;
-
-		strcpy(*(*pid_buf + sum), line);
+		*(*pid_buf + sum) = move_ptr(task_pid);
 		sum++;
 	}
 

From e771a80bb39141466dad33fd01247ef7efe63c60 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Jun 2020 12:24:15 +0200
Subject: [PATCH 08/15] proc_loadavg: simplify calc_pid()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/proc_loadavg.c | 26 ++++++--------------------
 1 file changed, 6 insertions(+), 20 deletions(-)

diff --git a/src/proc_loadavg.c b/src/proc_loadavg.c
index 8bd0901..62e9fe5 100644
--- a/src/proc_loadavg.c
+++ b/src/proc_loadavg.c
@@ -280,7 +280,7 @@ int proc_loadavg_read(char *buf, size_t size, off_t offset,
  * @sum : return the number of pid.
  * @cfd : the file descriptor of the mounted cgroup. eg: /sys/fs/cgroup/cpu
  */
-static int calc_pid(char ***pid_buf, const char *dpath, int depth, int sum, int cfd)
+static int calc_pid(char ***pid_buf, const char *rel_path, int depth, int sum, int cfd)
 {
 	__do_free char *line = NULL, *path = NULL;
 	__do_free void *fdopen_cache = NULL;
@@ -291,13 +291,7 @@ static int calc_pid(char ***pid_buf, const char *dpath, int depth, int sum, int
 	size_t linelen = 0;
 	int pd;
 
-	/* path = dpath + "/cgroup.procs" + /0 */
-	path = malloc(strlen(dpath) + 20);
-	if (!path)
-		return sum;
-
-	strcpy(path, dpath);
-	fd = openat(cfd, path, O_RDONLY | O_CLOEXEC);
+	fd = openat(cfd, rel_path, O_RDONLY | O_CLOEXEC);
 	if (fd < 0)
 		return sum;
 
@@ -315,22 +309,14 @@ static int calc_pid(char ***pid_buf, const char *dpath, int depth, int sum, int
 			continue;
 
 		if (file->d_type == DT_DIR) {
-			__do_free char *path_dir = NULL;
-			int ret;
-
-			/* path + '/' + d_name +/0 */
-			ret = asprintf(&path_dir, "%s/%s", path, file->d_name);
-			if (ret < 0) {
-				path_dir = NULL;
-				return sum;
-			}
-
+			__do_free char *path_next = NULL;
+			path_next = must_make_path(rel_path, "/", file->d_name, NULL);
 			pd = depth - 1;
-			sum = calc_pid(pid_buf, path_dir, pd, sum, cfd);
+			sum = calc_pid(pid_buf, path_next, pd, sum, cfd);
 		}
 	}
 
-	strcat(path, "/cgroup.procs");
+	path = must_make_path(rel_path, "/cgroup.procs", NULL);
 	fd = openat(cfd, path, O_RDONLY | O_CLOEXEC);
 	if (fd < 0)
 		return sum;

From c8f77ce49be97e3535d3ade55a05feedd7bbad4e Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Jun 2020 12:41:00 +0200
Subject: [PATCH 09/15] bindings: wipe initpid cache on library reload

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/bindings.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/src/bindings.c b/src/bindings.c
index 3c298b7..55c3500 100644
--- a/src/bindings.c
+++ b/src/bindings.c
@@ -251,6 +251,24 @@ static void prune_initpid_store(void)
 	}
 }
 
+static void clear_initpid_store(void)
+{
+	store_lock();
+	for (int i = 0; i < PIDNS_HASH_SIZE; i++) {
+		for (struct pidns_init_store *entry = pidns_hash_table[i]; entry;) {
+			struct pidns_init_store *cur = entry;
+
+			lxcfs_debug("Removed cache entry for pid %d to init pid cache", cur->initpid);
+
+			pidns_hash_table[i] = entry->next;
+			entry = entry->next;
+			close_prot_errno_disarm(cur->init_pidfd);
+			free_disarm(cur);
+		}
+	}
+	store_unlock();
+}
+
 /* Must be called under store_lock */
 static void save_initpid(ino_t pidns_inode, pid_t pid)
 {
@@ -838,6 +856,7 @@ static void __attribute__((destructor)) lxcfs_exit(void)
 {
 	lxcfs_info("Running destructor %s", __func__);
 
+	clear_initpid_store();
 	free_cpuview();
 	cgroup_exit(cgroup_ops);
 }

From 35acc24740ee0434936fb34cd72ec2fd5754d6b2 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Jun 2020 12:52:12 +0200
Subject: [PATCH 10/15] bindings: avoid dynamic stack allocations in clone()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/bindings.c | 93 ++++++++++++++++++++++++++++++++++++++------------
 src/macro.h    |  4 +++
 2 files changed, 76 insertions(+), 21 deletions(-)

diff --git a/src/bindings.c b/src/bindings.c
index 55c3500..28da74b 100644
--- a/src/bindings.c
+++ b/src/bindings.c
@@ -334,9 +334,8 @@ static pid_t lookup_verify_initpid(ino_t pidns_inode)
 	return ret_errno(ESRCH);
 }
 
-static int send_creds_clone_wrapper(void *arg)
+static bool send_creds_ok(int sock_fd)
 {
-	int sock = PTR_TO_INT(arg);
 	char v = '1'; /* we are the child */
 	struct ucred cred = {
 	    .uid = 0,
@@ -344,29 +343,76 @@ static int send_creds_clone_wrapper(void *arg)
 	    .pid = 1,
 	};
 
-	return send_creds(sock, &cred, v, true) != SEND_CREDS_OK;
+	return send_creds(sock_fd, &cred, v, true) == SEND_CREDS_OK;
 }
 
-/*
- * Let's use the "standard stack limit" (i.e. glibc thread size default) for
- * stack sizes: 8MB.
- */
-#define __LXCFS_STACK_SIZE (8 * 1024 * 1024)
-pid_t lxcfs_clone(int (*fn)(void *), void *arg, int flags)
+__returns_twice pid_t lxcfs_raw_clone(unsigned long flags, int *pidfd)
 {
-	pid_t ret;
-	void *stack;
+	/*
+	 * These flags don't interest at all so we don't jump through any hoops
+	 * of retrieving them and passing them to the kernel.
+	 */
+	errno = EINVAL;
+	if ((flags & (CLONE_VM | CLONE_PARENT_SETTID | CLONE_CHILD_SETTID |
+		      CLONE_CHILD_CLEARTID | CLONE_SETTLS)))
+		return -EINVAL;
+
+#if defined(__s390x__) || defined(__s390__) || defined(__CRIS__)
+	/* On s390/s390x and cris the order of the first and second arguments
+	 * of the system call is reversed.
+	 */
+	return syscall(__NR_clone, NULL, flags | SIGCHLD, pidfd);
+#elif defined(__sparc__) && defined(__arch64__)
+	{
+		/*
+		 * sparc64 always returns the other process id in %o0, and a
+		 * boolean flag whether this is the child or the parent in %o1.
+		 * Inline assembly is needed to get the flag returned in %o1.
+		 */
+		register long g1 asm("g1") = __NR_clone;
+		register long o0 asm("o0") = flags | SIGCHLD;
+		register long o1 asm("o1") = 0; /* is parent/child indicator */
+		register long o2 asm("o2") = (unsigned long)pidfd;
+		long is_error, retval, in_child;
+		pid_t child_pid;
+
+		asm volatile(
+#if defined(__arch64__)
+		    "t 0x6d\n\t" /* 64-bit trap */
+#else
+		    "t 0x10\n\t" /* 32-bit trap */
+#endif
+		    /*
+		     * catch errors: On sparc, the carry bit (csr) in the
+		     * processor status register (psr) is used instead of a
+		     * full register.
+		     */
+		    "addx %%g0, 0, %%g1"
+		    : "=r"(g1), "=r"(o0), "=r"(o1), "=r"(o2) /* outputs */
+		    : "r"(g1), "r"(o0), "r"(o1), "r"(o2)     /* inputs */
+		    : "%cc");				     /* clobbers */
+
+		is_error = g1;
+		retval = o0;
+		in_child = o1;
+
+		if (is_error) {
+			errno = retval;
+			return -1;
+		}
 
-	stack = malloc(__LXCFS_STACK_SIZE);
-	if (!stack)
-		return ret_errno(ENOMEM);
+		if (in_child)
+			return 0;
 
-#ifdef __ia64__
-	ret = __clone2(fn, stack, __LXCFS_STACK_SIZE, flags | SIGCHLD, arg, NULL);
+		child_pid = retval;
+		return child_pid;
+	}
+#elif defined(__ia64__)
+	/* On ia64 the stack and stack size are passed as separate arguments. */
+	return syscall(__NR_clone, flags | SIGCHLD, NULL, prctl_arg(0), pidfd);
 #else
-	ret = clone(fn, stack + __LXCFS_STACK_SIZE, flags | SIGCHLD, arg, NULL);
+	return syscall(__NR_clone, flags | SIGCHLD, NULL, pidfd);
 #endif
-	return ret;
 }
 
 #define LXCFS_PROC_PID_NS_LEN                                    \
@@ -397,16 +443,21 @@ static void write_task_init_pid_exit(int sock, pid_t target)
 	if (setns(fd, 0))
 		log_exit("Failed to setns to pid namespace of process %d", target);
 
-	pid = lxcfs_clone(send_creds_clone_wrapper, INT_TO_PTR(sock), 0);
+	pid = lxcfs_raw_clone(0, NULL);
 	if (pid < 0)
 		_exit(EXIT_FAILURE);
 
-	if (pid != 0) {
-		if (!wait_for_pid(pid))
+	if (pid == 0) {
+		if (!send_creds_ok(sock))
 			_exit(EXIT_FAILURE);
 
 		_exit(EXIT_SUCCESS);
 	}
+
+	if (!wait_for_pid(pid))
+		_exit(EXIT_FAILURE);
+
+	_exit(EXIT_SUCCESS);
 }
 
 static pid_t scm_init_pid(pid_t task)
diff --git a/src/macro.h b/src/macro.h
index da7936a..05eee65 100644
--- a/src/macro.h
+++ b/src/macro.h
@@ -139,4 +139,8 @@
 
 #define __lxcfs_fuse_ops
 
+#ifndef __returns_twice
+#define __returns_twice __attribute__((returns_twice))
+#endif
+
 #endif /* __LXCFS_MACRO_H */

From b58c203bc7c9c10b0460a6431f71de4ac35bd693 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Jun 2020 12:59:05 +0200
Subject: [PATCH 11/15] lxcfs: free opts on lxcfs binary exit

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/lxcfs.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/lxcfs.c b/src/lxcfs.c
index ed0592a..a6b4583 100644
--- a/src/lxcfs.c
+++ b/src/lxcfs.c
@@ -1198,6 +1198,7 @@ int main(int argc, char *argv[])
 		dlclose(dlopen_handle);
 	if (pidfile)
 		unlink(pidfile);
+	free(opts);
 	close_prot_errno_disarm(pidfile_fd);
 	exit(ret);
 }

From f1a33645c587c68f84ca20e67645ce5bb08ad398 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Jun 2020 13:11:27 +0200
Subject: [PATCH 12/15] proc_fuse: use zalloc()

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/proc_fuse.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/src/proc_fuse.c b/src/proc_fuse.c
index 41ac0b1..e185b98 100644
--- a/src/proc_fuse.c
+++ b/src/proc_fuse.c
@@ -161,20 +161,17 @@ __lxcfs_fuse_ops int proc_open(const char *path, struct fuse_file_info *fi)
 	if (type == -1)
 		return -ENOENT;
 
-	info = malloc(sizeof(*info));
+	info = zalloc(sizeof(*info));
 	if (!info)
 		return -ENOMEM;
 
-	memset(info, 0, sizeof(*info));
 	info->type = type;
 
 	info->buflen = get_procfile_size(path) + BUF_RESERVE_SIZE;
 
-	info->buf = malloc(info->buflen);
+	info->buf = zalloc(info->buflen);
 	if (!info->buf)
 		return -ENOMEM;
-
-	memset(info->buf, 0, info->buflen);
 	/* set actual size to buffer size */
 	info->size = info->buflen;
 

From cb4bf06be21ad38588d81d7ef24203cb61fd7225 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Jun 2020 13:11:39 +0200
Subject: [PATCH 13/15] proc_loadavg: use must_* alloc helpers

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/proc_loadavg.c | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/src/proc_loadavg.c b/src/proc_loadavg.c
index 62e9fe5..6a0b617 100644
--- a/src/proc_loadavg.c
+++ b/src/proc_loadavg.c
@@ -220,15 +220,8 @@ int proc_loadavg_read(char *buf, size_t size, off_t offset,
 			return read_file_fuse("/proc/loadavg", buf, size, d);
 		}
 
-		do {
-			n = malloc(sizeof(struct load_node));
-		} while (!n);
-
-		do {
-			n->cg = malloc(strlen(cg) + 1);
-		} while (!n->cg);
-
-		strcpy(n->cg, cg);
+		n = must_realloc(NULL, sizeof(struct load_node));
+		n->cg = must_copy_string(cg);
 		n->avenrun[0] = 0;
 		n->avenrun[1] = 0;
 		n->avenrun[2] = 0;

From cde2554cc26cd69e973a3a91a3ef13b0f5aaa160 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Jun 2020 13:23:31 +0200
Subject: [PATCH 14/15] proc_loadavg: remove dummy variable

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/proc_loadavg.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/proc_loadavg.c b/src/proc_loadavg.c
index 6a0b617..6125e19 100644
--- a/src/proc_loadavg.c
+++ b/src/proc_loadavg.c
@@ -172,7 +172,6 @@ int proc_loadavg_read(char *buf, size_t size, off_t offset,
 	struct file_info *d = INTTYPE_TO_PTR(fi->fh);
 	pid_t initpid;
 	ssize_t total_len = 0;
-	char *cache = d->buf;
 	struct load_node *n;
 	int hash;
 	int cfd;
@@ -189,7 +188,7 @@ int proc_loadavg_read(char *buf, size_t size, off_t offset,
 
 		left = d->size - offset;
 		total_len = left > size ? size : left;
-		memcpy(buf, cache + offset, total_len);
+		memcpy(buf, d->buf + offset, total_len);
 
 		return total_len;
 	}

From 70f7563e44ffd06427f364a3b4d1008308883858 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Jun 2020 13:24:33 +0200
Subject: [PATCH 15/15] proc_loadavg: avoid needless memory allocation

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/proc_loadavg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/proc_loadavg.c b/src/proc_loadavg.c
index 6125e19..7a7a39e 100644
--- a/src/proc_loadavg.c
+++ b/src/proc_loadavg.c
@@ -220,7 +220,7 @@ int proc_loadavg_read(char *buf, size_t size, off_t offset,
 		}
 
 		n = must_realloc(NULL, sizeof(struct load_node));
-		n->cg = must_copy_string(cg);
+		n->cg = move_ptr(cg);
 		n->avenrun[0] = 0;
 		n->avenrun[1] = 0;
 		n->avenrun[2] = 0;


More information about the lxc-devel mailing list