Browse Source

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 <yamato@redhat.com>
pull/1622/head
Masatake YAMATO 5 months ago
parent
commit
5211d5a180
  1. 86
      misc-utils/lsfd-fifo.c
  2. 11
      misc-utils/lsfd.1.adoc
  3. 12
      misc-utils/lsfd.c

86
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,
};

11
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.

12
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;
}

Loading…
Cancel
Save