From: Masatake YAMATO Date: Tue, 6 Jun 2023 22:30:06 +0000 (+0900) Subject: lsfd: print the masks specified in signalfds X-Git-Tag: v2.40-rc1~399^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b22d1e541ab5ecf126126bf686a390d8aefeb3f2;p=thirdparty%2Futil-linux.git lsfd: print the masks specified in signalfds An example output: # ./lsfd -p "$(pidof systemd-journald)" -Q '(TYPE == "signalfd")' COMMAND PID USER ASSOC MODE TYPE SOURCE MNTID INODE NAME systemd-journal 2382709 root 238 rw- signalfd anon_inodefs 15 1060 mask=USR1,USR2 systemd-journal 2382709 root 239 rw- signalfd anon_inodefs 15 1060 mask=INT,TERM systemd-journal 2382709 root 240 rw- signalfd anon_inodefs 15 1060 mask=35 Using signum_to_signame is suggested by Karel Zak . Signed-off-by: Masatake YAMATO --- diff --git a/misc-utils/lsfd-unkn.c b/misc-utils/lsfd-unkn.c index 9af0816f11..d5e44aa9a2 100644 --- a/misc-utils/lsfd-unkn.c +++ b/misc-utils/lsfd-unkn.c @@ -22,6 +22,7 @@ #include "xalloc.h" #include "nls.h" #include "libsmartcols.h" +#include "signames.h" #include "lsfd.h" @@ -715,6 +716,103 @@ static const struct anon_ops anon_timerfd_ops = { .handle_fdinfo = anon_timerfd_handle_fdinfo, }; +/* + * signalfd + */ +struct anon_signalfd_data { + uint64_t sigmask; +}; + +static bool anon_signalfd_probe(const char *str) +{ + return strncmp(str, "[signalfd]", 10) == 0; +} + +static void anon_signalfd_init(struct unkn *unkn) +{ + unkn->anon_data = xcalloc(1, sizeof(struct anon_signalfd_data)); +} + +static void anon_signalfd_free(struct unkn *unkn) +{ + struct anon_signalfd_data *data = unkn->anon_data; + free(data); +} + +static int anon_signalfd_handle_fdinfo(struct unkn *unkn, const char *key, const char *value) +{ + struct anon_signalfd_data *data = (struct anon_signalfd_data *)unkn->anon_data; + + if (strcmp(key, "sigmask") == 0) { + if (ul_strtou64(value, &data->sigmask, 16) < 0) { + data->sigmask = 0; + return 0; + } + } + return 0; +} + +static char *anon_signalfd_make_mask_string(const char* prefix, uint64_t sigmask) +{ + char *str = NULL; + + for (size_t i = 0; i < sizeof(sigmask) * 8; i++) { + if ((((uint64_t)0x1) << i) & sigmask) { + const int signum = i + 1; + const char *signame = signum_to_signame(signum); + + if (str) + xstrappend(&str, ","); + else if (prefix) + xstrappend(&str, prefix); + + if (signame) { + xstrappend(&str, signame); + } else { + char buf[BUFSIZ]; + snprintf(buf, sizeof(buf), "%d", signum); + xstrappend(&str, buf); + } + } + } + + return str; +} + +static char *anon_signalfd_get_name(struct unkn *unkn) +{ + struct anon_signalfd_data *data = (struct anon_signalfd_data *)unkn->anon_data; + return anon_signalfd_make_mask_string("mask=", data->sigmask); +} + +static bool anon_signalfd_fill_column(struct proc *proc __attribute__((__unused__)), + struct unkn *unkn, + struct libscols_line *ln __attribute__((__unused__)), + int column_id, + size_t column_index __attribute__((__unused__)), + char **str) +{ + struct anon_signalfd_data *data = (struct anon_signalfd_data *)unkn->anon_data; + + switch(column_id) { + case COL_SIGNALFD_MASK: + *str = anon_signalfd_make_mask_string(NULL, data->sigmask); + return true; + default: + return false; + } +} + +static const struct anon_ops anon_signalfd_ops = { + .class = "signalfd", + .probe = anon_signalfd_probe, + .get_name = anon_signalfd_get_name, + .fill_column = anon_signalfd_fill_column, + .init = anon_signalfd_init, + .free = anon_signalfd_free, + .handle_fdinfo = anon_signalfd_handle_fdinfo, +}; + /* * generic (fallback implementation) */ @@ -732,6 +830,7 @@ static const struct anon_ops *anon_ops[] = { &anon_eventfd_ops, &anon_eventpoll_ops, &anon_timerfd_ops, + &anon_signalfd_ops, }; static const struct anon_ops *anon_probe(const char *str) diff --git a/misc-utils/lsfd.c b/misc-utils/lsfd.c index decce120e4..590787bf43 100644 --- a/misc-utils/lsfd.c +++ b/misc-utils/lsfd.c @@ -255,6 +255,9 @@ static const struct colinfo infos[] = { [COL_RDEV] = { "RDEV", 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, N_("device ID (if special file)") }, + [COL_SIGNALFD_MASK] = { "SIGNALFD.MASK", + 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, + N_("masked signals") }, [COL_SIZE] = { "SIZE", 4, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, N_("file size"), }, diff --git a/misc-utils/lsfd.h b/misc-utils/lsfd.h index 7dcb553bf1..aeda9ef857 100644 --- a/misc-utils/lsfd.h +++ b/misc-utils/lsfd.h @@ -82,6 +82,7 @@ enum { COL_POS, COL_RAW_PROTOCOL, COL_RDEV, + COL_SIGNALFD_MASK, COL_SIZE, COL_SOCK_LISTENING, COL_SOCK_NETNS,