From: Masatake YAMATO Date: Sat, 27 May 2023 17:49:00 +0000 (+0900) Subject: lsfd: print file descriptors targeted by eventpoll files X-Git-Tag: v2.40-rc1~428 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c2e2dd6008766945d5daf35f76bbef7c7edf4492;p=thirdparty%2Futil-linux.git lsfd: print file descriptors targeted by eventpoll files Signed-off-by: Masatake YAMATO --- diff --git a/misc-utils/lsfd-unkn.c b/misc-utils/lsfd-unkn.c index 7d025b40fc..6ecdc76f20 100644 --- a/misc-utils/lsfd-unkn.c +++ b/misc-utils/lsfd-unkn.c @@ -434,6 +434,123 @@ static const struct anon_ops anon_eventfd_ops = { .ipc_class = &anon_eventfd_ipc_class, }; +/* + * eventpoll + */ +struct anon_eventpoll_data { + size_t count; + int *tfds; +}; + + +static bool anon_eventpoll_probe(const char *str) +{ + return strncmp(str, "[eventpoll]", 11) == 0; +} + +static void anon_eventpoll_init(struct unkn *unkn) +{ + unkn->anon_data = xcalloc(1, sizeof(struct anon_eventpoll_data)); +} + +static void anon_eventpoll_free(struct unkn *unkn) +{ + struct anon_eventpoll_data *data = unkn->anon_data; + free (data->tfds); + free (data); +} + +static int anon_eventpoll_handle_fdinfo(struct unkn *unkn, const char *key, const char *value) +{ + struct anon_eventpoll_data *data; + if (strcmp(key, "tfd") == 0) { + unsigned long tfd; + char *end = NULL; + + errno = 0; + tfd = strtoul(value, &end, 0); + if (errno != 0) + return 0; /* ignore -- parse failed */ + + data = (struct anon_eventpoll_data *)unkn->anon_data; + data->tfds = xreallocarray (data->tfds, ++data->count, sizeof(int)); + data->tfds[data->count - 1] = (int)tfd; + return 1; + } + return 0; +} + +static int intcmp (const void *a, const void *b) +{ + int ai = *(int *)a; + int bi = *(int *)b; + + return ai - bi; +} + +static void anon_eventpoll_attach_xinfo(struct unkn *unkn) +{ + struct anon_eventpoll_data *data = (struct anon_eventpoll_data *)unkn->anon_data; + qsort (data->tfds, data->count, sizeof (data->tfds[0]), + intcmp); +} + +static char *anon_eventpoll_make_tfds_string(struct anon_eventpoll_data *data, + const char *prefix) +{ + char *str = prefix? xstrdup(prefix): NULL; + + char buf[256]; + for (size_t i = 0; i < data->count; i++) { + size_t offset = 0; + + if (i > 0) { + buf[0] = ','; + offset = 1; + } + snprintf(buf + offset, sizeof(buf) - offset, "%d", data->tfds[i]); + xstrappend(&str, buf); + } + return str; +} + +static char *anon_eventpoll_get_name(struct unkn *unkn) +{ + return anon_eventpoll_make_tfds_string ((struct anon_eventpoll_data *)unkn->anon_data, + "tfds="); +} + +static bool anon_eventpoll_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_eventpoll_data *data = (struct anon_eventpoll_data *)unkn->anon_data; + + switch(column_id) { + case COL_EVENTPOLL_TFDS: + *str =anon_eventpoll_make_tfds_string (data, NULL); + if (*str) + return true; + break; + } + + return false; +} + +static const struct anon_ops anon_eventpoll_ops = { + .class = "eventpoll", + .probe = anon_eventpoll_probe, + .get_name = anon_eventpoll_get_name, + .fill_column = anon_eventpoll_fill_column, + .init = anon_eventpoll_init, + .free = anon_eventpoll_free, + .handle_fdinfo = anon_eventpoll_handle_fdinfo, + .attach_xinfo = anon_eventpoll_attach_xinfo, +}; + /* * generic (fallback implementation) */ @@ -449,6 +566,7 @@ static const struct anon_ops anon_generic_ops = { static const struct anon_ops *anon_ops[] = { &anon_pidfd_ops, &anon_eventfd_ops, + &anon_eventpoll_ops, }; static const struct anon_ops *anon_probe(const char *str) diff --git a/misc-utils/lsfd.1.adoc b/misc-utils/lsfd.1.adoc index 11e7ee7001..04340329cb 100644 --- a/misc-utils/lsfd.1.adoc +++ b/misc-utils/lsfd.1.adoc @@ -167,6 +167,9 @@ _PID_,_COMMAND_,_ASSOC_ EVENTFD.ID <``number``>:: Eventfd ID. +EVENTPOLL.TFDS <``string``>>:: +File descriptors targeted by the eventpoll file. + FD <``number``>:: File descriptor for the file. @@ -226,6 +229,9 @@ Cooked version of KNAME. It is mostly same as KNAME. + Some files have special formats and information sources: + +eventpoll::: +tfds=_EVENTPOLL.TFDS_ ++ eventfd::: id=_EVENTFD.ID_ + diff --git a/misc-utils/lsfd.c b/misc-utils/lsfd.c index d9c1a00bc2..9c56460e13 100644 --- a/misc-utils/lsfd.c +++ b/misc-utils/lsfd.c @@ -150,18 +150,18 @@ static const struct colinfo infos[] = { [COL_EVENTFD_ID] = {"EVENTFD.ID", 0, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, N_("eventfd ID") }, - [COL_FLAGS] = { "FLAGS", - 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, - N_("flags specified when opening the file") }, + [COL_EVENTPOLL_TFDS] = {"EVENTPOLL.TFDS", + 0, SCOLS_FL_WRAP, SCOLS_JSON_STRING, + N_("file descriptors targeted by the eventpoll file") }, [COL_FD] = { "FD", 0, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, N_("file descriptor for the file") }, + [COL_FLAGS] = { "FLAGS", + 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, + N_("flags specified when opening the file") }, [COL_FUID] = { "FUID", 0, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, N_("user ID number of the file's owner") }, - [COL_INODE] = { "INODE", - 0, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, - N_("inode number") }, [COL_INET_LADDR] = { "INET.LADDR", 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, N_("local IP address") }, @@ -174,6 +174,9 @@ static const struct colinfo infos[] = { [COL_INET6_RADDR] = { "INET6.RADDR", 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, N_("remote IPv6 address") }, + [COL_INODE] = { "INODE", + 0, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, + N_("inode number") }, [COL_KNAME] = { "KNAME", 0.4, SCOLS_FL_TRUNC, SCOLS_JSON_STRING, N_("name of the file (raw)") }, diff --git a/misc-utils/lsfd.h b/misc-utils/lsfd.h index dc02e30ecb..5b653658b5 100644 --- a/misc-utils/lsfd.h +++ b/misc-utils/lsfd.h @@ -47,13 +47,15 @@ enum { COL_DEVTYPE, COL_ENDPOINTS, COL_EVENTFD_ID, + COL_EVENTPOLL_TFDS, COL_FD, COL_FLAGS, - COL_INODE, + COL_FUID, /* file */ COL_INET_LADDR, COL_INET_RADDR, COL_INET6_LADDR, COL_INET6_RADDR, + COL_INODE, COL_KNAME, COL_KTHREAD, COL_MAJMIN, @@ -68,6 +70,7 @@ enum { COL_NLINK, COL_NS_NAME, COL_NS_TYPE, + COL_OWNER, /* file */ COL_PACKET_IFACE, COL_PACKET_PROTOCOL, COL_PARTITION, @@ -104,8 +107,6 @@ enum { COL_UID, /* process */ COL_UNIX_PATH, COL_USER, /* process */ - COL_FUID, /* file */ - COL_OWNER, /* file */ LSFD_N_COLS /* This must be at last. */ };