]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsblk: add --properties-by option
authorKarel Zak <kzak@redhat.com>
Mon, 24 Jun 2024 10:09:38 +0000 (12:09 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 24 Jun 2024 10:53:51 +0000 (12:53 +0200)
This new option allows for controlling the method(s) used by lsblk to
gather file system and partition data about devices.

Fixes: https://github.com/util-linux/util-linux/issues/2047
Signed-off-by: Karel Zak <kzak@redhat.com>
misc-utils/lsblk-properties.c
misc-utils/lsblk.8.adoc
misc-utils/lsblk.c
misc-utils/lsblk.h

index dc6f2896c968c378bb7cd18cced4cb10cedb099a..66a6df6ae3a25aec097ce4da089aa55939991fad 100644 (file)
@@ -69,6 +69,8 @@ static struct lsblk_devprop *get_properties_by_udev(struct lsblk_device *ld)
        if (ld->udev_requested)
                return ld->properties;
 
+       DBG(DEV, ul_debugobj(ld, " properties by udev"));
+
        if (!udev)
                udev = udev_new();      /* global handler */
        if (!udev)
@@ -214,6 +216,8 @@ static struct lsblk_devprop *get_properties_by_file(struct lsblk_device *ld)
        if (ld->file_requested)
                return ld->properties;
 
+       DBG(DEV, ul_debugobj(ld, " properties by file"));
+
        if (ld->properties || ld->filename) {
                lsblk_device_free_properties(ld->properties);
                ld->properties = NULL;
@@ -291,6 +295,8 @@ static struct lsblk_devprop *get_properties_by_blkid(struct lsblk_device *dev)
        if (getuid() != 0)
                goto done;;                             /* no permissions to read from the device */
 
+       DBG(DEV, ul_debugobj(dev, " properties by blkid"));
+
        pr = blkid_new_probe_from_filename(dev->filename);
        if (!pr)
                goto done;
@@ -344,18 +350,64 @@ done:
        return dev->properties;
 }
 
+static int name2method(const char *name, size_t namesz)
+{
+       if (namesz == 4 && strncasecmp(name, "none", namesz) == 0)
+               return LSBLK_METHOD_NONE;
+       if (namesz == 4 && strncasecmp(name, "udev", namesz) == 0)
+               return LSBLK_METHOD_UDEV;
+       if (namesz == 5 && strncasecmp(name, "blkid", namesz) == 0)
+               return LSBLK_METHOD_BLKID;
+       if (namesz == 4 && strncasecmp(name, "file", namesz) == 0)
+               return LSBLK_METHOD_FILE;
+
+       warnx(_("unknown properties probing method: %s"), name);
+       return -1;
+}
+
+int lsblk_set_properties_method(const char *opts)
+{
+       size_t i;
+
+       for (i = 0; i < __LSBLK_NMETHODS; i++)
+               lsblk->properties_by[i] = LSBLK_METHOD_NONE;
+
+       if (string_to_idarray(opts, lsblk->properties_by,
+                       __LSBLK_NMETHODS, name2method) < 0)
+               return -1;
+
+       return 0;
+}
+
 struct lsblk_devprop *lsblk_device_get_properties(struct lsblk_device *dev)
 {
-       struct lsblk_devprop *p = NULL;
+       size_t i;
 
        DBG(DEV, ul_debugobj(dev, "%s: properties requested", dev->filename));
-       if (lsblk->sysroot)
-               return get_properties_by_file(dev);
 
-       p = get_properties_by_udev(dev);
-       if (!p)
-               p = get_properties_by_blkid(dev);
-       return p;
+       for (i = 0; i < __LSBLK_NMETHODS; i++) {
+               struct lsblk_devprop *p = NULL;
+
+               switch (lsblk->properties_by[i]) {
+               case LSBLK_METHOD_NONE:
+                       return NULL;
+               case LSBLK_METHOD_UDEV:
+                       p = get_properties_by_udev(dev);
+                       break;
+               case LSBLK_METHOD_BLKID:
+                       p = get_properties_by_blkid(dev);
+                       break;
+               case LSBLK_METHOD_FILE:
+                       if (lsblk->sysroot)
+                               return get_properties_by_file(dev);
+                       break;
+               }
+
+               if (p)
+                       return p;
+       }
+
+       return NULL;
 }
 
 void lsblk_properties_deinit(void)
index 577ff71cd5b712a197b7d79ca4964f824bd6f7c2..308c71e3f628d94922902cc1d2ab8dde99b17259 100644 (file)
@@ -180,6 +180,20 @@ Print the zone related information for each device.
 *--sysroot* _directory_::
 Gather data for a Linux instance other than the instance from which the *lsblk* command is issued. The specified directory is the system root of the Linux instance to be inspected. The real device nodes in the target directory can be replaced by text files with udev attributes.
 
+*--properties-by* _list_::
+This option specifies the methods used by *lsblk* to gather information about
+filesystems and partition tables. The list is a comma-separated list of method
+names. The default setting is "file,udev,blkid". The supported methods are:
++
+*udev*;;
+Reads data from udev DB. If unsuccessful, it continues to the next probing method.
+*blkid*;;
+Reads data directly from the device using libblkid. If unsuccessful, it continues to the next probing method.
+*file*;;
+Reads data from a file. This method is only used if the --sysroot option is specified. This method always stops probing if used.
+*none*;;
+Does not probe. This method always stops probing.
+
 == EXIT STATUS
 
 0::
index 44279605c3dd37c6944ea6b9a2046fded1886368..41e9470ea75a32ed03adbd186d2057c76d48242f 100644 (file)
@@ -2389,7 +2389,9 @@ int main(int argc, char *argv[])
                .sort_id = -1,
                .dedup_id = -1,
                .flags = LSBLK_TREE,
-               .tree_id = COL_NAME
+               .tree_id = COL_NAME,
+               .properties_by = { LSBLK_METHOD_FILE, LSBLK_METHOD_UDEV,
+                                    LSBLK_METHOD_BLKID, LSBLK_METHOD_NONE }
        };
        struct lsblk_devtree *tr = NULL;
        int c, status = EXIT_FAILURE, collist = 0;
@@ -2403,6 +2405,7 @@ int main(int argc, char *argv[])
                OPT_COUNTER_FILTER,
                OPT_COUNTER,
                OPT_HIGHLIGHT,
+               OPT_PROPERTIES_BY
        };
 
        static const struct option longopts[] = {
@@ -2443,6 +2446,7 @@ int main(int argc, char *argv[])
                { "width",      required_argument, NULL, 'w' },
                { "ct-filter",  required_argument, NULL, OPT_COUNTER_FILTER },
                { "ct",         required_argument, NULL, OPT_COUNTER },
+               { "properties-by", required_argument, NULL, OPT_PROPERTIES_BY },
                { "list-columns", no_argument,     NULL, 'H' },
                { NULL, 0, NULL, 0 },
        };
@@ -2657,7 +2661,10 @@ int main(int argc, char *argv[])
                case OPT_HIGHLIGHT:
                        lsblk->hlighter = new_filter(optarg);
                        break;
-
+               case OPT_PROPERTIES_BY:
+                       if (lsblk_set_properties_method(optarg) < 0)
+                               errtryhelp(EXIT_FAILURE);
+                       break;
                case 'H':
                        collist = 1;
                        break;
index a2d9a009eac8d435263a1b3d6cdbb61601f1bc54..044fcab72e6db92ae79bb335f7558baad639356c 100644 (file)
@@ -32,6 +32,16 @@ UL_DEBUG_DECLARE_MASK(lsblk);
 #define UL_DEBUG_CURRENT_MASK  UL_DEBUG_MASK(lsblk)
 #include "debugobj.h"
 
+/* --properties-by items */
+enum lsblk_devprop_method {
+       LSBLK_METHOD_NONE = 0,
+       LSBLK_METHOD_UDEV,
+       LSBLK_METHOD_BLKID,
+       LSBLK_METHOD_FILE,
+
+       __LSBLK_NMETHODS        /* keep last */
+};
+
 struct lsblk {
        struct libscols_table *table;   /* output table */
        struct libscols_column *sort_col;/* sort output by this column */
@@ -51,6 +61,8 @@ struct lsblk {
        const char *sysroot;
        int flags;                      /* LSBLK_* */
 
+       int properties_by[__LSBLK_NMETHODS];
+
        unsigned int all_devices:1;     /* print all devices, including empty */
        unsigned int bytes:1;           /* print SIZE in bytes */
        unsigned int inverse:1;         /* print inverse dependencies */
@@ -94,6 +106,8 @@ struct lsblk_devprop {
        char *mode;             /* access mode in ls(1)-like notation */
 };
 
+
+
 /* Device dependence
  *
  * Note that the same device may be slave/holder for more another devices. It
@@ -233,6 +247,8 @@ extern void lsblk_properties_deinit(void);
 
 extern const char *lsblk_parttype_code_to_string(const char *code, const char *pttype);
 
+extern int lsblk_set_properties_method(const char *opts);
+
 /* lsblk-devtree.c */
 void lsblk_reset_iter(struct lsblk_iter *itr, int direction);
 struct lsblk_device *lsblk_new_device(void);