From 7a98cab187f452f15f72a2aebebd0e5084f2b602 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Sun, 28 Jun 2015 00:00:00 -0500 Subject: [PATCH] library: add missing meminfo logic, improve efficiency This patch fills in some missing fields which have top dependencies. Additionally, I've tried to mirror those calculations Jaromir added for release 3.3.10. The one calculation that remains missing is 'available' memory for some kernels. For this API, we'll use a fall-back. Lastly the lxc safeguards which were recently added to the old procps library were incorporated here as well. Signed-off-by: Jim Warner --- proc/meminfo.c | 101 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 72 insertions(+), 29 deletions(-) diff --git a/proc/meminfo.c b/proc/meminfo.c index beca4b22..ad332c59 100644 --- a/proc/meminfo.c +++ b/proc/meminfo.c @@ -46,6 +46,7 @@ struct meminfo_data { unsigned long shared; unsigned long total; unsigned long used; + unsigned long slab; unsigned long swap_free; unsigned long swap_total; unsigned long swap_used; @@ -95,6 +96,7 @@ PROCPS_EXPORT int procps_meminfo_read ( char *head, *tail; int size; unsigned long *valptr; + signed long mem_used; if (info == NULL) return -1; @@ -121,45 +123,86 @@ PROCPS_EXPORT int procps_meminfo_read ( break; *tail = '\0'; valptr = NULL; - if (0 == strcmp(head, "Active:")) { - valptr = &(info->data.active); - } else if (0 == strcmp(head, "Inactive:")) { - valptr = &(info->data.inactive); - } else if (0 == strcmp(head, "HighFree:")) { - valptr = &(info->data.high_free); - } else if (0 == strcmp(head, "HighTotal:")) { - valptr = &(info->data.high_total); - } else if (0 == strcmp(head, "LowFree:")) { - valptr = &(info->data.low_free); - } else if (0 == strcmp(head, "LowTotal:")) { - valptr = &(info->data.low_total); - } else if (0 == strcmp(head, "MemAvailable:")) { - valptr = &(info->data.available); - } else if (0 == strcmp(head, "Buffers:")) { - valptr = &(info->data.buffers); - } else if (0 == strcmp(head, "Cached:")) { - valptr = &(info->data.cached); - } else if (0 == strcmp(head, "MemFree:")) { - valptr = &(info->data.free); - } else if (0 == strcmp(head, "Shmem:")) { - valptr = &(info->data.shared); - } else if (0 == strcmp(head, "MemTotal:")) { - valptr = &(info->data.total); - } else if (0 == strcmp(head, "SwapFree:")) { - valptr = &(info->data.swap_free); - } else if (0 == strcmp(head, "SwapTotal:")) { - valptr = &(info->data.swap_total); + switch (*head) { + case 'A': + if (0 == strcmp(head, "Active:")) + valptr = &(info->data.active); + break; + case 'B': + if (0 == strcmp(head, "Buffers:")) + valptr = &(info->data.buffers); + break; + case 'C': + if (0 == strcmp(head, "Cached:")) + valptr = &(info->data.cached); + break; + case 'H': + if (0 == strcmp(head, "HighFree:")) + valptr = &(info->data.high_free); + else if (0 == strcmp(head, "HighTotal:")) + valptr = &(info->data.high_total); + break; + case 'I': + if (0 == strcmp(head, "Inactive:")) + valptr = &(info->data.inactive); + break; + case 'L': + if (0 == strcmp(head, "LowFree:")) + valptr = &(info->data.low_free); + else if (0 == strcmp(head, "LowTotal:")) + valptr = &(info->data.low_total); + break; + case 'M': + if (0 == strcmp(head, "MemAvailable:")) + valptr = &(info->data.available); + else if (0 == strcmp(head, "MemFree:")) + valptr = &(info->data.free); + else if (0 == strcmp(head, "MemTotal:")) + valptr = &(info->data.total); + break; + case 'S': + if (0 == strcmp(head, "Slab:")) + valptr = &(info->data.slab); + else if (0 == strcmp(head, "SwapFree:")) + valptr = &(info->data.swap_free); + else if (0 == strcmp(head, "SwapTotal:")) + valptr = &(info->data.swap_total); + else if (0 == strcmp(head, "Shmem:")) + valptr = &(info->data.shared); + break; + default: + break; } head = tail+1; if (valptr) { *valptr = strtoul(head, &tail, 10); } - tail = strchr(head, '\n'); if (!tail) break; head = tail + 1; } while(tail); + + if (0 == info->data.low_total) { + info->data.low_total = info->data.total; + info->data.low_free = info->data.free; + } + if (0 == info->data.available) { + info->data.available = info->data.free; + } + info->data.cached += info->data.slab; + info->data.swap_used = info->data.swap_total - info->data.swap_free; + + /* if 'available' is greater than 'total' or our calculation of mem_used + overflows, that's symptomatic of running within a lxc container where + such values will be dramatically distorted over those of the host. */ + if (info->data.available > info->data.total) + info->data.available = info->data.free; + mem_used = info->data.total - info->data.free - info->data.cached - info->data.buffers; + if (mem_used < 0) + mem_used = info->data.total - info->data.free; + info->data.used = (unsigned long)mem_used; + return 0; }