]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsfd: read /proc/partitions
authorMasatake YAMATO <yamato@redhat.com>
Fri, 7 May 2021 18:25:30 +0000 (03:25 +0900)
committerKarel Zak <kzak@redhat.com>
Wed, 6 Oct 2021 09:01:53 +0000 (11:01 +0200)
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
misc-utils/lsfd-bdev.c
misc-utils/lsfd.h

index e40c0c739cfe8918d014ef4075be17a3bd5d1ddd..56fa6dbfb6f9c498e56c70a20034fa0c535fa3eb 100644 (file)
 
 #include "lsfd.h"
 
+static struct list_head partitions;
+
+struct partition {
+       struct list_head partitions;
+       dev_t dev;
+       char *name;
+};
+
 static bool bdev_fill_column(struct proc *proc __attribute__((__unused__)),
                             struct file *file __attribute__((__unused__)),
                             struct libscols_line *ln,
@@ -60,9 +68,72 @@ struct file *make_bdev(const struct file_class *class,
                         sb, name, fd);
 }
 
+static struct partition *make_partition(dev_t dev, const char *name)
+{
+       struct partition *partition = xcalloc(1, sizeof(*partition));
+
+       INIT_LIST_HEAD(&partition->partitions);
+
+       partition->dev = dev;
+       partition->name = xstrdup(name);
+
+       return partition;
+}
+
+static void free_partition(struct partition *partition)
+{
+       free(partition->name);
+       free(partition);
+}
+
+static void read_partitions(struct list_head *partitions_list, FILE *part_fp)
+{
+       unsigned int major, minor;
+       char line[256];
+       char name[sizeof(line)];
+
+       while (fgets(line, sizeof(line), part_fp)) {
+               struct partition *partition;
+
+               if (sscanf(line, "%u %u %*u %s", &major, &minor, name) != 3)
+                       continue;
+               partition = make_partition(makedev(major, minor), name);
+               list_add_tail(&partition->partitions, partitions_list);
+       }
+}
+
+static void bdev_class_initialize(void)
+{
+       INIT_LIST_HEAD(&partitions);
+
+       FILE *part_fp = fopen("/proc/partitions", "r");
+       if (part_fp) {
+               read_partitions(&partitions, part_fp);
+               fclose(part_fp);
+       }
+}
+
+static void bdev_class_finalize(void)
+{
+       list_free(&partitions, struct partition,  partitions, free_partition);
+}
+
+const char *get_partition(dev_t dev)
+{
+       struct list_head *p;
+       list_for_each(p, &partitions) {
+               struct partition *partition = list_entry(p, struct partition, partitions);
+               if (partition->dev == dev)
+                       return partition->name;
+       }
+       return NULL;
+}
+
 const struct file_class bdev_class = {
        .super = &file_class,
        .size = sizeof(struct file),
+       .initialize_class = bdev_class_initialize,
+       .finalize_class = bdev_class_finalize,
        .fill_column = bdev_fill_column,
        .free_content = NULL,
 };
index c800e38f5938cd76c522ad7ca0ed352bf0507b25..b07bd4b9e49098b25d4057ff1d76d46ef18d384b 100644 (file)
@@ -158,4 +158,6 @@ void free_name_manager(struct name_manager *nm);
 const char *get_name(struct name_manager *nm, unsigned long id);
 unsigned long add_name(struct name_manager *nm, const char *name);
 
+const char *get_partition(dev_t dev);
+
 #endif /* UTIL_LINUX_LSFD_H */