Merge pull request #14093 from poettering/cgroups-delegate-xattr

mark delegated cgroups via xattr, and visualize the cut points in cgls
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2019-11-20 23:53:03 +01:00 committed by GitHub
commit 9389a3cdc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 86 additions and 16 deletions

4
TODO
View File

@ -166,10 +166,6 @@ Features:
* sd-boot: optionally, show boot menu when previous default boot item has
non-zero "tries done" count
* maybe set a special xattr on cgroups that have delegate=yes set, to make it
easy to mark cut points, then use this information in "systemd-cgls" to show
them (e.g. color delegated subtrees in a different color)
* introduce an option (or replacement) for "systemctl show" that outputs all
properties as JSON, similar to busctl's new JSON output. In contrast to that
it should skip the variant type string though.

View File

@ -605,6 +605,23 @@ int cg_get_xattr(const char *controller, const char *path, const char *name, voi
return (int) n;
}
int cg_remove_xattr(const char *controller, const char *path, const char *name) {
_cleanup_free_ char *fs = NULL;
int r;
assert(path);
assert(name);
r = cg_get_path(controller, path, NULL, &fs);
if (r < 0)
return r;
if (removexattr(fs, name) < 0)
return -errno;
return 0;
}
int cg_pid_get_path(const char *controller, pid_t pid, char **path) {
_cleanup_fclose_ FILE *f = NULL;
const char *fs, *controller_str;

View File

@ -188,6 +188,7 @@ int cg_set_access(const char *controller, const char *path, uid_t uid, gid_t gid
int cg_set_xattr(const char *controller, const char *path, const char *name, const void *value, size_t size, int flags);
int cg_get_xattr(const char *controller, const char *path, const char *name, void *value, size_t size);
int cg_remove_xattr(const char *controller, const char *path, const char *name);
int cg_install_release_agent(const char *controller, const char *agent);
int cg_uninstall_release_agent(const char *controller);

View File

@ -617,15 +617,27 @@ static void cgroup_xattr_apply(Unit *u) {
if (!MANAGER_IS_SYSTEM(u->manager))
return;
if (sd_id128_is_null(u->invocation_id))
return;
if (!sd_id128_is_null(u->invocation_id)) {
r = cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path,
"trusted.invocation_id",
sd_id128_to_string(u->invocation_id, ids), 32,
0);
if (r < 0)
log_unit_debug_errno(u, r, "Failed to set invocation ID on control group %s, ignoring: %m", u->cgroup_path);
}
r = cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path,
"trusted.invocation_id",
sd_id128_to_string(u->invocation_id, ids), 32,
0);
if (r < 0)
log_unit_debug_errno(u, r, "Failed to set invocation ID on control group %s, ignoring: %m", u->cgroup_path);
if (unit_cgroup_delegate(u)) {
r = cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path,
"trusted.delegate",
"1", 1,
0);
if (r < 0)
log_unit_debug_errno(u, r, "Failed to set delegate flag on control group %s, ignoring: %m", u->cgroup_path);
} else {
r = cg_remove_xattr(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, "trusted.delegate");
if (r != -ENODATA)
log_unit_debug_errno(u, r, "Failed to remove delegate flag on control group %s, ignoring: %m", u->cgroup_path);
}
}
static int lookup_block_device(const char *p, dev_t *ret) {

View File

@ -17,12 +17,14 @@
#include "locale-util.h"
#include "macro.h"
#include "output-mode.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
#include "sort-util.h"
#include "string-util.h"
#include "terminal-util.h"
#include "unit-name.h"
#include "xattr-util.h"
static void show_pid_array(
pid_t pids[],
@ -69,7 +71,7 @@ static void show_pid_array(
else
printf("%s%s", prefix, special_glyph(((more || i < n_pids-1) ? SPECIAL_GLYPH_TREE_BRANCH : SPECIAL_GLYPH_TREE_RIGHT)));
printf("%*"PID_PRI" %s\n", pid_width, pids[i], strna(t));
printf("%s%*"PID_PRI" %s%s\n", ansi_grey(), pid_width, pids[i], strna(t), ansi_normal());
}
}
@ -117,6 +119,44 @@ static int show_cgroup_one_by_path(
return 0;
}
static int show_cgroup_name(
const char *path,
const char *prefix,
const char *glyph) {
_cleanup_free_ char *b = NULL;
bool delegate = false;
int r;
r = getxattr_malloc(path, "trusted.delegate", &b, false);
if (r < 0) {
if (r != -ENODATA)
log_debug_errno(r, "Failed to read trusted.delegate extended attribute: %m");
} else {
r = parse_boolean(b);
if (r < 0)
log_debug_errno(r, "Failed to parse trusted.delegate extended attribute boolean value: %m");
else
delegate = r > 0;
b = mfree(b);
}
b = strdup(basename(path));
if (!b)
return -ENOMEM;
printf("%s%s%s%s%s %s%s%s\n",
prefix, glyph,
delegate ? ansi_underline() : "",
cg_unescape(b),
delegate ? ansi_normal() : "",
delegate ? ansi_highlight() : "",
delegate ? special_glyph(SPECIAL_GLYPH_ELLIPSIS) : "",
delegate ? ansi_normal() : "");
return 0;
}
int show_cgroup_by_path(
const char *path,
const char *prefix,
@ -125,8 +165,8 @@ int show_cgroup_by_path(
_cleanup_free_ char *fn = NULL, *p1 = NULL, *last = NULL, *p2 = NULL;
_cleanup_closedir_ DIR *d = NULL;
char *gn = NULL;
bool shown_pids = false;
char *gn = NULL;
int r;
assert(path);
@ -161,7 +201,9 @@ int show_cgroup_by_path(
}
if (last) {
printf("%s%s%s\n", prefix, special_glyph(SPECIAL_GLYPH_TREE_BRANCH), cg_unescape(basename(last)));
r = show_cgroup_name(last, prefix, special_glyph(SPECIAL_GLYPH_TREE_BRANCH));
if (r < 0)
return r;
if (!p1) {
p1 = strjoin(prefix, special_glyph(SPECIAL_GLYPH_TREE_VERTICAL));
@ -183,7 +225,9 @@ int show_cgroup_by_path(
show_cgroup_one_by_path(path, prefix, n_columns, !!last, flags);
if (last) {
printf("%s%s%s\n", prefix, special_glyph(SPECIAL_GLYPH_TREE_RIGHT), cg_unescape(basename(last)));
r = show_cgroup_name(last, prefix, special_glyph(SPECIAL_GLYPH_TREE_RIGHT));
if (r < 0)
return r;
if (!p2) {
p2 = strjoin(prefix, " ");