[lxc-devel] [lxcfs/master] add some metrics for meminfo
wlm86 on Github
lxc-bot at linuxcontainers.org
Tue Jan 21 03:31:57 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 420 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200120/a8b826ac/attachment.bin>
-------------- next part --------------
From 9383dbbde6776e75917c6753ea8ee22b529992c1 Mon Sep 17 00:00:00 2001
From: LiMing Wu <19092205 at suning.com>
Date: Fri, 17 Jan 2020 11:34:07 +0800
Subject: [PATCH] add some metrics for meminfo
dirty/writeback ... and so on
Signed-off-by LiMing Wu <19092205 at suning.com>
---
bindings.c | 252 ++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 171 insertions(+), 81 deletions(-)
diff --git a/bindings.c b/bindings.c
index d11f0e5..09977c8 100644
--- a/bindings.c
+++ b/bindings.c
@@ -63,6 +63,28 @@ struct cpuacct_usage {
bool online;
};
+struct memory_stat {
+ unsigned long long hierarchical_memory_limit;
+ unsigned long long hierarchical_memsw_limit;
+ unsigned long long total_cache;
+ unsigned long long total_rss;
+ unsigned long long total_rss_huge;
+ unsigned long long total_shmem;
+ unsigned long long total_mapped_file;
+ unsigned long long total_dirty;
+ unsigned long long total_writeback;
+ unsigned long long total_swap;
+ unsigned long long total_pgpgin;
+ unsigned long long total_pgpgout;
+ unsigned long long total_pgfault;
+ unsigned long long total_pgmajfault;
+ unsigned long long total_inactive_anon;
+ unsigned long long total_active_anon;
+ unsigned long long total_inactive_file;
+ unsigned long long total_active_file;
+ unsigned long long total_unevictable;
+};
+
/* The function of hash table.*/
#define LOAD_SIZE 100 /*the size of hash_table */
#define FLUSH_TIME 5 /*the flush rate */
@@ -1231,6 +1253,82 @@ void free_keys(struct cgfs_files **keys)
free(keys);
}
+bool cgfs_get_mstat(const char *controller, const char *cgroup,
+ const char *file, struct memory_stat *mstat)
+{
+ int ret, fd, cfd;
+ size_t len = 0;
+ char *fnam, *tmpc;
+
+ tmpc = find_mounted_controller(controller, &cfd);
+ if (!tmpc)
+ return false;
+
+ /* Make sure we pass a relative path to *at() family of functions.
+ * . + /cgroup + / + file + \0
+ */
+ len = strlen(cgroup) + strlen(file) + 3;
+ fnam = alloca(len);
+ ret = snprintf(fnam, len, "%s%s/%s", *cgroup == '/' ? "." : "", cgroup, file);
+ if (ret < 0 || (size_t)ret >= len)
+ return false;
+
+ fd = openat(cfd, fnam, O_RDONLY);
+ if (fd < 0)
+ return false;
+
+ FILE *f = fdopen(fd, "r");
+ len = 0;
+ char *line = NULL;
+ ssize_t linelen;
+
+ if (!f)
+ return NULL;
+
+ while ((linelen = getline(&line, &len, f)) != -1) {
+ if (strncmp(line, "hierarchical_memory_limit", 25) == 0) {
+ sscanf(line, "hierarchical_memory_limit %llu", &(mstat->hierarchical_memory_limit));
+ } else if (strncmp(line, "hierarchical_memsw_limit", 24) == 0) {
+ sscanf(line, "hierarchical_memsw_limit %llu", &(mstat->hierarchical_memsw_limit));
+ } else if (strncmp(line, "total_cache", 11) == 0) {
+ sscanf(line, "total_cache %llu", &(mstat->total_cache));
+ } else if (strncmp(line, "total_rss", 9) == 0) {
+ sscanf(line, "total_rss %llu", &(mstat->total_rss));
+ } else if (strncmp(line, "total_rss_huge", 14) == 0) {
+ sscanf(line, "total_rss_huge %llu", &(mstat->total_rss_huge));
+ } else if (strncmp(line, "total_shmem", 11) == 0) {
+ sscanf(line, "total_shmem %llu", &(mstat->total_shmem));
+ } else if (strncmp(line, "total_mapped_file", 17) == 0) {
+ sscanf(line, "total_mapped_file %llu", &(mstat->total_mapped_file));
+ } else if (strncmp(line, "total_dirty", 11) == 0) {
+ sscanf(line, "total_dirty %llu", &(mstat->total_dirty));
+ } else if (strncmp(line, "total_writeback", 15) == 0) {
+ sscanf(line, "total_writeback %llu", &(mstat->total_writeback));
+ } else if (strncmp(line, "total_swap", 10) == 0) {
+ sscanf(line, "total_swap %llu", &(mstat->total_swap));
+ } else if (strncmp(line, "total_pgpgin", 12) == 0) {
+ sscanf(line, "total_pgpgin %llu", &(mstat->total_pgpgin));
+ } else if (strncmp(line, "total_pgpgout", 13) == 0) {
+ sscanf(line, "total_pgpgout %llu", &(mstat->total_pgpgout));
+ } else if (strncmp(line, "total_pgfault", 13) == 0) {
+ sscanf(line, "total_pgfault %llu", &(mstat->total_pgfault));
+ } else if (strncmp(line, "total_pgmajfault", 16) == 0) {
+ sscanf(line, "total_pgmajfault %llu", &(mstat->total_pgmajfault));
+ } else if (strncmp(line, "total_inactive_anon", 19) == 0) {
+ sscanf(line, "total_inactive_anon %llu", &(mstat->total_inactive_anon));
+ } else if (strncmp(line, "total_active_anon", 17) == 0) {
+ sscanf(line, "total_active_anon %llu", &(mstat->total_active_anon));
+ } else if (strncmp(line, "total_inactive_file", 19) == 0) {
+ sscanf(line, "total_inactive_file %llu", &(mstat->total_inactive_file));
+ } else if (strncmp(line, "total_active_file", 17) == 0) {
+ sscanf(line, "total_active_file %llu", &(mstat->total_active_file));
+ } else if (strncmp(line, "total_unevictable", 17) == 0) {
+ sscanf(line, "total_unevictable %llu", &(mstat->total_unevictable));
+ }
+ }
+ return true;
+}
+
bool cgfs_get_value(const char *controller, const char *cgroup, const char *file, char **value)
{
int ret, fd, cfd;
@@ -3367,43 +3465,6 @@ static bool startswith(const char *line, const char *pref)
return false;
}
-static void parse_memstat(char *memstat, unsigned long *cached,
- unsigned long *active_anon, unsigned long *inactive_anon,
- unsigned long *active_file, unsigned long *inactive_file,
- unsigned long *unevictable, unsigned long *shmem)
-{
- char *eol;
-
- while (*memstat) {
- if (startswith(memstat, "total_cache")) {
- sscanf(memstat + 11, "%lu", cached);
- *cached /= 1024;
- } else if (startswith(memstat, "total_active_anon")) {
- sscanf(memstat + 17, "%lu", active_anon);
- *active_anon /= 1024;
- } else if (startswith(memstat, "total_inactive_anon")) {
- sscanf(memstat + 19, "%lu", inactive_anon);
- *inactive_anon /= 1024;
- } else if (startswith(memstat, "total_active_file")) {
- sscanf(memstat + 17, "%lu", active_file);
- *active_file /= 1024;
- } else if (startswith(memstat, "total_inactive_file")) {
- sscanf(memstat + 19, "%lu", inactive_file);
- *inactive_file /= 1024;
- } else if (startswith(memstat, "total_unevictable")) {
- sscanf(memstat + 17, "%lu", unevictable);
- *unevictable /= 1024;
- } else if (startswith(memstat, "total_shmem")) {
- sscanf(memstat + 11, "%lu", shmem);
- *shmem /= 1024;
- }
- eol = strchr(memstat, '\n');
- if (!eol)
- return;
- memstat = eol+1;
- }
-}
-
static void get_blkio_io_value(char *str, unsigned major, unsigned minor, char *iotype, unsigned long *v)
{
char *eol;
@@ -3512,10 +3573,9 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
char *cg;
char *memusage_str = NULL, *memstat_str = NULL,
*memswlimit_str = NULL, *memswusage_str = NULL;
- unsigned long memlimit = 0, memusage = 0, memswlimit = 0, memswusage = 0,
- cached = 0, hosttotal = 0, active_anon = 0, inactive_anon = 0,
- active_file = 0, inactive_file = 0, unevictable = 0, shmem = 0,
- hostswtotal = 0;
+ unsigned long long memlimit = 0, memusage = 0, memswlimit = 0, memswusage = 0,
+ hosttotal=0;
+ struct memory_stat *mstat = NULL;
char *line = NULL;
size_t linelen = 0, total_len = 0, rv = 0;
char *cache = d->buf;
@@ -3544,7 +3604,9 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
memlimit = get_min_memlimit(cg, "memory.limit_in_bytes");
if (!cgfs_get_value("memory", cg, "memory.usage_in_bytes", &memusage_str))
goto err;
- if (!cgfs_get_value("memory", cg, "memory.stat", &memstat_str))
+
+ mstat = (struct memory_stat *)malloc(sizeof(struct memory_stat));
+ if (!cgfs_get_mstat("memory", cg, "memory.stat", mstat))
goto err;
// Following values are allowed to fail, because swapaccount might be turned
@@ -3563,10 +3625,6 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
memlimit /= 1024;
memusage /= 1024;
- parse_memstat(memstat_str, &cached, &active_anon,
- &inactive_anon, &active_file, &inactive_file,
- &unevictable, &shmem);
-
f = fopen("/proc/meminfo", "r");
if (!f)
goto err;
@@ -3577,84 +3635,112 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
memset(lbuf, 0, 100);
if (startswith(line, "MemTotal:")) {
- sscanf(line+sizeof("MemTotal:")-1, "%lu", &hosttotal);
+ sscanf(line+sizeof("MemTotal:")-1, "%llu", &hosttotal);
if (hosttotal < memlimit)
memlimit = hosttotal;
- snprintf(lbuf, 100, "MemTotal: %8lu kB\n", memlimit);
+ snprintf(lbuf, 100, "MemTotal: %8llu kB\n", memlimit);
printme = lbuf;
} else if (startswith(line, "MemFree:")) {
- snprintf(lbuf, 100, "MemFree: %8lu kB\n", memlimit - memusage);
+ snprintf(lbuf, 100, "MemFree: %8llu kB\n", memlimit - memusage);
printme = lbuf;
} else if (startswith(line, "MemAvailable:")) {
- snprintf(lbuf, 100, "MemAvailable: %8lu kB\n", memlimit - memusage + cached);
+ snprintf(lbuf, 100, "MemAvailable: %8llu kB\n", memlimit - memusage +
+ (mstat->total_cache)/1024);
printme = lbuf;
} else if (startswith(line, "SwapTotal:") && memswlimit > 0 && opts && opts->swap_off == false) {
- sscanf(line+sizeof("SwapTotal:")-1, "%lu", &hostswtotal);
- if (hostswtotal < memswlimit)
- memswlimit = hostswtotal;
- snprintf(lbuf, 100, "SwapTotal: %8lu kB\n", memswlimit);
+ memswlimit -= memlimit;
+ snprintf(lbuf, 100, "SwapTotal: %8llu kB\n", memswlimit);
printme = lbuf;
} else if (startswith(line, "SwapTotal:") && opts && opts->swap_off == true) {
- snprintf(lbuf, 100, "SwapTotal: %8lu kB\n", 0UL);
+ snprintf(lbuf, 100, "SwapTotal: %8llu kB\n", 0ULL);
printme = lbuf;
} else if (startswith(line, "SwapFree:") && memswlimit > 0 && memswusage > 0 && opts && opts->swap_off == false) {
- unsigned long swaptotal = memswlimit,
+ unsigned long long swaptotal = memswlimit,
swapusage = memswusage - memusage,
swapfree = swapusage < swaptotal ? swaptotal - swapusage : 0;
- snprintf(lbuf, 100, "SwapFree: %8lu kB\n", swapfree);
+ snprintf(lbuf, 100, "SwapFree: %8llu kB\n", swapfree);
printme = lbuf;
} else if (startswith(line, "SwapFree:") && opts && opts->swap_off == true) {
- snprintf(lbuf, 100, "SwapFree: %8lu kB\n", 0UL);
+ snprintf(lbuf, 100, "SwapFree: %8llu kB\n", 0ULL);
printme = lbuf;
} else if (startswith(line, "Slab:")) {
- snprintf(lbuf, 100, "Slab: %8lu kB\n", 0UL);
+ snprintf(lbuf, 100, "Slab: %8llu kB\n", 0ULL);
printme = lbuf;
} else if (startswith(line, "Buffers:")) {
- snprintf(lbuf, 100, "Buffers: %8lu kB\n", 0UL);
+ snprintf(lbuf, 100, "Buffers: %8llu kB\n", 0ULL);
printme = lbuf;
} else if (startswith(line, "Cached:")) {
- snprintf(lbuf, 100, "Cached: %8lu kB\n", cached);
+ snprintf(lbuf, 100, "Cached: %8llu kB\n",
+ (mstat->total_cache)/1024);
printme = lbuf;
} else if (startswith(line, "SwapCached:")) {
- snprintf(lbuf, 100, "SwapCached: %8lu kB\n", 0UL);
+ snprintf(lbuf, 100, "SwapCached: %8llu kB\n", 0ULL);
printme = lbuf;
} else if (startswith(line, "Active:")) {
- snprintf(lbuf, 100, "Active: %8lu kB\n",
- active_anon + active_file);
+ snprintf(lbuf, 100, "Active: %8llu kB\n",
+ (mstat->total_active_anon + mstat->total_active_file)/1024);
printme = lbuf;
} else if (startswith(line, "Inactive:")) {
- snprintf(lbuf, 100, "Inactive: %8lu kB\n",
- inactive_anon + inactive_file);
+ snprintf(lbuf, 100, "Inactive: %8llu kB\n",
+ (mstat->total_inactive_anon + mstat->total_inactive_file)/1024);
printme = lbuf;
} else if (startswith(line, "Active(anon)")) {
- snprintf(lbuf, 100, "Active(anon): %8lu kB\n", active_anon);
+ snprintf(lbuf, 100, "Active(anon): %8llu kB\n",
+ (mstat->total_active_anon)/1024);
printme = lbuf;
} else if (startswith(line, "Inactive(anon)")) {
- snprintf(lbuf, 100, "Inactive(anon): %8lu kB\n", inactive_anon);
+ snprintf(lbuf, 100, "Inactive(anon): %8llu kB\n",
+ (mstat->total_inactive_anon)/1024);
printme = lbuf;
} else if (startswith(line, "Active(file)")) {
- snprintf(lbuf, 100, "Active(file): %8lu kB\n", active_file);
+ snprintf(lbuf, 100, "Active(file): %8llu kB\n",
+ (mstat->total_active_file)/1024);
printme = lbuf;
} else if (startswith(line, "Inactive(file)")) {
- snprintf(lbuf, 100, "Inactive(file): %8lu kB\n", inactive_file);
+ snprintf(lbuf, 100, "Inactive(file): %8llu kB\n",
+ (mstat->total_inactive_file)/1024);
printme = lbuf;
} else if (startswith(line, "Unevictable")) {
- snprintf(lbuf, 100, "Unevictable: %8lu kB\n", unevictable);
+ snprintf(lbuf, 100, "Unevictable: %8llu kB\n",
+ (mstat->total_unevictable)/1024);
+ printme = lbuf;
+ } else if (startswith(line, "Dirty")) {
+ snprintf(lbuf, 100, "Dirty: %8llu kB\n",
+ (mstat->total_dirty)/1024);
+ printme = lbuf;
+ } else if (startswith(line, "Writeback")) {
+ snprintf(lbuf, 100, "Writeback: %8llu kB\n",
+ (mstat->total_writeback)/1024);
+ printme = lbuf;
+ } else if (startswith(line, "AnonPages")) {
+ snprintf(lbuf, 100, "AnonPages: %8llu kB\n",
+ (mstat->total_active_anon
+ + mstat->total_inactive_anon
+ - mstat->total_shmem)/1024);
+ printme = lbuf;
+ } else if (startswith(line, "Mapped")) {
+ snprintf(lbuf, 100, "Mapped: %8llu kB\n",
+ (mstat->total_mapped_file)/1024);
printme = lbuf;
} else if (startswith(line, "SReclaimable")) {
- snprintf(lbuf, 100, "SReclaimable: %8lu kB\n", 0UL);
+ snprintf(lbuf, 100, "SReclaimable: %8llu kB\n", 0ULL);
printme = lbuf;
} else if (startswith(line, "SUnreclaim")) {
- snprintf(lbuf, 100, "SUnreclaim: %8lu kB\n", 0UL);
+ snprintf(lbuf, 100, "SUnreclaim: %8llu kB\n", 0ULL);
printme = lbuf;
} else if (startswith(line, "Shmem:")) {
- snprintf(lbuf, 100, "Shmem: %8lu kB\n", shmem);
+ snprintf(lbuf, 100, "Shmem: %8llu kB\n",
+ (mstat->total_shmem)/1024);
printme = lbuf;
} else if (startswith(line, "ShmemHugePages")) {
- snprintf(lbuf, 100, "ShmemHugePages: %8lu kB\n", 0UL);
+ snprintf(lbuf, 100, "ShmemHugePages: %8llu kB\n", 0ULL);
printme = lbuf;
} else if (startswith(line, "ShmemPmdMapped")) {
- snprintf(lbuf, 100, "ShmemPmdMapped: %8lu kB\n", 0UL);
+ snprintf(lbuf, 100, "ShmemPmdMapped: %8llu kB\n", 0ULL);
+ printme = lbuf;
+ } else if (startswith(line, "AnonHugePages")) {
+ snprintf(lbuf, 100, "AnonHugePages: %8llu kB\n",
+ (mstat->total_rss_huge)/1024);
printme = lbuf;
} else
printme = line;
@@ -3692,6 +3778,7 @@ static int proc_meminfo_read(char *buf, size_t size, off_t offset,
free(memswlimit_str);
free(memswusage_str);
free(memstat_str);
+ free(mstat);
return rv;
}
@@ -5698,12 +5785,15 @@ static int refresh_load(struct load_node *p, char *path)
if (f != NULL) {
while (getline(&line, &linelen, f) != -1) {
/* Find State */
- if ((line[0] == 'S') && (line[1] == 't'))
- break;
+ if (strncmp(line, "State", 5) == 0) {
+ if (strncmp(line, "State R", 7) == 0 ||
+ strncmp(line, "State D", 7) == 0) {
+ run_pid++;
+ }
+ break;
+ }
}
- if ((line[7] == 'R') || (line[7] == 'D'))
- run_pid++;
- fclose(f);
+ fclose(f);
}
}
closedir(dp);
More information about the lxc-devel
mailing list