Merge pull request #19647 from ddstreet/test-oomd-failure
handle lack of kernel support for some cgroup files
This commit is contained in:
+3
-3
@@ -371,8 +371,6 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
|
||||
int n_retries;
|
||||
bool truncated = false;
|
||||
|
||||
assert(ret_contents);
|
||||
|
||||
/* Virtual filesystems such as sysfs or procfs use kernfs, and kernfs can work with two sorts of
|
||||
* virtual files. One sort uses "seq_file", and the results of the first read are buffered for the
|
||||
* second read. The other sort uses "raw" reads which always go direct to the device. In the latter
|
||||
@@ -486,7 +484,9 @@ int read_virtual_file(const char *filename, size_t max_size, char **ret_contents
|
||||
return -EBADMSG;
|
||||
|
||||
buf[n] = 0;
|
||||
*ret_contents = TAKE_PTR(buf);
|
||||
|
||||
if (ret_contents)
|
||||
*ret_contents = TAKE_PTR(buf);
|
||||
|
||||
return !truncated;
|
||||
}
|
||||
|
||||
@@ -236,6 +236,29 @@ int log_emergency_level(void);
|
||||
#define log_error_errno(error, ...) log_full_errno(LOG_ERR, error, __VA_ARGS__)
|
||||
#define log_emergency_errno(error, ...) log_full_errno(log_emergency_level(), error, __VA_ARGS__)
|
||||
|
||||
/* This logs at the specified level the first time it is called, and then
|
||||
* logs at debug. If the specified level is debug, this logs only the first
|
||||
* time it is called. */
|
||||
#define log_once(level, ...) \
|
||||
({ \
|
||||
if (ONCE) \
|
||||
log_full(level, __VA_ARGS__); \
|
||||
else if (LOG_PRI(level) != LOG_DEBUG) \
|
||||
log_debug(__VA_ARGS__); \
|
||||
})
|
||||
|
||||
#define log_once_errno(level, error, ...) \
|
||||
({ \
|
||||
int _err = (error); \
|
||||
if (ONCE) \
|
||||
_err = log_full_errno(level, _err, __VA_ARGS__); \
|
||||
else if (LOG_PRI(level) != LOG_DEBUG) \
|
||||
_err = log_debug_errno(_err, __VA_ARGS__); \
|
||||
else \
|
||||
_err = -ERRNO_VALUE(_err); \
|
||||
_err; \
|
||||
})
|
||||
|
||||
#if LOG_TRACE
|
||||
# define log_trace(...) log_debug(__VA_ARGS__)
|
||||
#else
|
||||
|
||||
@@ -50,6 +50,17 @@
|
||||
#define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq))
|
||||
#define UNIQ __COUNTER__
|
||||
|
||||
/* Note that this works differently from pthread_once(): this macro does
|
||||
* not synchronize code execution, i.e. code that is run conditionalized
|
||||
* on this macro will run concurrently to all other code conditionalized
|
||||
* the same way, there's no ordering or completion enforced. */
|
||||
#define ONCE __ONCE(UNIQ_T(_once_, UNIQ))
|
||||
#define __ONCE(o) \
|
||||
({ \
|
||||
static bool (o) = false; \
|
||||
__sync_bool_compare_and_swap(&(o), false, true); \
|
||||
})
|
||||
|
||||
#undef MAX
|
||||
#define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b))
|
||||
#define __MAX(aq, a, bq, b) \
|
||||
|
||||
+5
-1
@@ -333,7 +333,11 @@ int oomd_cgroup_context_acquire(const char *path, OomdCGroupContext **ret) {
|
||||
return log_debug_errno(r, "Error getting memory.low from %s: %m", path);
|
||||
|
||||
r = cg_get_attribute_as_uint64(SYSTEMD_CGROUP_CONTROLLER, path, "memory.swap.current", &ctx->swap_usage);
|
||||
if (r < 0)
|
||||
if (r == -ENODATA)
|
||||
/* The kernel can be compiled without support for memory.swap.* files,
|
||||
* or it can be disabled with boot param 'swapaccount=0' */
|
||||
log_once(LOG_WARNING, "No kernel support for memory.swap.current from %s (try boot param swapaccount=1), ignoring.", path);
|
||||
else if (r < 0)
|
||||
return log_debug_errno(r, "Error getting memory.swap.current from %s: %m", path);
|
||||
|
||||
r = cg_get_keyed_attribute(SYSTEMD_CGROUP_CONTROLLER, path, "memory.stat", STRV_MAKE("pgscan"), &val);
|
||||
|
||||
+13
-6
@@ -4,6 +4,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "extract-word.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
@@ -107,12 +108,18 @@ int read_resource_pressure(const char *path, PressureType type, ResourcePressure
|
||||
int is_pressure_supported(void) {
|
||||
const char *p;
|
||||
|
||||
FOREACH_STRING(p, "/proc/pressure/cpu", "/proc/pressure/io", "/proc/pressure/memory")
|
||||
if (access(p, F_OK) < 0) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
return -errno;
|
||||
}
|
||||
/* The pressure files, both under /proc and in cgroups, will exist
|
||||
* even if the kernel has PSI support disabled; we have to read
|
||||
* the file to make sure it doesn't return -EOPNOTSUPP */
|
||||
FOREACH_STRING(p, "/proc/pressure/cpu", "/proc/pressure/io", "/proc/pressure/memory") {
|
||||
int r;
|
||||
|
||||
r = read_virtual_file(p, 0, NULL, NULL);
|
||||
if (r == -ENOENT || ERRNO_IS_NOT_SUPPORTED(r))
|
||||
return 0;
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user