From: Masatake YAMATO Date: Sat, 4 Mar 2023 05:38:57 +0000 (+0900) Subject: lsfd: fill ENDPOINTS column for eventfd X-Git-Tag: v2.40-rc1~458^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d4fea4d089f4ae2e9cb6e73987dfff2269a86b2e;p=thirdparty%2Futil-linux.git lsfd: fill ENDPOINTS column for eventfd An example output: $ ./lsfd -Q '(TYPE == "eventfd") and (ENDPOINTS =~ ".+") ' -o+ENDPOINTS COMMAND PID USER ASSOC MODE TYPE SOURCE MNTID INODE NAME ENDPOINTS pipewire 17251 jet 40 rw- eventfd anon_inodefs 15 1060 id=818 17255,pipewire-pulse,26 pipewire 17251 jet 52 rw- eventfd anon_inodefs 15 1060 id=695 17255,pipewire-pulse,30 17255,pipewire-pulse,37 17255,pipewire-pulse,49 pipewire 17251 jet 54 rw- eventfd anon_inodefs 15 1060 id=845 17255,pipewire-pulse,31 pipewire 17251 jet 61 rw- eventfd anon_inodefs 15 1060 id=212 17255,pipewire-pulse,45 pipewire 17251 jet 62 rw- eventfd anon_inodefs 15 1060 id=224 17255,pipewire-pulse,46 pipewire-pulse 17255 jet 26 rw- eventfd anon_inodefs 15 1060 id=818 17251,pipewire,40 pipewire-pulse 17255 jet 30 rw- eventfd anon_inodefs 15 1060 id=695 17251,pipewire,52 17255,pipewire-pulse,37 17255,pipewire-pulse,49 pipewire-pulse 17255 jet 31 rw- eventfd anon_inodefs 15 1060 id=845 17251,pipewire,54 pipewire-pulse 17255 jet 37 rw- eventfd anon_inodefs 15 1060 id=695 17251,pipewire,52 17255,pipewire-pulse,30 17255,pipewire-pulse,49 pipewire-pulse 17255 jet 45 rw- eventfd anon_inodefs 15 1060 id=212 17251,pipewire,61 pipewire-pulse 17255 jet 46 rw- eventfd anon_inodefs 15 1060 id=224 17251,pipewire,62 pipewire-pulse 17255 jet 49 rw- eventfd anon_inodefs 15 1060 id=695 17251,pipewire,52 17255,pipewire-pulse,30 17255,pipewire-pulse,37 Signed-off-by: Masatake YAMATO --- diff --git a/misc-utils/lsfd-unkn.c b/misc-utils/lsfd-unkn.c index 853232eda5..7d025b40fc 100644 --- a/misc-utils/lsfd-unkn.c +++ b/misc-utils/lsfd-unkn.c @@ -45,6 +45,8 @@ struct anon_ops { void (*init)(struct unkn *); void (*free)(struct unkn *); int (*handle_fdinfo)(struct unkn *, const char *, const char *); + void (*attach_xinfo)(struct unkn *); + const struct ipc_class *ipc_class; }; static const struct anon_ops *anon_probe(const char *); @@ -117,6 +119,22 @@ static bool unkn_fill_column(struct proc *proc, return true; } +static void unkn_attach_xinfo(struct file *file) +{ + struct unkn *unkn = (struct unkn *)file; + if (unkn->anon_ops && unkn->anon_ops->attach_xinfo) + unkn->anon_ops->attach_xinfo(unkn); +} + +static const struct ipc_class *unkn_get_ipc_class(struct file *file) +{ + struct unkn *unkn = (struct unkn *)file; + + if (unkn->anon_ops && unkn->anon_ops->ipc_class) + return unkn->anon_ops->ipc_class; + return NULL; +} + static void unkn_init_content(struct file *file) { struct unkn *unkn = (struct unkn *)file; @@ -269,6 +287,35 @@ static const struct anon_ops anon_pidfd_ops = { struct anon_eventfd_data { int id; struct unkn *backptr; + struct ipc_endpoint endpoint; +}; + +struct eventfd_ipc { + struct ipc ipc; + int id; +}; + +static unsigned int anon_eventfd_get_hash(struct file *file) +{ + struct unkn *unkn = (struct unkn *)file; + struct anon_eventfd_data *data = (struct anon_eventfd_data *)unkn->anon_data; + + return (unsigned int)data->id; +} + +static bool anon_eventfd_is_suitable_ipc(struct ipc *ipc, struct file *file) +{ + struct unkn *unkn = (struct unkn *)file; + struct anon_eventfd_data *data = (struct anon_eventfd_data *)unkn->anon_data; + + return ((struct eventfd_ipc *)ipc)->id == data->id; +} + +static const struct ipc_class anon_eventfd_ipc_class = { + .size = sizeof(struct eventfd_ipc), + .get_hash = anon_eventfd_get_hash, + .is_suitable_ipc = anon_eventfd_is_suitable_ipc, + .free = NULL, }; static bool anon_eventfd_probe(const char *str) @@ -287,8 +334,10 @@ static char *anon_eventfd_get_name(struct unkn *unkn) static void anon_eventfd_init(struct unkn *unkn) { - unkn->anon_data = xcalloc(1, sizeof(struct anon_eventfd_data)); - ((struct anon_eventfd_data *)unkn->anon_data)->backptr = unkn; + struct anon_eventfd_data *data = xcalloc(1, sizeof(struct anon_eventfd_data)); + init_endpoint(&data->endpoint); + data->backptr = unkn; + unkn->anon_data = data; } static void anon_eventfd_free(struct unkn *unkn) @@ -296,6 +345,24 @@ static void anon_eventfd_free(struct unkn *unkn) free(unkn->anon_data); } +static void anon_eventfd_attach_xinfo(struct unkn *unkn) +{ + struct anon_eventfd_data *data = (struct anon_eventfd_data *)unkn->anon_data; + unsigned int hash; + struct ipc *ipc = get_ipc(&unkn->file); + if (ipc) + goto link; + + ipc = new_ipc(&anon_eventfd_ipc_class); + ((struct eventfd_ipc *)ipc)->id = data->id; + + hash = anon_eventfd_get_hash(&unkn->file); + add_ipc(ipc, hash); + + link: + add_endpoint(&data->endpoint, ipc); +} + static int anon_eventfd_handle_fdinfo(struct unkn *unkn, const char *key, const char *value) { if (strcmp(key, "eventfd-id") == 0) { @@ -310,6 +377,14 @@ static int anon_eventfd_handle_fdinfo(struct unkn *unkn, const char *key, const return 0; } +static inline char *anon_eventfd_data_xstrendpoint(struct file *file) +{ + char *str = NULL; + xasprintf(&str, "%d,%s,%d", + file->proc->pid, file->proc->command, file->association); + return str; +} + static bool anon_eventfd_fill_column(struct proc *proc __attribute__((__unused__)), struct unkn *unkn, struct libscols_line *ln __attribute__((__unused__)), @@ -323,6 +398,25 @@ static bool anon_eventfd_fill_column(struct proc *proc __attribute__((__unused_ case COL_EVENTFD_ID: xasprintf(str, "%d", data->id); return true; + case COL_ENDPOINTS: { + struct list_head *e; + char *estr; + foreach_endpoint(e, data->endpoint) { + struct anon_eventfd_data *other = list_entry(e, + struct anon_eventfd_data, + endpoint.endpoints); + if (data == other) + continue; + if (*str) + xstrputc(str, '\n'); + estr = anon_eventfd_data_xstrendpoint(&other->backptr->file); + xstrappend(str, estr); + free(estr); + } + if (!*str) + return false; + return true; + } default: return false; } @@ -336,6 +430,8 @@ static const struct anon_ops anon_eventfd_ops = { .init = anon_eventfd_init, .free = anon_eventfd_free, .handle_fdinfo = anon_eventfd_handle_fdinfo, + .attach_xinfo = anon_eventfd_attach_xinfo, + .ipc_class = &anon_eventfd_ipc_class, }; /* @@ -370,4 +466,6 @@ const struct file_class unkn_class = { .initialize_content = unkn_init_content, .free_content = unkn_content_free, .handle_fdinfo = unkn_handle_fdinfo, + .attach_xinfo = unkn_attach_xinfo, + .get_ipc_class = unkn_get_ipc_class, }; diff --git a/misc-utils/lsfd.1.adoc b/misc-utils/lsfd.1.adoc index d389b2876a..cfdaeea7be 100644 --- a/misc-utils/lsfd.1.adoc +++ b/misc-utils/lsfd.1.adoc @@ -146,19 +146,22 @@ Device type (`blk`, `char`, or `nodev`). ENDPOINT <``string``>:: IPC endpoints information communicated with the fd. ++ +*lsfd* collects endpoints within the processes that +*lsfd* scans; *lsfd* may miss some endpoints +if you limits the processes with *-p* option. ++ The format of the column depends on the object associated with the fd: -+ + FIFO type::: _PID_,_COMMAND_,_ASSOC_[-r][-w] + The last characters ([-r][-w]) represents the read and/or write mode of the endpoint. -+ -*lsfd* collects endpoints within the processes that -*lsfd* scans; *lsfd* may miss some endpoints -if you limits the processes with *-p* option. +eventfd type::: +_PID_,_COMMAND_,_ASSOC_ EVENTFD.ID <``number``>:: Eventfd ID.