From: Anita Zhang Date: Fri, 2 Jul 2021 00:07:32 +0000 (-0700) Subject: oomd: review follow ups to #20020 X-Git-Tag: v249~29 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e82acab4db6f5f212f6c9c9b3ec2df9010a83925;p=thirdparty%2Fsystemd.git oomd: review follow ups to #20020 --- diff --git a/src/basic/procfs-util.c b/src/basic/procfs-util.c index db3e29d04ac..9234ccaf859 100644 --- a/src/basic/procfs-util.c +++ b/src/basic/procfs-util.c @@ -201,7 +201,8 @@ int procfs_cpu_get_usage(nsec_t *ret) { return 0; } -int convert_meminfo_value_to_uint64_bytes(char *word, uint64_t *ret) { +int convert_meminfo_value_to_uint64_bytes(const char *word, uint64_t *ret) { + _cleanup_free_ char *w = NULL; char *digits, *e; uint64_t v; size_t n; @@ -210,9 +211,13 @@ int convert_meminfo_value_to_uint64_bytes(char *word, uint64_t *ret) { assert(word); assert(ret); + w = strdup(word); + if (!w) + return -ENOMEM; + /* Determine length of numeric value */ - n = strspn(word, WHITESPACE); - digits = word + n; + n = strspn(w, WHITESPACE); + digits = w + n; n = strspn(digits, DIGITS); if (n == 0) return -EINVAL; @@ -232,6 +237,9 @@ int convert_meminfo_value_to_uint64_bytes(char *word, uint64_t *ret) { if (v == UINT64_MAX) return -EINVAL; + if (v > UINT64_MAX/1024) + return -EOVERFLOW; + *ret = v * 1024U; return 0; } diff --git a/src/basic/procfs-util.h b/src/basic/procfs-util.h index b7bf7b729db..61fa71d479f 100644 --- a/src/basic/procfs-util.h +++ b/src/basic/procfs-util.h @@ -16,5 +16,4 @@ static inline int procfs_memory_get_used(uint64_t *ret) { return procfs_memory_get(NULL, ret); } -/* This function destroys "word" (it'll be truncated to perform conversion) */ -int convert_meminfo_value_to_uint64_bytes(char *word, uint64_t *ret); +int convert_meminfo_value_to_uint64_bytes(const char *word, uint64_t *ret); diff --git a/src/oom/oomd-util.c b/src/oom/oomd-util.c index 04d2bfe0bde..b2a48acb1f4 100644 --- a/src/oom/oomd-util.c +++ b/src/oom/oomd-util.c @@ -129,7 +129,7 @@ bool oomd_mem_free_below(const OomdSystemContext *ctx, int threshold_permyriad) assert(threshold_permyriad <= 10000); mem_threshold = ctx->mem_total * threshold_permyriad / (uint64_t) 10000; - return (ctx->mem_total - ctx->mem_used) < mem_threshold; + return LESS_BY(ctx->mem_total, ctx->mem_used) < mem_threshold; } bool oomd_swap_free_below(const OomdSystemContext *ctx, int threshold_permyriad) { @@ -375,6 +375,14 @@ int oomd_system_context_acquire(const char *proc_meminfo_path, OomdSystemContext uint64_t mem_free, swap_free; int r; + enum { + MEM_TOTAL = 1U << 0, + MEM_FREE = 1U << 1, + SWAP_TOTAL = 1U << 2, + SWAP_FREE = 1U << 3, + ALL = MEM_TOTAL|MEM_FREE|SWAP_TOTAL|SWAP_FREE, + }; + assert(proc_meminfo_path); assert(ret); @@ -393,16 +401,16 @@ int oomd_system_context_acquire(const char *proc_meminfo_path, OomdSystemContext return -EINVAL; if ((word = startswith(line, "MemTotal:"))) { - field_filled |= 1U << 0; + field_filled |= MEM_TOTAL; r = convert_meminfo_value_to_uint64_bytes(word, &ctx.mem_total); } else if ((word = startswith(line, "MemFree:"))) { - field_filled |= 1U << 1; + field_filled |= MEM_FREE; r = convert_meminfo_value_to_uint64_bytes(word, &mem_free); } else if ((word = startswith(line, "SwapTotal:"))) { - field_filled |= 1U << 2; + field_filled |= SWAP_TOTAL; r = convert_meminfo_value_to_uint64_bytes(word, &ctx.swap_total); } else if ((word = startswith(line, "SwapFree:"))) { - field_filled |= 1U << 3; + field_filled |= SWAP_FREE; r = convert_meminfo_value_to_uint64_bytes(word, &swap_free); } else continue; @@ -410,11 +418,11 @@ int oomd_system_context_acquire(const char *proc_meminfo_path, OomdSystemContext if (r < 0) return log_debug_errno(r, "Error converting '%s' from %s to uint64_t: %m", line, proc_meminfo_path); - if (field_filled == 15U) + if (field_filled == ALL) break; } - if (field_filled != 15U) + if (field_filled != ALL) return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "%s is missing expected fields", proc_meminfo_path); if (mem_free > ctx.mem_total)