From 426ff07f9a54503c5d8646a1589d4d7a7018d740 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Mon, 2 Oct 2023 23:03:06 +0900 Subject: [PATCH] lsfd: add SOCK.SHUTDOWN column An example output: # ./lsfd -p1 -Q '(TYPE == "UNIX-STREAM")' -o+SOCK.SHUTDOWN systemd 1 root 443 rw---m UNIX-STREAM sockfs 9 183103884 state=connected path=/run/systemd/journal/stdout r- systemd 1 root 462 rw---- UNIX-STREAM sockfs 9 11172039 state=listen path=/run/libvirt/libvirt-sock rw Signed-off-by: Masatake YAMATO --- misc-utils/lsfd-sock-xinfo.c | 33 ++++++++++++++++++++++++++++++++- misc-utils/lsfd-sock.c | 3 +++ misc-utils/lsfd.c | 3 +++ misc-utils/lsfd.h | 1 + 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/misc-utils/lsfd-sock-xinfo.c b/misc-utils/lsfd-sock-xinfo.c index 301da27889..a0e82026d7 100644 --- a/misc-utils/lsfd-sock-xinfo.c +++ b/misc-utils/lsfd-sock-xinfo.c @@ -404,6 +404,9 @@ struct unix_xinfo { int acceptcon; /* flags */ uint16_t type; uint8_t st; +#define is_shutdown_mask_set(mask) ((mask) & (1 << 2)) +#define set_shutdown_mask(mask) ((mask) |= (1 << 2)) + uint8_t shutdown_mask:3; struct unix_ipc *unix_ipc; char path[ UNIX_PATH_MAX @@ -519,6 +522,19 @@ static struct ipc_class *unix_get_ipc_class(struct sock_xinfo *sock_xinfo __attr return &unix_ipc_class; } +static bool unix_shutdown_chars(struct unix_xinfo *ux, char rw[2]) +{ + uint8_t mask = ux->shutdown_mask; + + if (is_shutdown_mask_set(mask)) { + rw[0] = ((mask & (1 << 0))? '-': 'r'); + rw[1] = ((mask & (1 << 1))? '-': 'w'); + return true; + } + + return false; +} + static inline char *unix_xstrendpoint(struct sock *sock) { char *str = NULL; @@ -552,6 +568,7 @@ static bool unix_fill_column(struct proc *proc __attribute__((__unused__)), struct unix_xinfo *ux = (struct unix_xinfo *)sock_xinfo; struct ipc *peer_ipc; struct list_head *e; + char shutdown_chars[3] = { 0 }; switch (column_id) { case COL_UNIX_PATH: @@ -578,6 +595,12 @@ static bool unix_fill_column(struct proc *proc __attribute__((__unused__)), if (*str) return true; break; + case COL_SOCK_SHUTDOWN: + if (unix_shutdown_chars(ux, shutdown_chars)) { + *str = xstrdup(shutdown_chars); + return true; + } + break; } return false; @@ -706,6 +729,14 @@ static bool handle_diag_unix(ino_t netns __attribute__((__unused__)), unix_refill_name(xinfo, RTA_DATA(attr), len); break; + case UNIX_DIAG_SHUTDOWN: + if (len < 1) + break; + + unix_xinfo->shutdown_mask = *(uint8_t *)RTA_DATA(attr); + set_shutdown_mask(unix_xinfo->shutdown_mask); + break; + case UNIX_DIAG_PEER: if (len < 4) break; @@ -725,7 +756,7 @@ static void load_xinfo_from_diag_unix(int diagsd, ino_t netns) struct unix_diag_req udr = { .sdiag_family = AF_UNIX, .udiag_states = -1, /* set the all bits. */ - .udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER, + .udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER | UNIX_DIAG_SHUTDOWN, }; send_diag_request(diagsd, &udr, sizeof(udr), handle_diag_unix, netns); diff --git a/misc-utils/lsfd-sock.c b/misc-utils/lsfd-sock.c index ee0aa737a6..4c75e6eaf9 100644 --- a/misc-utils/lsfd-sock.c +++ b/misc-utils/lsfd-sock.c @@ -120,6 +120,9 @@ static bool sock_fill_column(struct proc *proc __attribute__((__unused__)), ? "1" : "0"); break; + case COL_SOCK_SHUTDOWN: + str = xstrdup("??"); + break; default: return false; } diff --git a/misc-utils/lsfd.c b/misc-utils/lsfd.c index 13f6282c7e..7bd24d2677 100644 --- a/misc-utils/lsfd.c +++ b/misc-utils/lsfd.c @@ -296,6 +296,9 @@ static const struct colinfo infos[] = { [COL_SOCK_PROTONAME] = { "SOCK.PROTONAME", 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, N_("protocol name") }, + [COL_SOCK_SHUTDOWN] = { "SOCK.SHUTDOWN", + 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, + N_("shutdown state of socket ([-r?][-w?])") }, [COL_SOCK_STATE] = { "SOCK.STATE", 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, N_("State of socket") }, diff --git a/misc-utils/lsfd.h b/misc-utils/lsfd.h index 9cf87f8308..c9c975392f 100644 --- a/misc-utils/lsfd.h +++ b/misc-utils/lsfd.h @@ -99,6 +99,7 @@ enum { COL_SOCK_LISTENING, COL_SOCK_NETNS, COL_SOCK_PROTONAME, + COL_SOCK_SHUTDOWN, COL_SOCK_STATE, COL_SOCK_TYPE, COL_SOURCE, -- 2.47.3