]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsfd: fill ENDPOINTS column for eventfd
authorMasatake YAMATO <yamato@redhat.com>
Sat, 4 Mar 2023 05:38:57 +0000 (14:38 +0900)
committerMasatake YAMATO <yamato@redhat.com>
Thu, 18 May 2023 18:27:27 +0000 (03:27 +0900)
An example output:

  $ ./lsfd -Q '(TYPE == "eventfd") and (ENDPOINTS =~ ".+") ' -o+ENDPOINTS
  COMMAND          PID USER ASSOC MODE    TYPE       SOURCE MNTID INODE NAME   ENDPOINTS
  pipewire       17251  jet    40  rw- eventfd anon_inodefs    15  1060 id=818 17255,pipewire-pulse,26
  pipewire       17251  jet    52  rw- eventfd anon_inodefs    15  1060 id=695 17255,pipewire-pulse,30
       17255,pipewire-pulse,37
       17255,pipewire-pulse,49
  pipewire       17251  jet    54  rw- eventfd anon_inodefs    15  1060 id=845 17255,pipewire-pulse,31
  pipewire       17251  jet    61  rw- eventfd anon_inodefs    15  1060 id=212 17255,pipewire-pulse,45
  pipewire       17251  jet    62  rw- eventfd anon_inodefs    15  1060 id=224 17255,pipewire-pulse,46
  pipewire-pulse 17255  jet    26  rw- eventfd anon_inodefs    15  1060 id=818 17251,pipewire,40
  pipewire-pulse 17255  jet    30  rw- eventfd anon_inodefs    15  1060 id=695 17251,pipewire,52
       17255,pipewire-pulse,37
       17255,pipewire-pulse,49
  pipewire-pulse 17255  jet    31  rw- eventfd anon_inodefs    15  1060 id=845 17251,pipewire,54
  pipewire-pulse 17255  jet    37  rw- eventfd anon_inodefs    15  1060 id=695 17251,pipewire,52
       17255,pipewire-pulse,30
       17255,pipewire-pulse,49
  pipewire-pulse 17255  jet    45  rw- eventfd anon_inodefs    15  1060 id=212 17251,pipewire,61
  pipewire-pulse 17255  jet    46  rw- eventfd anon_inodefs    15  1060 id=224 17251,pipewire,62
  pipewire-pulse 17255  jet    49  rw- eventfd anon_inodefs    15  1060 id=695 17251,pipewire,52
       17255,pipewire-pulse,30
       17255,pipewire-pulse,37

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
misc-utils/lsfd-unkn.c
misc-utils/lsfd.1.adoc

index 853232eda5f86b62e056f3a29bc28be72c836ea9..7d025b40fc4afcda4f267c766db7b0cbcecb8b4e 100644 (file)
@@ -45,6 +45,8 @@ struct anon_ops {
        void (*init)(struct unkn *);
        void (*free)(struct unkn *);
        int (*handle_fdinfo)(struct unkn *, const char *, const char *);
+       void (*attach_xinfo)(struct unkn *);
+       const struct ipc_class *ipc_class;
 };
 
 static const struct anon_ops *anon_probe(const char *);
@@ -117,6 +119,22 @@ static bool unkn_fill_column(struct proc *proc,
        return true;
 }
 
+static void unkn_attach_xinfo(struct file *file)
+{
+       struct unkn *unkn = (struct unkn *)file;
+       if (unkn->anon_ops && unkn->anon_ops->attach_xinfo)
+               unkn->anon_ops->attach_xinfo(unkn);
+}
+
+static const struct ipc_class *unkn_get_ipc_class(struct file *file)
+{
+       struct unkn *unkn = (struct unkn *)file;
+
+       if (unkn->anon_ops && unkn->anon_ops->ipc_class)
+               return unkn->anon_ops->ipc_class;
+       return NULL;
+}
+
 static void unkn_init_content(struct file *file)
 {
        struct unkn *unkn = (struct unkn *)file;
@@ -269,6 +287,35 @@ static const struct anon_ops anon_pidfd_ops = {
 struct anon_eventfd_data {
        int id;
        struct unkn *backptr;
+       struct ipc_endpoint endpoint;
+};
+
+struct eventfd_ipc {
+       struct ipc ipc;
+       int id;
+};
+
+static unsigned int anon_eventfd_get_hash(struct file *file)
+{
+       struct unkn *unkn = (struct unkn *)file;
+       struct anon_eventfd_data *data = (struct anon_eventfd_data *)unkn->anon_data;
+
+       return (unsigned int)data->id;
+}
+
+static bool anon_eventfd_is_suitable_ipc(struct ipc *ipc, struct file *file)
+{
+       struct unkn *unkn = (struct unkn *)file;
+       struct anon_eventfd_data *data = (struct anon_eventfd_data *)unkn->anon_data;
+
+       return ((struct eventfd_ipc *)ipc)->id == data->id;
+}
+
+static const struct ipc_class anon_eventfd_ipc_class = {
+       .size = sizeof(struct eventfd_ipc),
+       .get_hash = anon_eventfd_get_hash,
+       .is_suitable_ipc = anon_eventfd_is_suitable_ipc,
+       .free = NULL,
 };
 
 static bool anon_eventfd_probe(const char *str)
@@ -287,8 +334,10 @@ static char *anon_eventfd_get_name(struct unkn *unkn)
 
 static void anon_eventfd_init(struct unkn *unkn)
 {
-       unkn->anon_data = xcalloc(1, sizeof(struct anon_eventfd_data));
-       ((struct anon_eventfd_data *)unkn->anon_data)->backptr = unkn;
+       struct anon_eventfd_data *data = xcalloc(1, sizeof(struct anon_eventfd_data));
+       init_endpoint(&data->endpoint);
+       data->backptr = unkn;
+       unkn->anon_data = data;
 }
 
 static void anon_eventfd_free(struct unkn *unkn)
@@ -296,6 +345,24 @@ static void anon_eventfd_free(struct unkn *unkn)
        free(unkn->anon_data);
 }
 
+static void anon_eventfd_attach_xinfo(struct unkn *unkn)
+{
+       struct anon_eventfd_data *data = (struct anon_eventfd_data *)unkn->anon_data;
+       unsigned int hash;
+       struct ipc *ipc = get_ipc(&unkn->file);
+       if (ipc)
+               goto link;
+
+       ipc = new_ipc(&anon_eventfd_ipc_class);
+       ((struct eventfd_ipc *)ipc)->id = data->id;
+
+       hash = anon_eventfd_get_hash(&unkn->file);
+       add_ipc(ipc, hash);
+
+ link:
+       add_endpoint(&data->endpoint, ipc);
+}
+
 static int anon_eventfd_handle_fdinfo(struct unkn *unkn, const char *key, const char *value)
 {
        if (strcmp(key, "eventfd-id") == 0) {
@@ -310,6 +377,14 @@ static int anon_eventfd_handle_fdinfo(struct unkn *unkn, const char *key, const
        return 0;
 }
 
+static inline char *anon_eventfd_data_xstrendpoint(struct file *file)
+{
+       char *str = NULL;
+       xasprintf(&str, "%d,%s,%d",
+                 file->proc->pid, file->proc->command, file->association);
+       return str;
+}
+
 static bool anon_eventfd_fill_column(struct proc *proc  __attribute__((__unused__)),
                                     struct unkn *unkn,
                                     struct libscols_line *ln __attribute__((__unused__)),
@@ -323,6 +398,25 @@ static bool anon_eventfd_fill_column(struct proc *proc  __attribute__((__unused_
        case COL_EVENTFD_ID:
                xasprintf(str, "%d", data->id);
                return true;
+       case COL_ENDPOINTS: {
+               struct list_head *e;
+               char *estr;
+               foreach_endpoint(e, data->endpoint) {
+                       struct anon_eventfd_data *other = list_entry(e,
+                                                                    struct anon_eventfd_data,
+                                                                    endpoint.endpoints);
+                       if (data == other)
+                               continue;
+                       if (*str)
+                               xstrputc(str, '\n');
+                       estr = anon_eventfd_data_xstrendpoint(&other->backptr->file);
+                       xstrappend(str, estr);
+                       free(estr);
+               }
+               if (!*str)
+                       return false;
+               return true;
+       }
        default:
                return false;
        }
@@ -336,6 +430,8 @@ static const struct anon_ops anon_eventfd_ops = {
        .init = anon_eventfd_init,
        .free = anon_eventfd_free,
        .handle_fdinfo = anon_eventfd_handle_fdinfo,
+       .attach_xinfo = anon_eventfd_attach_xinfo,
+       .ipc_class = &anon_eventfd_ipc_class,
 };
 
 /*
@@ -370,4 +466,6 @@ const struct file_class unkn_class = {
        .initialize_content = unkn_init_content,
        .free_content = unkn_content_free,
        .handle_fdinfo = unkn_handle_fdinfo,
+       .attach_xinfo = unkn_attach_xinfo,
+       .get_ipc_class = unkn_get_ipc_class,
 };
index d389b2876a327ca15b9529cf39afee184b84cc15..cfdaeea7bee0f57d7c9faa7f369849e898601e01 100644 (file)
@@ -146,19 +146,22 @@ Device type (`blk`, `char`, or `nodev`).
 
 ENDPOINT <``string``>::
 IPC endpoints information communicated with the fd.
++
+*lsfd* collects endpoints within the processes that
+*lsfd* scans; *lsfd* may miss some endpoints
+if you limits the processes with *-p* option.
++
 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.
+eventfd type:::
+_PID_,_COMMAND_,_ASSOC_
 
 EVENTFD.ID <``number``>::
 Eventfd ID.