]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsfd: add basic code for tracking IPC endpoints
authorMasatake YAMATO <yamato@redhat.com>
Mon, 7 Mar 2022 09:20:10 +0000 (18:20 +0900)
committerMasatake YAMATO <yamato@redhat.com>
Mon, 4 Apr 2022 12:05:58 +0000 (21:05 +0900)
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
misc-utils/lsfd.c
misc-utils/lsfd.h

index 414d04801d8472e85e6d959752ed5a37e1eee711..6614a889d476cf80fd16b8a3459bcb12b9cb92e2 100644 (file)
@@ -93,6 +93,17 @@ struct devdrv {
 static struct list_head chrdrvs;
 static struct list_head blkdrvs;
 
+/*
+ * IPC table
+ */
+
+#define IPC_TABLE_SIZE 997
+struct ipc_table {
+       struct list_head tables[IPC_TABLE_SIZE];
+};
+
+static struct ipc_table ipc_table;
+
 /*
  * Column related stuffs
  */
@@ -812,6 +823,54 @@ static void add_nodevs(FILE *mnt)
        }
 }
 
+static void initialize_ipc_table(void)
+{
+       for (int i = 0; i < IPC_TABLE_SIZE; i++)
+               INIT_LIST_HEAD(ipc_table.tables + i);
+}
+
+static void free_ipc(struct ipc *ipc)
+{
+       if (ipc->class->free)
+               ipc->class->free(ipc);
+}
+
+static void finalize_ipc_table(void)
+{
+       for (int i = 0; i < IPC_TABLE_SIZE; i++)
+               list_free(ipc_table.tables, struct ipc, ipcs, free_ipc);
+}
+
+struct ipc *get_ipc(struct file *file)
+{
+       int slot;
+       struct list_head *e;
+       struct ipc_class *ipc_class;
+
+       if (!file->class->get_ipc_class)
+               return NULL;
+
+       ipc_class = file->class->get_ipc_class(file);
+       if (!ipc_class)
+               return NULL;
+
+       slot = ipc_class->get_hash(file) % IPC_TABLE_SIZE;
+       list_for_each (e, &ipc_table.tables[slot]) {
+               struct ipc *ipc = list_entry(e, struct ipc, ipcs);
+               if (ipc->class != ipc_class)
+                       continue;
+               if (ipc_class->is_suitable_ipc(ipc, file))
+                       return ipc;
+       }
+       return NULL;
+}
+
+void add_ipc(struct ipc *ipc, unsigned int hash)
+{
+       int slot = hash % IPC_TABLE_SIZE;
+       list_add(&ipc->ipcs, &ipc_table.tables[slot]);
+}
+
 static void fill_column(struct proc *proc,
                        struct file *file,
                        struct libscols_line *ln,
@@ -1687,6 +1746,7 @@ int main(int argc, char *argv[])
        initialize_nodevs();
        initialize_classes();
        initialize_devdrvs();
+       initialize_ipc_table();
 
        collect_processes(&ctl, pids, n_pids);
        free(pids);
@@ -1703,6 +1763,7 @@ int main(int argc, char *argv[])
        /* cleanup */
        delete(&ctl.procs, &ctl);
 
+       finalize_ipc_table();
        finalize_devdrvs();
        finalize_classes();
        finalize_nodevs();
index bcee186d658954d3531705d11eb120ac45b01be3..ec8f40cfb5b455ea18a54c8d24e2ae9e03868d08 100644 (file)
@@ -137,10 +137,34 @@ struct file_class {
        int  (*handle_fdinfo)(struct file *file, const char *key, const char* value);
        void (*initialize_content)(struct file *file);
        void (*free_content)(struct file *file);
+       struct ipc_class *(*get_ipc_class)(struct file *file);
 };
 
 extern const struct file_class file_class, cdev_class, bdev_class, sock_class, unkn_class, fifo_class;
 
+/*
+ * IPC
+ */
+struct ipc {
+       const struct ipc_class *class;
+       struct list_head endpoints;
+       struct list_head ipcs;
+};
+
+struct ipc_endpoint {
+       struct ipc *ipc;
+       struct list_head endpoints;
+};
+
+struct ipc_class {
+       unsigned int (*get_hash)(struct file *file);
+       bool (*is_suitable_ipc)(struct ipc *ipc, struct file *file);
+       void (*free)(struct ipc *ipc);
+};
+
+struct ipc *get_ipc(struct file *file);
+void add_ipc(struct ipc *ipc, unsigned int hash);
+
 /*
  * Name managing
  */