The values shown in the new columns are already shown in NAME column.
Showing these values together in the NAME column helps users
understand the pidfds opened quickly. However, the showing them
together is not suitable for machine processing. The newly introduced
columns are for machine processing.
Below an example output:
$ ./lsfd -o COMMAND,TYPE,PIDFD.COMM,PIDFD.PID -Q '(TYPE == "pidfd")'
COMMAND TYPE PIDFD.COMM PIDFD.PID
dbus-broker-lau pidfd dbus-broker 4661
dbus-broker-lau pidfd dbus-broker 4924
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
struct anon_ops {
const char *class;
char * (*get_name)(struct unkn *);
+ /* Return true is handled the column. */
+ bool (*fill_column)(struct proc *,
+ struct unkn *,
+ struct libscols_line *,
+ int,
+ size_t,
+ char **str);
void (*init)(struct unkn *);
void (*free)(struct unkn *);
int (*handle_fdinfo)(struct unkn *, const char *, const char *);
return strdup(name);
}
-static bool unkn_fill_column(struct proc *proc __attribute__((__unused__)),
+static bool unkn_fill_column(struct proc *proc,
struct file *file,
struct libscols_line *ln,
int column_id,
}
return false;
default:
+ if (unkn->anon_ops && unkn->anon_ops->fill_column) {
+ if (unkn->anon_ops->fill_column(proc, unkn, ln,
+ column_id, column_index, &str))
+ break;
+ }
return false;
}
return 0;
}
+static bool anon_pidfd_fill_column(struct proc *proc __attribute__((__unused__)),
+ struct unkn *unkn,
+ struct libscols_line *ln __attribute__((__unused__)),
+ int column_id,
+ size_t column_index __attribute__((__unused__)),
+ char **str)
+{
+ struct anon_pidfd_data *data = (struct anon_pidfd_data *)unkn->anon_data;
+
+ switch(column_id) {
+ case COL_PIDFD_COMM: {
+ struct proc *pidfd_proc = get_proc(data->pid);
+ char *pidfd_comm = NULL;
+ if (pidfd_proc)
+ pidfd_comm = pidfd_proc->command;
+ if (pidfd_comm) {
+ *str = strdup(pidfd_comm);
+ return true;
+ }
+ break;
+ }
+ case COL_PIDFD_NSPID:
+ if (data->nspid) {
+ *str = strdup(data->nspid);
+ return true;
+ }
+ break;
+ case COL_PIDFD_PID:
+ xasprintf(str, "%d", (int)data->pid);
+ return true;
+ }
+
+ return false;
+}
+
static struct anon_ops anon_pidfd_ops = {
.class = "pidfd",
.get_name = anon_pidfd_get_name,
+ .fill_column = anon_pidfd_fill_column,
.init = anon_pidfd_init,
.free = anon_pidfd_free,
.handle_fdinfo = anon_pidfd_handle_fdinfo,
static struct anon_ops anon_generic_ops = {
.class = NULL,
.get_name = NULL,
+ .fill_column = NULL,
.init = NULL,
.free = NULL,
.handle_fdinfo = NULL,
N_("PID of the process opening the file") },
[COL_PARTITION]={ "PARTITION",0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING,
N_("block device name resolved by /proc/partition") },
+ [COL_PIDFD_COMM]={"PIDFD.COMM",0.2,SCOLS_FL_TRUNC,SCOLS_JSON_STRING,
+ N_("command of the process targeted by the pidfd") },
+ [COL_PIDFD_NSPID]={"PIDFD.NSPID",0.2,SCOLS_FL_TRUNC,SCOLS_JSON_STRING,
+ N_("NSpid field in fdinfo of the pidfd") },
+ [COL_PIDFD_PID]={ "PIDFD.PID",5, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER,
+ N_("PID of the process targeted by the pidfd") },
[COL_POS] = { "POS", 5, SCOLS_FL_RIGHT, SCOLS_JSON_NUMBER,
N_("file position") },
[COL_PROTONAME]={ "PROTONAME",0, SCOLS_FL_RIGHT, SCOLS_JSON_STRING,
COL_NLINK,
COL_PARTITION,
COL_PID,
+ COL_PIDFD_COMM,
+ COL_PIDFD_NSPID,
+ COL_PIDFD_PID,
COL_POS,
COL_PROTONAME,
COL_RDEV,
- 3 UNKN anon_inodefs pid=1 comm=systemd nspid=1
-ASSOC,STTYPE,SOURCE,NAME: 0
+ 3 UNKN anon_inodefs pid=1 comm=systemd nspid=1 systemd 1
+ASSOC,STTYPE,SOURCE,NAME,PIDFD.COMM,PIDFD.PID: 0
PID=
FD=3
TARGET=1
-EXPR="(PID != ${TARGET}) and (FD == 3)"
+EXPR="(PID != ${TARGET}) and (FD == 3) and (PIDFD.PID == ${TARGET})"
{
coproc MKFDS { "$TS_HELPER_MKFDS" pidfd $FD target-pid=${TARGET} ; }
if read -u ${MKFDS[0]} PID; then
- ${TS_CMD_LSFD} -n -o ASSOC,STTYPE,SOURCE,NAME -p "${PID}" -p ${TARGET} -Q "${EXPR}"
- echo 'ASSOC,STTYPE,SOURCE,NAME': $?
+ ${TS_CMD_LSFD} -n -o ASSOC,STTYPE,SOURCE,NAME,PIDFD.COMM,PIDFD.PID -p "${PID}" -p ${TARGET} -Q "${EXPR}"
+ echo 'ASSOC,STTYPE,SOURCE,NAME,PIDFD.COMM,PIDFD.PID': $?
kill -CONT ${PID}
wait ${MKFDS_PID}