diff options
author | Anita Zhang <the.anitazha@gmail.com> | 2021-06-24 02:37:57 -0700 |
---|---|---|
committer | Anita Zhang <the.anitazha@gmail.com> | 2021-06-30 03:47:26 -0700 |
commit | 47136b9d9a75fff5f9e2e777aaed736e6f66c7f7 (patch) | |
tree | cf93ebb50ced0d8abdb477a66b68191ffdef87e8 /src/oom/oomd-util.c | |
parent | 4dbad977ff153f1457fd3ec5bc06b5b7e6414cc0 (diff) | |
download | systemd-47136b9d9a75fff5f9e2e777aaed736e6f66c7f7.tar.gz |
oomd: switch system context parsing to use /proc/meminfo
Makes it easier in the next commits to unify on one way to read swap and
memory info.
Diffstat (limited to 'src/oom/oomd-util.c')
-rw-r--r-- | src/oom/oomd-util.c | 60 |
1 files changed, 36 insertions, 24 deletions
diff --git a/src/oom/oomd-util.c b/src/oom/oomd-util.c index 0550ac6c74..bb77c84807 100644 --- a/src/oom/oomd-util.c +++ b/src/oom/oomd-util.c @@ -4,6 +4,7 @@ #include <unistd.h> #include "fd-util.h" +#include "fileio.h" #include "format-util.h" #include "oomd-util.h" #include "parse-util.h" @@ -357,45 +358,56 @@ int oomd_cgroup_context_acquire(const char *path, OomdCGroupContext **ret) { return 0; } -int oomd_system_context_acquire(const char *proc_swaps_path, OomdSystemContext *ret) { +int oomd_system_context_acquire(const char *proc_meminfo_path, OomdSystemContext *ret) { _cleanup_fclose_ FILE *f = NULL; + unsigned field_filled = 0; OomdSystemContext ctx = {}; + uint64_t swap_free; int r; - assert(proc_swaps_path); + assert(proc_meminfo_path); assert(ret); - f = fopen(proc_swaps_path, "re"); + f = fopen(proc_meminfo_path, "re"); if (!f) return -errno; - (void) fscanf(f, "%*s %*s %*s %*s %*s\n"); - for (;;) { - uint64_t total, used; + _cleanup_free_ char *line = NULL; + char *word; - r = fscanf(f, - "%*s " /* device/file */ - "%*s " /* type of swap */ - "%" PRIu64 " " /* swap size */ - "%" PRIu64 " " /* used */ - "%*s\n", /* priority */ - &total, &used); + r = read_line(f, LONG_LINE_MAX, &line); + if (r < 0) + return r; + if (r == 0) + return -EINVAL; + + if ((word = startswith(line, "SwapTotal:"))) { + field_filled |= 1U << 0; + r = convert_meminfo_value_to_uint64_bytes(word, &ctx.swap_total); + } else if ((word = startswith(line, "SwapFree:"))) { + field_filled |= 1U << 1; + r = convert_meminfo_value_to_uint64_bytes(word, &swap_free); + } else + continue; - if (r == EOF && feof(f)) - break; + if (r < 0) + return log_debug_errno(r, "Error converting '%s' from %s to uint64_t: %m", line, proc_meminfo_path); - if (r != 2) { - if (ferror(f)) - return log_debug_errno(errno, "Error reading from %s: %m", proc_swaps_path); + if (field_filled == 3U) + break; + } - return log_debug_errno(SYNTHETIC_ERRNO(EIO), - "Failed to parse values from %s: %m", proc_swaps_path); - } + if (field_filled != 3U) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "%s is missing expected fields", proc_meminfo_path); - ctx.swap_total += total * 1024U; - ctx.swap_used += used * 1024U; - } + if (swap_free > ctx.swap_total) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), + "SwapFree (%" PRIu64 ") cannot be greater than SwapTotal (%" PRIu64 ") %m", + swap_free, + ctx.swap_total); + + ctx.swap_used = ctx.swap_total - swap_free; *ret = ctx; return 0; |