mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-24 21:34:08 +03:00
cgroups-show: optionally show cgroup xattrs + cgroup id in cgroup tree output
This commit is contained in:
parent
aa13d38417
commit
5a5a5d2914
@ -12,11 +12,13 @@
|
||||
#include "cgroup-show.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "env-file.h"
|
||||
#include "escape.h"
|
||||
#include "fd-util.h"
|
||||
#include "format-util.h"
|
||||
#include "hostname-util.h"
|
||||
#include "locale-util.h"
|
||||
#include "macro.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "output-mode.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
@ -122,38 +124,109 @@ static int show_cgroup_one_by_path(
|
||||
static int show_cgroup_name(
|
||||
const char *path,
|
||||
const char *prefix,
|
||||
const char *glyph) {
|
||||
SpecialGlyph glyph,
|
||||
OutputFlags flags) {
|
||||
|
||||
uint64_t cgroupid = UINT64_MAX;
|
||||
_cleanup_free_ char *b = NULL;
|
||||
_cleanup_close_ int fd = -1;
|
||||
bool delegate = false;
|
||||
int r;
|
||||
|
||||
r = lgetxattr_malloc(path, "trusted.delegate", &b);
|
||||
if (FLAGS_SET(flags, OUTPUT_CGROUP_XATTRS) || FLAGS_SET(flags, OUTPUT_CGROUP_ID)) {
|
||||
fd = open(path, O_PATH|O_CLOEXEC|O_NOFOLLOW|O_DIRECTORY, 0);
|
||||
if (fd < 0)
|
||||
log_debug_errno(errno, "Failed to open cgroup '%s', ignoring: %m", path);
|
||||
}
|
||||
|
||||
r = getxattr_malloc(fd < 0 ? path : FORMAT_PROC_FD_PATH(fd), "trusted.delegate", &b);
|
||||
if (r < 0) {
|
||||
if (r != -ENODATA)
|
||||
log_debug_errno(r, "Failed to read trusted.delegate extended attribute: %m");
|
||||
log_debug_errno(r, "Failed to read trusted.delegate extended attribute, ignoring: %m");
|
||||
} else {
|
||||
r = parse_boolean(b);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse trusted.delegate extended attribute boolean value: %m");
|
||||
log_debug_errno(r, "Failed to parse trusted.delegate extended attribute boolean value, ignoring: %m");
|
||||
else
|
||||
delegate = r > 0;
|
||||
|
||||
b = mfree(b);
|
||||
}
|
||||
|
||||
b = strdup(basename(path));
|
||||
if (!b)
|
||||
return -ENOMEM;
|
||||
if (FLAGS_SET(flags, OUTPUT_CGROUP_ID)) {
|
||||
cg_file_handle fh = CG_FILE_HANDLE_INIT;
|
||||
int mnt_id = -1;
|
||||
|
||||
printf("%s%s%s%s%s %s%s%s\n",
|
||||
prefix, glyph,
|
||||
if (name_to_handle_at(
|
||||
fd < 0 ? AT_FDCWD : fd,
|
||||
fd < 0 ? path : "",
|
||||
&fh.file_handle,
|
||||
&mnt_id,
|
||||
fd < 0 ? 0 : AT_EMPTY_PATH) < 0)
|
||||
log_debug_errno(errno, "Failed to determine cgroup ID of %s, ignoring: %m", path);
|
||||
else
|
||||
cgroupid = CG_FILE_HANDLE_CGROUPID(fh);
|
||||
}
|
||||
|
||||
r = path_extract_filename(path, &b);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to extract filename from cgroup path: %m");
|
||||
|
||||
printf("%s%s%s%s%s",
|
||||
prefix, special_glyph(glyph),
|
||||
delegate ? ansi_underline() : "",
|
||||
cg_unescape(b),
|
||||
delegate ? ansi_normal() : "",
|
||||
delegate ? ansi_highlight() : "",
|
||||
delegate ? special_glyph(SPECIAL_GLYPH_ELLIPSIS) : "",
|
||||
delegate ? ansi_normal() : "");
|
||||
|
||||
if (delegate)
|
||||
printf(" %s%s%s",
|
||||
ansi_highlight(),
|
||||
special_glyph(SPECIAL_GLYPH_ELLIPSIS),
|
||||
ansi_normal());
|
||||
|
||||
if (cgroupid != UINT64_MAX)
|
||||
printf(" %s(#%" PRIu64 ")%s", ansi_grey(), cgroupid, ansi_normal());
|
||||
|
||||
printf("\n");
|
||||
|
||||
if (FLAGS_SET(flags, OUTPUT_CGROUP_XATTRS) && fd >= 0) {
|
||||
_cleanup_free_ char *nl = NULL;
|
||||
char *xa;
|
||||
|
||||
r = flistxattr_malloc(fd, &nl);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to enumerate xattrs on '%s', ignoring: %m", path);
|
||||
|
||||
NULSTR_FOREACH(xa, nl) {
|
||||
_cleanup_free_ char *x = NULL, *y = NULL, *buf = NULL;
|
||||
int n;
|
||||
|
||||
if (!STARTSWITH_SET(xa, "user.", "trusted."))
|
||||
continue;
|
||||
|
||||
n = fgetxattr_malloc(fd, xa, &buf);
|
||||
if (n < 0) {
|
||||
log_debug_errno(r, "Failed to read xattr '%s' off '%s', ignoring: %m", xa, path);
|
||||
continue;
|
||||
}
|
||||
|
||||
x = cescape(xa);
|
||||
if (!x)
|
||||
return -ENOMEM;
|
||||
|
||||
y = cescape_length(buf, n);
|
||||
if (!y)
|
||||
return -ENOMEM;
|
||||
|
||||
printf("%s%s%s %s%s%s: %s\n",
|
||||
prefix,
|
||||
glyph == SPECIAL_GLYPH_TREE_BRANCH ? special_glyph(SPECIAL_GLYPH_TREE_VERTICAL) : " ",
|
||||
special_glyph(SPECIAL_GLYPH_ARROW),
|
||||
ansi_blue(), x, ansi_normal(),
|
||||
y);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -201,7 +274,7 @@ int show_cgroup_by_path(
|
||||
}
|
||||
|
||||
if (last) {
|
||||
r = show_cgroup_name(last, prefix, special_glyph(SPECIAL_GLYPH_TREE_BRANCH));
|
||||
r = show_cgroup_name(last, prefix, SPECIAL_GLYPH_TREE_BRANCH, flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -225,7 +298,7 @@ int show_cgroup_by_path(
|
||||
show_cgroup_one_by_path(path, prefix, n_columns, !!last, flags);
|
||||
|
||||
if (last) {
|
||||
r = show_cgroup_name(last, prefix, special_glyph(SPECIAL_GLYPH_TREE_RIGHT));
|
||||
r = show_cgroup_name(last, prefix, SPECIAL_GLYPH_TREE_RIGHT, flags);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -33,14 +33,20 @@ static inline bool OUTPUT_MODE_IS_JSON(OutputMode m) {
|
||||
|
||||
typedef enum OutputFlags {
|
||||
OUTPUT_SHOW_ALL = 1 << 0,
|
||||
OUTPUT_WARN_CUTOFF = 1 << 1,
|
||||
OUTPUT_FULL_WIDTH = 1 << 2,
|
||||
OUTPUT_COLOR = 1 << 3,
|
||||
OUTPUT_FULL_WIDTH = 1 << 1,
|
||||
OUTPUT_COLOR = 1 << 2,
|
||||
|
||||
/* Specific to log output */
|
||||
OUTPUT_WARN_CUTOFF = 1 << 3,
|
||||
OUTPUT_CATALOG = 1 << 4,
|
||||
OUTPUT_BEGIN_NEWLINE = 1 << 5,
|
||||
OUTPUT_UTC = 1 << 6,
|
||||
OUTPUT_KERNEL_THREADS = 1 << 7,
|
||||
OUTPUT_NO_HOSTNAME = 1 << 8,
|
||||
OUTPUT_NO_HOSTNAME = 1 << 7,
|
||||
|
||||
/* Specific to process tree output */
|
||||
OUTPUT_KERNEL_THREADS = 1 << 8,
|
||||
OUTPUT_CGROUP_XATTRS = 1 << 9,
|
||||
OUTPUT_CGROUP_ID = 1 << 10,
|
||||
} OutputFlags;
|
||||
|
||||
JsonFormatFlags output_mode_to_json_format_flags(OutputMode m);
|
||||
|
Loading…
Reference in New Issue
Block a user