summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnita Zhang <the.anitazha@gmail.com>2021-07-01 17:07:32 -0700
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2021-07-12 13:30:54 +0200
commitfe50f37972df7dbe6eb1ba93c422f631dc9944a8 (patch)
treef89f61693899f81d3475f3a3abb445c714d9a748
parent7e558b501783757f63b9c93edce43239a5178611 (diff)
downloadsystemd-fe50f37972df7dbe6eb1ba93c422f631dc9944a8.tar.gz
oomd: review follow ups to #20020
(cherry picked from commit e82acab4db6f5f212f6c9c9b3ec2df9010a83925)
-rw-r--r--src/basic/procfs-util.c14
-rw-r--r--src/basic/procfs-util.h3
-rw-r--r--src/oom/oomd-util.c22
3 files changed, 27 insertions, 12 deletions
diff --git a/src/basic/procfs-util.c b/src/basic/procfs-util.c
index db3e29d04a..9234ccaf85 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 b7bf7b729d..61fa71d479 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 f49cbe8e81..2ee81ce114 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) {
@@ -371,6 +371,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);
@@ -389,16 +397,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;
@@ -406,11 +414,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)