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 <james.warner@comcast.net>
This commit is contained in:
Jim Warner 2015-06-28 00:00:00 -05:00 committed by Craig Small
parent 500a901475
commit 7a98cab187

View File

@ -46,6 +46,7 @@ struct meminfo_data {
unsigned long shared; unsigned long shared;
unsigned long total; unsigned long total;
unsigned long used; unsigned long used;
unsigned long slab;
unsigned long swap_free; unsigned long swap_free;
unsigned long swap_total; unsigned long swap_total;
unsigned long swap_used; unsigned long swap_used;
@ -95,6 +96,7 @@ PROCPS_EXPORT int procps_meminfo_read (
char *head, *tail; char *head, *tail;
int size; int size;
unsigned long *valptr; unsigned long *valptr;
signed long mem_used;
if (info == NULL) if (info == NULL)
return -1; return -1;
@ -121,45 +123,86 @@ PROCPS_EXPORT int procps_meminfo_read (
break; break;
*tail = '\0'; *tail = '\0';
valptr = NULL; valptr = NULL;
if (0 == strcmp(head, "Active:")) { switch (*head) {
valptr = &(info->data.active); case 'A':
} else if (0 == strcmp(head, "Inactive:")) { if (0 == strcmp(head, "Active:"))
valptr = &(info->data.inactive); valptr = &(info->data.active);
} else if (0 == strcmp(head, "HighFree:")) { break;
valptr = &(info->data.high_free); case 'B':
} else if (0 == strcmp(head, "HighTotal:")) { if (0 == strcmp(head, "Buffers:"))
valptr = &(info->data.high_total); valptr = &(info->data.buffers);
} else if (0 == strcmp(head, "LowFree:")) { break;
valptr = &(info->data.low_free); case 'C':
} else if (0 == strcmp(head, "LowTotal:")) { if (0 == strcmp(head, "Cached:"))
valptr = &(info->data.low_total); valptr = &(info->data.cached);
} else if (0 == strcmp(head, "MemAvailable:")) { break;
valptr = &(info->data.available); case 'H':
} else if (0 == strcmp(head, "Buffers:")) { if (0 == strcmp(head, "HighFree:"))
valptr = &(info->data.buffers); valptr = &(info->data.high_free);
} else if (0 == strcmp(head, "Cached:")) { else if (0 == strcmp(head, "HighTotal:"))
valptr = &(info->data.cached); valptr = &(info->data.high_total);
} else if (0 == strcmp(head, "MemFree:")) { break;
valptr = &(info->data.free); case 'I':
} else if (0 == strcmp(head, "Shmem:")) { if (0 == strcmp(head, "Inactive:"))
valptr = &(info->data.shared); valptr = &(info->data.inactive);
} else if (0 == strcmp(head, "MemTotal:")) { break;
valptr = &(info->data.total); case 'L':
} else if (0 == strcmp(head, "SwapFree:")) { if (0 == strcmp(head, "LowFree:"))
valptr = &(info->data.swap_free); valptr = &(info->data.low_free);
} else if (0 == strcmp(head, "SwapTotal:")) { else if (0 == strcmp(head, "LowTotal:"))
valptr = &(info->data.swap_total); 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; head = tail+1;
if (valptr) { if (valptr) {
*valptr = strtoul(head, &tail, 10); *valptr = strtoul(head, &tail, 10);
} }
tail = strchr(head, '\n'); tail = strchr(head, '\n');
if (!tail) if (!tail)
break; break;
head = tail + 1; head = tail + 1;
} while(tail); } 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; return 0;
} }