From: Karel Zak Date: Mon, 24 Jun 2024 10:09:38 +0000 (+0200) Subject: lsblk: add --properties-by option X-Git-Tag: v2.42-start~286^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6186f3f176da4b122b127ca8f9448429b8712366;p=thirdparty%2Futil-linux.git lsblk: add --properties-by option 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 --- diff --git a/misc-utils/lsblk-properties.c b/misc-utils/lsblk-properties.c index dc6f2896c..66a6df6ae 100644 --- a/misc-utils/lsblk-properties.c +++ b/misc-utils/lsblk-properties.c @@ -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) diff --git a/misc-utils/lsblk.8.adoc b/misc-utils/lsblk.8.adoc index 577ff71cd..308c71e3f 100644 --- a/misc-utils/lsblk.8.adoc +++ b/misc-utils/lsblk.8.adoc @@ -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:: diff --git a/misc-utils/lsblk.c b/misc-utils/lsblk.c index 44279605c..41e9470ea 100644 --- a/misc-utils/lsblk.c +++ b/misc-utils/lsblk.c @@ -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; diff --git a/misc-utils/lsblk.h b/misc-utils/lsblk.h index a2d9a009e..044fcab72 100644 --- a/misc-utils/lsblk.h +++ b/misc-utils/lsblk.h @@ -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);