From: Xi Ruoyao Date: Wed, 3 Apr 2024 15:29:34 +0800 Subject: lsfd: Refactor the pidfd logic into lsfd-pidfd.c Git-repo: https://github.com/util-linux/util-linux.git Git-commit: bf6645dc1edef09ad378cc5b9eb2c93861408735 Patch-mainline: yes References: kernel 6.9 We'll reuse these logic for pidfd support on Linux >= 6.9. This should be a no-functional change. Besides moving the code, this change also renames anon_pidfd_data to pidfd_data, and removes a redundant nullity check for free (because free(NULL) will just do nothing per the C standard). Signed-off-by: Xi Ruoyao Signed-off-by: Jiri Slaby --- misc-utils/Makemodule.am | 4 +- misc-utils/lsfd-pidfd.c | 95 ++++++++++++++++++++++++++++++++++++++++ misc-utils/lsfd-pidfd.h | 37 ++++++++++++++++ misc-utils/lsfd-unkn.c | 71 +++++------------------------- misc-utils/meson.build | 1 + 5 files changed, 147 insertions(+), 61 deletions(-) create mode 100644 misc-utils/lsfd-pidfd.c create mode 100644 misc-utils/lsfd-pidfd.h diff --git a/misc-utils/Makemodule.am b/misc-utils/Makemodule.am index 9edf3d98..7622a5d7 100644 --- a/misc-utils/Makemodule.am +++ b/misc-utils/Makemodule.am @@ -298,7 +298,9 @@ lsfd_SOURCES = \ misc-utils/lsfd-sock.h \ misc-utils/lsfd-sock-xinfo.c \ misc-utils/lsfd-unkn.c \ - misc-utils/lsfd-fifo.c + misc-utils/lsfd-fifo.c \ + misc-utils/lsfd-pidfd.h \ + misc-utils/lsfd-pidfd.c lsfd_LDADD = $(LDADD) $(MQ_LIBS) libsmartcols.la libcommon.la lsfd_CFLAGS = $(AM_CFLAGS) -I$(ul_libsmartcols_incdir) endif diff --git a/misc-utils/lsfd-pidfd.c b/misc-utils/lsfd-pidfd.c new file mode 100644 index 00000000..430a8028 --- /dev/null +++ b/misc-utils/lsfd-pidfd.c @@ -0,0 +1,95 @@ +/* + * lsfd-pidfd.c - handle pidfd (from anon_inode or pidfs) + * + * Copyright (C) 2024 Xi Ruoyao + * + * Refactored and moved out from lsfd-unkn.c (originally authored by + * Masatake YAMATO ). + * + * This program 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 program is distributed in the hope that it would 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#include "strutils.h" +#include "xalloc.h" + +#include "lsfd.h" +#include "lsfd-pidfd.h" + +int pidfd_handle_fdinfo(struct pidfd_data *data, const char *key, + const char *value) +{ + if (strcmp(key, "Pid") == 0) { + uint64_t pid; + int rc = ul_strtou64(value, &pid, 10); + + if (rc < 0) + return 0; /* ignore -- parse failed */ + + data->pid = (pid_t)pid; + return 1; + } else if (strcmp(key, "NSpid") == 0) { + data->nspid = xstrdup(value); + return 1; + } + + return 0; +} + +char *pidfd_get_name(struct pidfd_data *data) +{ + char *str = NULL; + char *comm = NULL; + struct proc *proc = get_proc(data->pid); + + if (proc) + comm = proc->command; + + xasprintf(&str, "pid=%d comm=%s nspid=%s", + data->pid, + comm ? comm : "", + data->nspid ? data->nspid : ""); + return str; +} + +bool pidfd_fill_column(struct pidfd_data *data, int column_id, char **str) +{ + 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 = xstrdup(pidfd_comm); + return true; + } + break; + } + case COL_PIDFD_NSPID: + if (data->nspid) { + *str = xstrdup(data->nspid); + return true; + } + break; + case COL_PIDFD_PID: + xasprintf(str, "%d", (int)data->pid); + return true; + } + + return false; +} diff --git a/misc-utils/lsfd-pidfd.h b/misc-utils/lsfd-pidfd.h new file mode 100644 index 00000000..2f65d3b3 --- /dev/null +++ b/misc-utils/lsfd-pidfd.h @@ -0,0 +1,37 @@ +/* + * lsfd-pidfd.h - handle pidfd (from anon_inode or pidfs) + * + * Copyright (C) 2024 Xi Ruoyao + * + * This program 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 program is distributed in the hope that it would 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +struct pidfd_data { + pid_t pid; + char *nspid; +}; + +int pidfd_handle_fdinfo(struct pidfd_data *, const char *, const char *); +char *pidfd_get_name(struct pidfd_data *); +bool pidfd_fill_column(struct pidfd_data *, int, char **); + +static inline void __attribute__((nonnull(1))) +pidfd_free(struct pidfd_data *data) +{ + free(data->nspid); +} diff --git a/misc-utils/lsfd-unkn.c b/misc-utils/lsfd-unkn.c index 8f6e9084..8e257f47 100644 --- a/misc-utils/lsfd-unkn.c +++ b/misc-utils/lsfd-unkn.c @@ -28,6 +28,7 @@ #include "timeutils.h" #include "lsfd.h" +#include "lsfd-pidfd.h" #define offsetofend(TYPE, MEMBER) \ (offsetof(TYPE, MEMBER) + sizeof_member(TYPE, MEMBER)) @@ -183,10 +184,6 @@ static int unkn_handle_fdinfo(struct file *file, const char *key, const char *va /* * pidfd */ -struct anon_pidfd_data { - pid_t pid; - char *nspid; -}; static bool anon_pidfd_probe(const char *str) { @@ -195,51 +192,28 @@ static bool anon_pidfd_probe(const char *str) static char *anon_pidfd_get_name(struct unkn *unkn) { - char *str = NULL; - struct anon_pidfd_data *data = (struct anon_pidfd_data *)unkn->anon_data; + struct pidfd_data *data = (struct pidfd_data *)unkn->anon_data; - char *comm = NULL; - struct proc *proc = get_proc(data->pid); - if (proc) - comm = proc->command; - - xasprintf(&str, "pid=%d comm=%s nspid=%s", - data->pid, - comm? comm: "", - data->nspid? data->nspid: ""); - return str; + return pidfd_get_name(data); } static void anon_pidfd_init(struct unkn *unkn) { - unkn->anon_data = xcalloc(1, sizeof(struct anon_pidfd_data)); + unkn->anon_data = xcalloc(1, sizeof(struct pidfd_data)); } static void anon_pidfd_free(struct unkn *unkn) { - struct anon_pidfd_data *data = (struct anon_pidfd_data *)unkn->anon_data; + struct pidfd_data *data = (struct pidfd_data *)unkn->anon_data; - if (data->nspid) - free(data->nspid); + pidfd_free(data); free(data); } static int anon_pidfd_handle_fdinfo(struct unkn *unkn, const char *key, const char *value) { - if (strcmp(key, "Pid") == 0) { - uint64_t pid; - - int rc = ul_strtou64(value, &pid, 10); - if (rc < 0) - return 0; /* ignore -- parse failed */ - ((struct anon_pidfd_data *)unkn->anon_data)->pid = (pid_t)pid; - return 1; - } else if (strcmp(key, "NSpid") == 0) { - ((struct anon_pidfd_data *)unkn->anon_data)->nspid = xstrdup(value); - return 1; - - } - return 0; + return pidfd_handle_fdinfo((struct pidfd_data *)unkn->anon_data, + key, value); } static bool anon_pidfd_fill_column(struct proc *proc __attribute__((__unused__)), @@ -249,32 +223,9 @@ static bool anon_pidfd_fill_column(struct proc *proc __attribute__((__unused__) 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 = xstrdup(pidfd_comm); - return true; - } - break; - } - case COL_PIDFD_NSPID: - if (data->nspid) { - *str = xstrdup(data->nspid); - return true; - } - break; - case COL_PIDFD_PID: - xasprintf(str, "%d", (int)data->pid); - return true; - } - - return false; + return pidfd_fill_column((struct pidfd_data *)unkn->anon_data, + column_id, + str); } static const struct anon_ops anon_pidfd_ops = { diff --git a/misc-utils/meson.build b/misc-utils/meson.build index 847b1012..68ea9777 100644 --- a/misc-utils/meson.build +++ b/misc-utils/meson.build @@ -56,6 +56,7 @@ lsfd_sources = files ( 'lsfd-sock-xinfo.c', 'lsfd-unkn.c', 'lsfd-fifo.c', + 'lsfd-pidfd.c', ) uuidgen_sources = files( -- 2.45.0