From: Masatake YAMATO Date: Mon, 7 Mar 2022 13:19:28 +0000 (+0900) Subject: lsfd: fill ENDPOINTS column for FIFOs X-Git-Tag: v2.39-rc1~709^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5211d5a18082c52c31dfc92b3c710e8e32c8ef2c;p=thirdparty%2Futil-linux.git lsfd: fill ENDPOINTS column for FIFOs For FIFO type files, lsof can fill ENDPOINTS as following: _PID_,_COMMAND_,_ASSOC_[-r][-w] Example output: $ dd if=/dev/zero | nc -l 127.0.0.1 9091 > /dev/null & [1] 1707808 1707809 $ ./lsfd -p "1707808 1707809" -o+ENDPOINTS -Q '(type == "FIFO")' COMMAND PID USER ASSOC MODE TYPE SOURCE MNTID INODE NAME ENDPOINTS dd 1707808 yamato 1 -w- FIFO pipefs 14 73477636 pipe:[73477636] 1707809,nc,0r- nc 1707809 yamato 0 r-- FIFO pipefs 14 73477636 pipe:[73477636] 1707808,dd,1-w Signed-off-by: Masatake YAMATO --- diff --git a/misc-utils/lsfd-fifo.c b/misc-utils/lsfd-fifo.c index 63eb18c7c0..3799313cdb 100644 --- a/misc-utils/lsfd-fifo.c +++ b/misc-utils/lsfd-fifo.c @@ -25,6 +25,26 @@ #include "lsfd.h" +struct fifo { + struct file file; + struct ipc_endpoint endpoint; +}; + +struct fifo_ipc { + struct ipc ipc; + ino_t ino; +}; + +static inline char *fifo_xstrendpoint(struct file *file) +{ + char *str = NULL; + xasprintf(&str, "%d,%s,%d%c%c", + file->proc->pid, file->proc->command, file->association, + (file->mode & S_IRUSR)? 'r': '-', + (file->mode & S_IWUSR)? 'w': '-'); + return str; +} + static bool fifo_fill_column(struct proc *proc __attribute__((__unused__)), struct file *file, struct libscols_line *ln, @@ -45,6 +65,24 @@ static bool fifo_fill_column(struct proc *proc __attribute__((__unused__)), break; } return false; + case COL_ENDPOINTS: { + struct fifo *this = (struct fifo *)file; + struct list_head *e; + char *estr; + list_for_each_backwardly(e, &this->endpoint.ipc->endpoints) { + struct fifo *other = list_entry(e, struct fifo, endpoint.endpoints); + if (this == other) + continue; + if (str) + xstrputc(&str, '\n'); + estr = fifo_xstrendpoint(&other->file); + xstrappend(&str, estr); + free(estr); + } + if (!str) + return false; + break; + } default: return false; } @@ -56,9 +94,55 @@ static bool fifo_fill_column(struct proc *proc __attribute__((__unused__)), return true; } +static unsigned int fifo_get_hash(struct file *file) +{ + return (unsigned int)(file->stat.st_ino % UINT_MAX); +} + +static bool fifo_is_suitable_ipc(struct ipc *ipc, struct file *file) +{ + return ((struct fifo_ipc *)ipc)->ino == file->stat.st_ino; +} + +static struct ipc_class *fifo_get_ipc_class(struct file *file __attribute__((__unused__))) +{ + static struct ipc_class fifo_ipc_class = { + .get_hash = fifo_get_hash, + .is_suitable_ipc = fifo_is_suitable_ipc, + .free = NULL, + }; + return &fifo_ipc_class; +} + +static void fifo_initialize_content(struct file *file) +{ + struct fifo *fifo = (struct fifo *)file; + struct ipc *ipc; + unsigned int hash; + + INIT_LIST_HEAD(&fifo->endpoint.endpoints); + ipc = get_ipc(file); + if (ipc) + goto link; + + ipc = xmalloc(sizeof(struct fifo_ipc)); + ipc->class = fifo_get_ipc_class(file); + INIT_LIST_HEAD(&ipc->endpoints); + INIT_LIST_HEAD(&ipc->ipcs); + ((struct fifo_ipc *)ipc)->ino = file->stat.st_ino; + + hash = fifo_get_hash(file); + add_ipc(ipc, hash); + link: + fifo->endpoint.ipc = ipc; + list_add(&fifo->endpoint.endpoints, &ipc->endpoints); +} + const struct file_class fifo_class = { .super = &file_class, - .size = sizeof(struct file), + .size = sizeof(struct fifo), .fill_column = fifo_fill_column, + .initialize_content = fifo_initialize_content, .free_content = NULL, + .get_ipc_class = fifo_get_ipc_class, }; diff --git a/misc-utils/lsfd.1.adoc b/misc-utils/lsfd.1.adoc index ca9d8287d4..146908c33f 100644 --- a/misc-utils/lsfd.1.adoc +++ b/misc-utils/lsfd.1.adoc @@ -135,6 +135,17 @@ Device type (_blk_, _char_, or _nodev_). ENDPOINT <__string__>:: IPC endpoints information communicated with the fd. +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. FD <__number__>:: File descriptor for the file. diff --git a/misc-utils/lsfd.c b/misc-utils/lsfd.c index 88b9205cb1..0022ead6dc 100644 --- a/misc-utils/lsfd.c +++ b/misc-utils/lsfd.c @@ -133,7 +133,7 @@ static struct colinfo infos[] = { N_("ID of device containing file") }, [COL_DEVTYPE] = { "DEVTYPE", 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, N_("device type (blk, char, or nodev)") }, - [COL_ENDPOINTS] ={"ENDPOINTS",0, 0, SCOLS_JSON_STRING, + [COL_ENDPOINTS] ={"ENDPOINTS",0, SCOLS_FL_WRAP, SCOLS_JSON_STRING, N_("IPC endpoints information communicated with the fd") }, [COL_FLAGS] = { "FLAGS", 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, N_("flags specified when opening the file") }, @@ -347,8 +347,16 @@ static struct libscols_column *add_column(struct libscols_table *tb, const struc int flags = col->flags; cl = scols_table_new_column(tb, col->name, col->whint, flags); - if (cl) + if (cl) { scols_column_set_json_type(cl, col->json_type); + if (col->flags & SCOLS_FL_WRAP) { + scols_column_set_wrapfunc(cl, + scols_wrapnl_chunksize, + scols_wrapnl_nextchunk, + NULL); + scols_column_set_safechars(cl, "\n"); + } + } return cl; }