cgroup: analyze: Report memory configurations that deviate from systemd
This is the most basic consumer of the new systemd-vs-kernel checker, both acting as a reasonable standalone exerciser of the code, and also as a way for easy inspection of deviations from systemd internal state.
This commit is contained in:
parent
6dfb92823f
commit
bc0623df16
|
@ -328,7 +328,38 @@ static int unit_compare_memory_limit(Unit *u, const char *property_name, uint64_
|
|||
return *ret_kernel_value == *ret_unit_value;
|
||||
}
|
||||
|
||||
void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
|
||||
#define FORMAT_CGROUP_DIFF_MAX 128
|
||||
|
||||
static char *format_cgroup_memory_limit_comparison(char *buf, size_t l, Unit *u, const char *property_name) {
|
||||
uint64_t kval, sval;
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
assert(buf);
|
||||
assert(l > 0);
|
||||
|
||||
r = unit_compare_memory_limit(u, property_name, &sval, &kval);
|
||||
|
||||
/* memory.swap.max is special in that it relies on CONFIG_MEMCG_SWAP (and the default swapaccount=1).
|
||||
* In the absence of reliably being able to detect whether memcg swap support is available or not,
|
||||
* only complain if the error is not ENOENT. */
|
||||
if (r > 0 || IN_SET(r, -ENODATA, -EOWNERDEAD) ||
|
||||
(r == -ENOENT && streq(property_name, "MemorySwapMax"))) {
|
||||
buf[0] = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
if (r < 0) {
|
||||
snprintf(buf, l, " (error getting kernel value: %s)", strerror_safe(r));
|
||||
return buf;
|
||||
}
|
||||
|
||||
snprintf(buf, l, " (different value in kernel: %" PRIu64 ")", kval);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||||
_cleanup_free_ char *disable_controllers_str = NULL;
|
||||
_cleanup_free_ char *cpuset_cpus = NULL;
|
||||
_cleanup_free_ char *cpuset_mems = NULL;
|
||||
|
@ -338,14 +369,24 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
|
|||
CGroupBlockIODeviceBandwidth *b;
|
||||
CGroupBlockIODeviceWeight *w;
|
||||
CGroupDeviceAllow *a;
|
||||
CGroupContext *c;
|
||||
IPAddressAccessItem *iaai;
|
||||
char **path;
|
||||
char u[FORMAT_TIMESPAN_MAX];
|
||||
char q[FORMAT_TIMESPAN_MAX];
|
||||
char v[FORMAT_TIMESPAN_MAX];
|
||||
|
||||
assert(c);
|
||||
char cda[FORMAT_CGROUP_DIFF_MAX];
|
||||
char cdb[FORMAT_CGROUP_DIFF_MAX];
|
||||
char cdc[FORMAT_CGROUP_DIFF_MAX];
|
||||
char cdd[FORMAT_CGROUP_DIFF_MAX];
|
||||
char cde[FORMAT_CGROUP_DIFF_MAX];
|
||||
|
||||
assert(u);
|
||||
assert(f);
|
||||
|
||||
c = unit_get_cgroup_context(u);
|
||||
assert(c);
|
||||
|
||||
prefix = strempty(prefix);
|
||||
|
||||
(void) cg_mask_to_string(c->disable_controllers, &disable_controllers_str);
|
||||
|
@ -374,11 +415,11 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
|
|||
"%sStartupBlockIOWeight: %" PRIu64 "\n"
|
||||
"%sDefaultMemoryMin: %" PRIu64 "\n"
|
||||
"%sDefaultMemoryLow: %" PRIu64 "\n"
|
||||
"%sMemoryMin: %" PRIu64 "\n"
|
||||
"%sMemoryLow: %" PRIu64 "\n"
|
||||
"%sMemoryHigh: %" PRIu64 "\n"
|
||||
"%sMemoryMax: %" PRIu64 "\n"
|
||||
"%sMemorySwapMax: %" PRIu64 "\n"
|
||||
"%sMemoryMin: %" PRIu64 "%s\n"
|
||||
"%sMemoryLow: %" PRIu64 "%s\n"
|
||||
"%sMemoryHigh: %" PRIu64 "%s\n"
|
||||
"%sMemoryMax: %" PRIu64 "%s\n"
|
||||
"%sMemorySwapMax: %" PRIu64 "%s\n"
|
||||
"%sMemoryLimit: %" PRIu64 "\n"
|
||||
"%sTasksMax: %" PRIu64 "\n"
|
||||
"%sDevicePolicy: %s\n"
|
||||
|
@ -394,7 +435,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
|
|||
prefix, c->startup_cpu_weight,
|
||||
prefix, c->cpu_shares,
|
||||
prefix, c->startup_cpu_shares,
|
||||
prefix, format_timespan(u, sizeof(u), c->cpu_quota_per_sec_usec, 1),
|
||||
prefix, format_timespan(q, sizeof(q), c->cpu_quota_per_sec_usec, 1),
|
||||
prefix, format_timespan(v, sizeof(v), c->cpu_quota_period_usec, 1),
|
||||
prefix, cpuset_cpus,
|
||||
prefix, cpuset_mems,
|
||||
|
@ -404,11 +445,11 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
|
|||
prefix, c->startup_blockio_weight,
|
||||
prefix, c->default_memory_min,
|
||||
prefix, c->default_memory_low,
|
||||
prefix, c->memory_min,
|
||||
prefix, c->memory_low,
|
||||
prefix, c->memory_high,
|
||||
prefix, c->memory_max,
|
||||
prefix, c->memory_swap_max,
|
||||
prefix, c->memory_min, format_cgroup_memory_limit_comparison(cda, sizeof(cda), u, "MemoryMin"),
|
||||
prefix, c->memory_low, format_cgroup_memory_limit_comparison(cdb, sizeof(cdb), u, "MemoryLow"),
|
||||
prefix, c->memory_high, format_cgroup_memory_limit_comparison(cdc, sizeof(cdc), u, "MemoryHigh"),
|
||||
prefix, c->memory_max, format_cgroup_memory_limit_comparison(cdd, sizeof(cdd), u, "MemoryMax"),
|
||||
prefix, c->memory_swap_max, format_cgroup_memory_limit_comparison(cde, sizeof(cde), u, "MemorySwapMax"),
|
||||
prefix, c->memory_limit,
|
||||
prefix, c->tasks_max,
|
||||
prefix, cgroup_device_policy_to_string(c->device_policy),
|
||||
|
@ -444,7 +485,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
|
|||
"%sIODeviceLatencyTargetSec: %s %s\n",
|
||||
prefix,
|
||||
l->path,
|
||||
format_timespan(u, sizeof(u), l->target_usec, 1));
|
||||
format_timespan(q, sizeof(q), l->target_usec, 1));
|
||||
|
||||
LIST_FOREACH(device_limits, il, c->io_device_limits) {
|
||||
char buf[FORMAT_BYTES_MAX];
|
||||
|
|
|
@ -166,7 +166,7 @@ usec_t cgroup_cpu_adjust_period(usec_t period, usec_t quota, usec_t resolution,
|
|||
|
||||
void cgroup_context_init(CGroupContext *c);
|
||||
void cgroup_context_done(CGroupContext *c);
|
||||
void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix);
|
||||
void cgroup_context_dump(Unit *u, FILE* f, const char *prefix);
|
||||
|
||||
void cgroup_context_free_device_allow(CGroupContext *c, CGroupDeviceAllow *a);
|
||||
void cgroup_context_free_io_device_weight(CGroupContext *c, CGroupIODeviceWeight *w);
|
||||
|
|
|
@ -769,7 +769,7 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
|
|||
|
||||
exec_context_dump(&m->exec_context, f, prefix);
|
||||
kill_context_dump(&m->kill_context, f, prefix);
|
||||
cgroup_context_dump(&m->cgroup_context, f, prefix);
|
||||
cgroup_context_dump(UNIT(m), f, prefix);
|
||||
}
|
||||
|
||||
static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
|
||||
|
|
|
@ -234,7 +234,7 @@ static void scope_dump(Unit *u, FILE *f, const char *prefix) {
|
|||
prefix, scope_state_to_string(s->state),
|
||||
prefix, scope_result_to_string(s->result));
|
||||
|
||||
cgroup_context_dump(&s->cgroup_context, f, prefix);
|
||||
cgroup_context_dump(UNIT(s), f, prefix);
|
||||
kill_context_dump(&s->kill_context, f, prefix);
|
||||
}
|
||||
|
||||
|
|
|
@ -905,7 +905,7 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
|
|||
prefix, s->n_fd_store_max,
|
||||
prefix, s->n_fd_store);
|
||||
|
||||
cgroup_context_dump(&s->cgroup_context, f, prefix);
|
||||
cgroup_context_dump(UNIT(s), f, prefix);
|
||||
}
|
||||
|
||||
static int service_is_suitable_main_pid(Service *s, pid_t pid, int prio) {
|
||||
|
|
|
@ -215,7 +215,7 @@ static void slice_dump(Unit *u, FILE *f, const char *prefix) {
|
|||
"%sSlice State: %s\n",
|
||||
prefix, slice_state_to_string(t->state));
|
||||
|
||||
cgroup_context_dump(&t->cgroup_context, f, prefix);
|
||||
cgroup_context_dump(UNIT(t), f, prefix);
|
||||
}
|
||||
|
||||
static int slice_start(Unit *u) {
|
||||
|
|
|
@ -843,7 +843,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
|
|||
exec_command_dump_list(s->exec_command[c], f, prefix2);
|
||||
}
|
||||
|
||||
cgroup_context_dump(&s->cgroup_context, f, prefix);
|
||||
cgroup_context_dump(UNIT(s), f, prefix);
|
||||
}
|
||||
|
||||
static int instance_from_socket(int fd, unsigned nr, char **instance) {
|
||||
|
|
|
@ -621,7 +621,7 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) {
|
|||
|
||||
exec_context_dump(&s->exec_context, f, prefix);
|
||||
kill_context_dump(&s->kill_context, f, prefix);
|
||||
cgroup_context_dump(&s->cgroup_context, f, prefix);
|
||||
cgroup_context_dump(UNIT(s), f, prefix);
|
||||
}
|
||||
|
||||
static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
|
||||
|
|
Loading…
Reference in New Issue