From: Masatake YAMATO Date: Sat, 3 Sep 2022 15:25:15 +0000 (+0900) Subject: lsfd: use TYPE column to show cooked file types X-Git-Tag: v2.39-rc1~527^2~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=be019f664db6eef7f2df38d31f1627d74a82fe65;p=thirdparty%2Futil-linux.git lsfd: use TYPE column to show cooked file types lsfd has two exclusive requirements: A. show quickly understandable information in limited display area, and B. provide primitive raw information for post-process tools. For the purpose A, summarizing information is nice. However, the summarized information is not suitable for tools. To satisfy the both requirements, I plan introducing new fields with a new convention. STTYPE represents the type information returned from stat(2). TYPE is the same as STTYPE but two exceptions; TYPE is filled with PROTONAME value if the target fd is a socket, or with AINODECLASS value if the target fd is a anonymous inode. Below an example output: $ ./lsfd -o COMMAND,TYPE,STTYPE,NAME -Q '(TYPE != STTYPE)' | head COMMAND TYPE STTYPE NAME systemd UNIX-STREAM SOCK UNIX-STREAM:[25493] systemd UNIX-STREAM SOCK UNIX-STREAM:[25493] systemd UNIX SOCK UNIX:[31445] systemd eventpoll UNKN anon_inode:[eventpoll] systemd signalfd UNKN anon_inode:[signalfd] systemd inotify UNKN anon_inode:inotify systemd timerfd UNKN anon_inode:[timerfd] systemd eventpoll UNKN anon_inode:[eventpoll] systemd inotify UNKN anon_inode:inotify STTYPE, column for tools, is printed only when the column is specified with -o option. Signed-off-by: Masatake YAMATO --- diff --git a/misc-utils/lsfd-file.c b/misc-utils/lsfd-file.c index 842bf03401..2b4e8dc968 100644 --- a/misc-utils/lsfd-file.c +++ b/misc-utils/lsfd-file.c @@ -126,6 +126,7 @@ static bool file_fill_column(struct proc *proc, && scols_line_set_data(ln, column_index, file->name)) err(EXIT_FAILURE, _("failed to add output data")); return true; + case COL_STTYPE: case COL_TYPE: ftype = file->stat.st_mode & S_IFMT; if (scols_line_set_data(ln, column_index, strftype(ftype))) diff --git a/misc-utils/lsfd-sock.c b/misc-utils/lsfd-sock.c index 0ed5663778..78fbd19c87 100644 --- a/misc-utils/lsfd-sock.c +++ b/misc-utils/lsfd-sock.c @@ -43,9 +43,9 @@ static bool sock_fill_column(struct proc *proc __attribute__((__unused__)), struct sock *sock = (struct sock *)file; switch(column_id) { case COL_TYPE: - if (scols_line_set_data(ln, column_index, "SOCK")) - err(EXIT_FAILURE, _("failed to add output data")); - return true; + if (!sock->protoname) + return false; + /* FALL THROUGH */ case COL_PROTONAME: if (sock->protoname) if (scols_line_set_data(ln, column_index, sock->protoname)) diff --git a/misc-utils/lsfd-unkn.c b/misc-utils/lsfd-unkn.c index 4bcebfcffa..1dd9d4b669 100644 --- a/misc-utils/lsfd-unkn.c +++ b/misc-utils/lsfd-unkn.c @@ -79,9 +79,9 @@ static bool unkn_fill_column(struct proc *proc __attribute__((__unused__)), } return false; case COL_TYPE: - if (scols_line_set_data(ln, column_index, "UNKN")) - err(EXIT_FAILURE, _("failed to add output data")); - return true; + if (!unkn->anon_ops) + return false; + /* FALL THROUGH */ case COL_AINODECLASS: if (unkn->anon_ops) { str = anon_get_class(unkn); diff --git a/misc-utils/lsfd.1.adoc b/misc-utils/lsfd.1.adoc index 0c3c56bfa4..51d92673e1 100644 --- a/misc-utils/lsfd.1.adoc +++ b/misc-utils/lsfd.1.adoc @@ -230,11 +230,16 @@ File size. SOURCE <``string``>:: File system, partition, or device containing the file. +STTYPE <``string``>:: +Raw file types returned from stat(2): BLK, CHR, DIR, FIFO, LINK, REG, SOCK, or UNKN. + TID <``number``>:: Thread ID of the process opening the file. TYPE <``string``>:: -File types: BLK, CHR, DIR, FIFO, LINK, REG, SOCK, or UNKN. +Cooked version of STTYPE. It is same as STTYPE with exceptions. +For SOCK, print the value for PROTONAME. +For UNKN, print the value for AINODECLASS if SOURCE is anon_inodefs. UID <``number``>:: User ID number. @@ -479,6 +484,7 @@ mailto:kzak@redhat.com[Karel Zak] *lsof*(8) *pidof*(1) *proc*(5) +*stat*(2) include::man-common/bugreports.adoc[] diff --git a/misc-utils/lsfd.c b/misc-utils/lsfd.c index f67301a1b2..093f55e06c 100644 --- a/misc-utils/lsfd.c +++ b/misc-utils/lsfd.c @@ -179,10 +179,12 @@ static struct colinfo infos[] = { N_("file size"), }, [COL_SOURCE] = { "SOURCE", 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, N_("file system, partition, or device containing file") }, + [COL_STTYPE] = { "STTYPE", 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, + N_("file type (raw)") }, [COL_TID] = { "TID", 5, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, N_("thread ID of the process opening the file") }, [COL_TYPE] = { "TYPE", 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, - N_("file type") }, + N_("file type (cooked)") }, [COL_UID] = { "UID", 0, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER, N_("user ID number of the process") }, [COL_USER] = { "USER", 0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING, @@ -267,31 +269,31 @@ static struct counter_spec default_counter_specs[] = { }, { .name = N_("regular files"), - .expr = "(FD >= 0) && (TYPE == 'REG')", + .expr = "(FD >= 0) && (_TYPE == 'REG')", }, { .name = N_("directories"), - .expr = "(FD >= 0) && (TYPE == 'DIR')", + .expr = "(FD >= 0) && (_TYPE == 'DIR')", }, { .name = N_("sockets"), - .expr = "(FD >= 0) && (TYPE == 'SOCK')", + .expr = "(FD >= 0) && (_TYPE == 'SOCK')", }, { .name = N_("fifos/pipes"), - .expr = "(FD >= 0) && (TYPE == 'FIFO')", + .expr = "(FD >= 0) && (_TYPE == 'FIFO')", }, { .name = N_("character devices"), - .expr = "(FD >= 0) && (TYPE == 'CHR')", + .expr = "(FD >= 0) && (_TYPE == 'CHR')", }, { .name = N_("block devices"), - .expr = "(FD >= 0) && (TYPE == 'BLK')", + .expr = "(FD >= 0) && (_TYPE == 'BLK')", }, { .name = N_("unknown types"), - .expr = "(FD >= 0) && (TYPE == 'UNKN')", + .expr = "(FD >= 0) && (_TYPE == 'UNKN')", } }; diff --git a/misc-utils/lsfd.h b/misc-utils/lsfd.h index 7e243c5fa2..bea5f8cfb1 100644 --- a/misc-utils/lsfd.h +++ b/misc-utils/lsfd.h @@ -63,6 +63,7 @@ enum { COL_RDEV, COL_SIZE, COL_SOURCE, + COL_STTYPE, COL_TID, COL_TYPE, COL_UID, /* process */ diff --git a/tests/expected/lsfd/column-ainodeclass b/tests/expected/lsfd/column-ainodeclass index fa164eb2a1..d3428760f5 100644 --- a/tests/expected/lsfd/column-ainodeclass +++ b/tests/expected/lsfd/column-ainodeclass @@ -1,4 +1,4 @@ - 3 UNKN pidfd -pidfd:ASSOC,TYPE,AINODECLASS: 0 - 3 UNKN inotify -inotify:ASSOC,TYPE,AINODECLASS: 0 + 3 UNKN pidfd +pidfd:ASSOC,STTYPE,AINODECLASS: 0 + 3 UNKN inotify +inotify:ASSOC,STTYPE,AINODECLASS: 0 diff --git a/tests/expected/lsfd/column-type b/tests/expected/lsfd/column-type new file mode 100644 index 0000000000..39684fac42 --- /dev/null +++ b/tests/expected/lsfd/column-type @@ -0,0 +1,8 @@ + 3 REG REG +ro-regular-file:ASSOC,STTYPE,TYPE: 0 + 3 UNKN pidfd +pidfd:ASSOC,STTYPE,TYPE: 0 + 3 UNKN inotify +inotify:ASSOC,STTYPE,TYPE: 0 + 3 SOCK UNIX +socketpair:ASSOC,STTYPE,TYPE: 0 diff --git a/tests/expected/lsfd/mkfds-pidfd b/tests/expected/lsfd/mkfds-pidfd index b962000157..5fbb3aa102 100644 --- a/tests/expected/lsfd/mkfds-pidfd +++ b/tests/expected/lsfd/mkfds-pidfd @@ -1,2 +1,2 @@ - 3 UNKN anon_inodefs pidfd: pid=1 comm=systemd nspid=1 -ASSOC,TYPE,SOURCE,NAME: 0 + 3 UNKN anon_inodefs pidfd: pid=1 comm=systemd nspid=1 +ASSOC,STTYPE,SOURCE,NAME: 0 diff --git a/tests/expected/lsfd/mkfds-socketpair b/tests/expected/lsfd/mkfds-socketpair index b2c95978b0..48b4ca24e0 100644 --- a/tests/expected/lsfd/mkfds-socketpair +++ b/tests/expected/lsfd/mkfds-socketpair @@ -1,3 +1,3 @@ - 3 rw- SOCK sockfs UNIX - 4 rw- SOCK sockfs UNIX -ASSOC,MODE,TYPE,SOURCE,PROTONAME: 0 + 3 rw- SOCK sockfs UNIX + 4 rw- SOCK sockfs UNIX +ASSOC,MODE,STTYPE,SOURCE,PROTONAME: 0 diff --git a/tests/ts/lsfd/column-ainodeclass b/tests/ts/lsfd/column-ainodeclass index 2e768bc35c..b80f7b8ac0 100755 --- a/tests/ts/lsfd/column-ainodeclass +++ b/tests/ts/lsfd/column-ainodeclass @@ -33,8 +33,8 @@ EXPR="(FD == 3)" for C in pidfd inotify; do coproc MKFDS { "$TS_HELPER_MKFDS" $C $FD ; } if read -u ${MKFDS[0]} PID; then - ${TS_CMD_LSFD} -n -o ASSOC,TYPE,AINODECLASS -p "${PID}" -Q "${EXPR}" - echo "$C"':ASSOC,TYPE,AINODECLASS': $? + ${TS_CMD_LSFD} -n -o ASSOC,STTYPE,AINODECLASS -p "${PID}" -Q "${EXPR}" + echo "$C"':ASSOC,STTYPE,AINODECLASS': $? kill -CONT ${PID} wait ${MKFDS_PID} diff --git a/tests/ts/lsfd/column-type b/tests/ts/lsfd/column-type new file mode 100755 index 0000000000..5ecb2516c8 --- /dev/null +++ b/tests/ts/lsfd/column-type @@ -0,0 +1,51 @@ +#!/bin/bash +# +# Copyright (C) 2022 Masatake YAMATO +# +# This file is part of util-linux. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This file is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +TS_TOPDIR="${0%/*}/../.." +TS_DESC="TYPE and STTYPE column" + +. $TS_TOPDIR/functions.sh +ts_init "$*" + +ts_check_test_command "$TS_CMD_LSFD" +ts_check_test_command "$TS_HELPER_MKFDS" + +ts_cd "$TS_OUTDIR" + +PID= +FD=3 +EXPR="(FD == 3)" + +{ + for C in ro-regular-file pidfd inotify socketpair; do + coproc MKFDS { + case $C in + socketpair) + argv="$((FD + 1)) socktype=DGRAM" + esac + "$TS_HELPER_MKFDS" $C $FD ${argv} + } + if read -u ${MKFDS[0]} PID; then + ${TS_CMD_LSFD} -n -o ASSOC,STTYPE,TYPE -p "${PID}" -Q "${EXPR}" + echo "$C"':ASSOC,STTYPE,TYPE': $? + + kill -CONT ${PID} + wait ${MKFDS_PID} + fi + done +} > $TS_OUTPUT 2>&1 + +ts_finalize diff --git a/tests/ts/lsfd/mkfds-mapped-packet-socket b/tests/ts/lsfd/mkfds-mapped-packet-socket index e7818e9286..bad564ea59 100755 --- a/tests/ts/lsfd/mkfds-mapped-packet-socket +++ b/tests/ts/lsfd/mkfds-mapped-packet-socket @@ -37,7 +37,7 @@ INTERFACE=lo { coproc MKFDS { "$TS_HELPER_MKFDS" mapped-packet-socket $FD interface=${INTERFACE}; } if read -u ${MKFDS[0]} PID; then - EXPR='(ASSOC == "shm") and (TYPE == "SOCK") and (MODE == "-w-")' + EXPR='(ASSOC == "shm") and (STTYPE == "SOCK") and (MODE == "-w-")' ${TS_CMD_LSFD} -p "$PID" -n -o PROTONAME -Q "${EXPR}" echo 'PROTONAME': $? fi diff --git a/tests/ts/lsfd/mkfds-pidfd b/tests/ts/lsfd/mkfds-pidfd index 112e478fcf..c707cd1970 100755 --- a/tests/ts/lsfd/mkfds-pidfd +++ b/tests/ts/lsfd/mkfds-pidfd @@ -36,8 +36,8 @@ EXPR="(PID != ${TARGET}) and (FD == 3)" { coproc MKFDS { "$TS_HELPER_MKFDS" pidfd $FD target-pid=${TARGET} ; } if read -u ${MKFDS[0]} PID; then - ${TS_CMD_LSFD} -n -o ASSOC,TYPE,SOURCE,NAME -p "${PID}" -p ${TARGET} -Q "${EXPR}" - echo 'ASSOC,TYPE,SOURCE,NAME': $? + ${TS_CMD_LSFD} -n -o ASSOC,STTYPE,SOURCE,NAME -p "${PID}" -p ${TARGET} -Q "${EXPR}" + echo 'ASSOC,STTYPE,SOURCE,NAME': $? kill -CONT ${PID} wait ${MKFDS_PID} diff --git a/tests/ts/lsfd/mkfds-socketpair b/tests/ts/lsfd/mkfds-socketpair index 7c0ef7d965..d20800d0a9 100755 --- a/tests/ts/lsfd/mkfds-socketpair +++ b/tests/ts/lsfd/mkfds-socketpair @@ -37,8 +37,8 @@ EXPR= coproc MKFDS { "$TS_HELPER_MKFDS" socketpair $FD0 $FD1 socktype=DGRAM; } if read -u ${MKFDS[0]} PID; then EXPR='(PID == '"${PID}"') and ((FD == '"$FD0"') or (FD == '"$FD1"'))' - ${TS_CMD_LSFD} -n -o ASSOC,MODE,TYPE,SOURCE,PROTONAME -Q "${EXPR}" | sed -e 's/UNIX-DGRAM/UNIX/' - echo 'ASSOC,MODE,TYPE,SOURCE,PROTONAME': $? + ${TS_CMD_LSFD} -n -o ASSOC,MODE,STTYPE,SOURCE,PROTONAME -Q "${EXPR}" | sed -e 's/UNIX-DGRAM/UNIX/' + echo 'ASSOC,MODE,STTYPE,SOURCE,PROTONAME': $? kill -CONT ${PID} wait ${MKFDS_PID}