]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
findmnt: allow SOURCES field even without '--fstab'
authorGoffredo Baroncelli <kreijack@inwind.it>
Sat, 22 Jan 2022 14:08:08 +0000 (15:08 +0100)
committerKarel Zak <kzak@redhat.com>
Fri, 28 Jan 2022 10:08:36 +0000 (11:08 +0100)
The SOURCES output field was fully enabled only when "--fstab" is
enabled too. This patch enables SOURCES even without "--fstab".

$ ./findmnt -o TARGET,SOURCES
TARGET                                        SOURCES
/                                             /dev/sdg3
├─/mnt/btrfs-raid1                            /dev/sdb2
│                                             /dev/sde2
│                                             /dev/sda2
└─/tmp/t                                      /dev/mapper/pool-v2
                                              /dev/mapper/pool-v1

If '--fstab' is passed, and in fstab the filesystem is referred by UUID,
only one UUID for filesystem is showed:

$ ./findmnt -o TARGET,SOURCES --fstab
TARGET                         SOURCES
/                              UUID=d7a06504-cc14-435d-a5df-674da09c2894
/mnt/btrfs-raid1               UUID=b39b0b27-ff80-4cb4-bf48-0be939ff0788

However if you pass '-e', all the devices are showed

$ ./findmnt -o TARGET,SOURCES --fstab -e
TARGET                         SOURCES
/                              /dev/sdg3
/mnt/btrfs-raid1               /dev/sdb2
                               /dev/sde2
                               /dev/sda2

[kzak@redhat.com: - support all tags (not only LABEL or UUID),
                  - fix small memory leak,
                  - simplify code]

Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it>
Signed-off-by: Karel Zak <kzak@redhat.com>
misc-utils/findmnt.c

index f2313e3bf09b6dfad844ffba0f3335a43a252f66..e3095d974e4731c6747c94c1fe34b0b7860c823f 100644 (file)
@@ -119,7 +119,7 @@ static struct colinfo infos[] = {
        [COL_PASSNO]       = { "PASSNO",          1, SCOLS_FL_RIGHT, N_("pass number on parallel fsck(8) [fstab only]") },
        [COL_PROPAGATION]  = { "PROPAGATION",  0.10, 0, N_("VFS propagation flags") },
        [COL_SIZE]         = { "SIZE",            5, SCOLS_FL_RIGHT, N_("filesystem size") },
-       [COL_SOURCES]      = { "SOURCES",      0.25, SCOLS_FL_WRAP, N_("all possible source devices [fstab only]") },
+       [COL_SOURCES]      = { "SOURCES",      0.25, SCOLS_FL_WRAP, N_("all possible source devices") },
        [COL_SOURCE]       = { "SOURCE",       0.25, SCOLS_FL_NOEXTREMES, N_("source device") },
        [COL_TARGET]       = { "TARGET",       0.30, SCOLS_FL_TREE| SCOLS_FL_NOEXTREMES, N_("mountpoint") },
        [COL_TID]          = { "TID",             4, SCOLS_FL_RIGHT, N_("task ID") },
@@ -158,6 +158,7 @@ unsigned int flags;
 int parse_nerrors;
 struct libmnt_cache *cache;
 
+static blkid_cache blk_cache;
 
 #ifdef HAVE_LIBUDEV
 static struct udev *udev;
@@ -508,45 +509,90 @@ static char *get_vfs_attr(struct libmnt_fs *fs, int sizetype)
        return sizestr;
 }
 
+/* reads sources from libmount/libblkid
+ */
+static char *get_data_col_sources(struct libmnt_fs *fs, int evaluate)
+{
+       const char *tag = NULL, *p = NULL;
+       int i = 0;
+       const char *device = NULL;
+       char *val = NULL;
+       blkid_dev_iterate iter;
+       blkid_dev dev;
+       struct ul_buffer buf = UL_INIT_BUFFER;
+
+       /* get TAG from libmount if avalable (e.g. fstab) */
+       if (mnt_fs_get_tag(fs, &tag, &p) == 0) {
+
+               /* if device is in the form 'UUID=..' or 'LABEL=..' and evaluate==0
+                * then it is ok to do not search for multiple devices
+                */
+               if (!evaluate)
+                       goto nothing;
+               val = xstrdup(p);
+       }
+
+       /* or get device name */
+       else if (!(device = mnt_fs_get_srcpath(fs))
+                || strncmp(device, "/dev/", 5) != 0)
+               goto nothing;
+
+       if (!blk_cache) {
+               if (blkid_get_cache(&blk_cache, NULL) != 0)
+                       goto nothing;
+               blkid_probe_all(blk_cache);
+       }
+
+       /* ask libblkid for the UUID */
+       if (!val) {
+               assert(device);
+
+               tag = "UUID";
+               val = blkid_get_tag_value(blk_cache, "UUID", device);   /* returns allocated string */
+               if (!val)
+                       goto nothing;
+       }
+
+       assert(val);
+       assert(tag);
+
+       /* scan all devices for the TAG */
+       iter = blkid_dev_iterate_begin(blk_cache);
+       blkid_dev_set_search(iter, tag, val);
+
+       while (blkid_dev_next(iter, &dev) == 0) {
+               dev = blkid_verify(blk_cache, dev);
+               if (!dev)
+                       continue;
+               if (i != 0)
+                       ul_buffer_append_data(&buf, "\n", 1);
+               ul_buffer_append_string(&buf, blkid_dev_devname(dev));
+               i++;
+       }
+       blkid_dev_iterate_end(iter);
+       free(val);
+
+       return ul_buffer_get_data(&buf, NULL, NULL);
+
+nothing:
+       free(val);
+       return NULL;
+}
+
 /* reads FS data from libmount
  */
 static char *get_data(struct libmnt_fs *fs, int num)
 {
        char *str = NULL;
-       const char *t = NULL, *v = NULL;
        int col_id = get_column_id(num);
 
        switch (col_id) {
        case COL_SOURCES:
                /* print all devices with the same tag (LABEL, UUID) */
-               if ((flags & FL_EVALUATE) &&
-                   mnt_fs_get_tag(fs, &t, &v) == 0) {
-                       blkid_dev_iterate iter;
-                       blkid_dev dev;
-                       blkid_cache cache = NULL;
-                       struct ul_buffer buf = UL_INIT_BUFFER;
-                       int i = 0;
-
-                       if (blkid_get_cache(&cache, NULL) < 0)
-                               break;
-
-                       blkid_probe_all(cache);
-
-                       iter = blkid_dev_iterate_begin(cache);
-                       blkid_dev_set_search(iter, t, v);
-                       while (blkid_dev_next(iter, &dev) == 0) {
-                               dev = blkid_verify(cache, dev);
-                               if (!dev)
-                                       continue;
-                               if (i != 0)
-                                       ul_buffer_append_data(&buf, "\n", 1);
-                               ul_buffer_append_string(&buf, blkid_dev_devname(dev));
-                               i++;
-                       }
-                       blkid_dev_iterate_end(iter);
-                       str = ul_buffer_get_data(&buf, NULL, NULL);
+               str = get_data_col_sources(fs, flags & FL_EVALUATE);
+               if (str)
                        break;
-               }
+
                /* fallthrough */
        case COL_SOURCE:
        {