[lxc-devel] [lxcfs/master] proc_fuse: improve /proc/meminfo

brauner on Github lxc-bot at linuxcontainers.org
Fri Mar 20 09:48:26 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/20200320/e7badc03/attachment-0001.bin>
-------------- next part --------------
From 6d025f61da2045ee65c56ff13ee27cb515f39381 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 20 Mar 2020 10:46:40 +0100
Subject: [PATCH] proc_fuse: improve /proc/meminfo

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 src/proc_fuse.c | 32 ++++++++++++++++++--------------
 src/utils.c     | 25 ++++++++++++++++++++++++-
 src/utils.h     |  1 +
 3 files changed, 43 insertions(+), 15 deletions(-)

diff --git a/src/proc_fuse.c b/src/proc_fuse.c
index c3870fb..233d5e0 100644
--- a/src/proc_fuse.c
+++ b/src/proc_fuse.c
@@ -1075,10 +1075,10 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
 
 	ret = cgroup_ops->get_memory_current(cgroup_ops, cgroup, &memusage_str);
 	if (ret < 0)
-		return 0;
+		return read_file_fuse("/proc/meminfo", buf, size, d);
 
 	if (!cgroup_parse_memory_stat(cgroup, &mstat))
-		return 0;
+		return read_file_fuse("/proc/meminfo", buf, size, d);
 
 	/*
 	 * Following values are allowed to fail, because swapaccount might be
@@ -1087,20 +1087,23 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
 	ret = cgroup_ops->get_memory_swap_max(cgroup_ops, cgroup, &memswlimit_str);
 	if (ret >= 0)
 		ret = cgroup_ops->get_memory_swap_current(cgroup_ops, cgroup, &memswusage_str);
-	if (ret >= 0) {
-		memswlimit = get_min_memlimit(cgroup, true);
-		memswusage = strtoull(memswusage_str, NULL, 10);
-		memswlimit = memswlimit / 1024;
-		memswusage = memswusage / 1024;
-	}
+	if (ret < 0)
+		return read_file_fuse("/proc/meminfo", buf, size, d);
 
-	memusage = strtoull(memusage_str, NULL, 10);
+	memswlimit = get_min_memlimit(cgroup, true);
+	memswlimit = memswlimit / 1024;
+	if (safe_uint64(memswusage_str, &memswusage, 10) < 0)
+		memswusage = 0;
+	memswusage = memswusage / 1024;
+
+	if (safe_uint64(memusage_str, &memusage, 10) < 0)
+		memusage = 0;
 	memlimit /= 1024;
 	memusage /= 1024;
 
 	f = fopen_cached("/proc/meminfo", "re", &fopen_cache);
 	if (!f)
-		return 0;
+		return read_file_fuse("/proc/meminfo", buf, size, d);
 
 	while (getline(&line, &linelen, f) != -1) {
 		ssize_t l;
@@ -1119,10 +1122,11 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
 		} else if (startswith(line, "MemAvailable:")) {
 			snprintf(lbuf, 100, "MemAvailable:   %8" PRIu64 " kB\n", memlimit - memusage + mstat.total_cache / 1024);
 			printme = lbuf;
-		} else if (startswith(line, "SwapTotal:") && memswlimit > 0 &&
-			   opts && opts->swap_off == false) {
-			memswlimit -= memlimit;
-			snprintf(lbuf, 100, "SwapTotal:      %8" PRIu64 " kB\n", memswlimit);
+		} else if (startswith(line, "SwapTotal:") && memswlimit > 0 && opts && opts->swap_off == false) {
+			snprintf(lbuf, 100, "SwapTotal:      %8" PRIu64 " kB\n",
+				 (memswlimit >= memlimit)
+				     ? (memswlimit - memlimit)
+				     : 0);
 			printme = lbuf;
 		} else if (startswith(line, "SwapTotal:") && opts && opts->swap_off == true) {
 			snprintf(lbuf, 100, "SwapTotal:      %8" PRIu64 " kB\n", (uint64_t)0);
diff --git a/src/utils.c b/src/utils.c
index fe83aef..0be997c 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -10,13 +10,13 @@
 
 #define _FILE_OFFSET_BITS 64
 
+#include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <fuse.h>
 #include <inttypes.h>
 #include <sched.h>
 #include <stdarg.h>
-#include <stdio.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -520,3 +520,26 @@ ssize_t write_nointr(int fd, const void *buf, size_t count)
 
 	return ret;
 }
+
+int safe_uint64(const char *numstr, uint64_t *converted, int base)
+{
+	char *err = NULL;
+	uint64_t u;
+
+	while (isspace(*numstr))
+		numstr++;
+
+	if (*numstr == '-')
+		return -EINVAL;
+
+	errno = 0;
+	u = strtoull(numstr, &err, base);
+	if (errno == ERANGE && u == UINT64_MAX)
+		return -ERANGE;
+
+	if (err == numstr || *err != '\0')
+		return -EINVAL;
+
+	*converted = u;
+	return 0;
+}
diff --git a/src/utils.h b/src/utils.h
index 39a2943..29c87dc 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -75,5 +75,6 @@ extern FILE *fopen_cached(const char *path, const char *mode,
 			  void **caller_freed_buffer);
 extern FILE *fdopen_cached(int fd, const char *mode, void **caller_freed_buffer);
 extern ssize_t write_nointr(int fd, const void *buf, size_t count);
+extern int safe_uint64(const char *numstr, uint64_t *converted, int base);
 
 #endif /* __LXCFS_UTILS_H */


More information about the lxc-devel mailing list