diff options
author | Karel Zak | 2018-12-07 12:29:50 +0100 |
---|---|---|
committer | Karel Zak | 2018-12-07 12:57:49 +0100 |
commit | 0bd05f5ee4876ffd13c98acd56c2bff9971f28f1 (patch) | |
tree | f0635d4af03006fa5cf90c03ee4ed7a32dfd89d9 /misc-utils/lsblk.c | |
parent | libsmartcols: add grouping API docs (diff) | |
download | kernel-qcow2-util-linux-0bd05f5ee4876ffd13c98acd56c2bff9971f28f1.tar.gz kernel-qcow2-util-linux-0bd05f5ee4876ffd13c98acd56c2bff9971f28f1.tar.xz kernel-qcow2-util-linux-0bd05f5ee4876ffd13c98acd56c2bff9971f28f1.zip |
lsblk: add --merge
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'misc-utils/lsblk.c')
-rw-r--r-- | misc-utils/lsblk.c | 71 |
1 files changed, 52 insertions, 19 deletions
diff --git a/misc-utils/lsblk.c b/misc-utils/lsblk.c index 95c3cdc4d..7ee6dff90 100644 --- a/misc-utils/lsblk.c +++ b/misc-utils/lsblk.c @@ -141,7 +141,6 @@ struct colinfo { double whint; /* width hint (N < 1 is in percent of termwidth) */ int flags; /* SCOLS_FL_* */ const char *help; - int type; /* COLTYPE_* */ }; @@ -217,7 +216,6 @@ struct lsblk *lsblk; /* global handler */ static int columns[ARRAY_SIZE(infos) * 2]; static size_t ncolumns; - static inline void add_column(int id) { if (ncolumns >= ARRAY_SIZE(columns)) @@ -405,7 +403,7 @@ static char *get_type(struct lsblk_device *dev) { char *res = NULL, *p; - if (cxt->partition) + if (device_is_partition(dev)) return xstrdup("part"); if (is_dm(dev->name)) { @@ -701,7 +699,6 @@ static int is_removable_device(struct lsblk_device *dev, struct lsblk_device *pa /* parent is something else, use sysfs parent */ ul_path_scanf(pc, "removable", "%d", &dev->removable); } - done: if (dev->removable == -1) dev->removable = 0; @@ -718,7 +715,6 @@ static uint64_t device_get_discard_granularity(struct lsblk_device *dev) return dev->discard_granularity; } - /* * Generates data (string) for column specified by column ID for specified device. If sortdata * is not NULL then returns number usable to sort the column if the data are available for the @@ -1032,13 +1028,42 @@ static void device_to_scols( struct libscols_line *ln; struct lsblk_iter itr; struct lsblk_device *child = NULL; + int link_group = 0; ON_DBG(DEV, if (ul_path_isopen_dirfd(dev->sysfs)) ul_debugobj(dev, "%s ---> is open!", dev->name)); - ln = scols_table_new_line(tab, parent_line); + /* Do not print device more than one in --list mode */ + if (!(lsblk->flags & LSBLK_TREE) && dev->is_printed) + return; + + if (lsblk->merge && list_count_entries(&dev->parents) > 1) { + if (!lsblk_device_is_last_parent(dev, parent)) + return; + link_group = 1; + } + + ln = scols_table_new_line(tab, link_group ? NULL : parent_line); if (!ln) err(EXIT_FAILURE, _("failed to allocate output line")); + dev->is_printed = 1; + + if (link_group) { + struct lsblk_device *p; + struct libscols_line *gr = parent_line; + + /* Merge all my parents to the one group */ + lsblk_reset_iter(&itr, LSBLK_ITER_FORWARD); + while (lsblk_device_next_parent(dev, &itr, &p) == 0) { + if (!p->scols_line) + continue; + scols_table_group_lines(tab, gr, p->scols_line, 0); + } + + /* Link the group -- this makes group->child connection */ + scols_line_link_group(ln, gr, 0); + } + /* read column specific data and set it to smartcols table line */ for (i = 0; i < ncolumns; i++) { char *data; @@ -1057,13 +1082,15 @@ static void device_to_scols( err(EXIT_FAILURE, _("failed to add output data")); } + dev->scols_line = ln; + if (dev->npartitions == 0) /* For partitions we often read from parental whole-disk sysfs, * otherwise we can close */ ul_path_close_dirfd(dev->sysfs); - lsblk_reset_iter(&itr, LSBLK_ITER_FORWARD); + lsblk_reset_iter(&itr, LSBLK_ITER_FORWARD); while (lsblk_device_next_child(dev, &itr, &child) == 0) device_to_scols(child, dev, tab, ln); @@ -1547,6 +1574,7 @@ static int process_all_devices(struct lsblk_devtree *tr) DBG(DEV, ul_debug(" %s: ignore (in-middle)", d->d_name)); goto next; } + lsblk_devtree_add_root(tr, dev); process_dependencies(tr, dev, 1); next: @@ -1690,29 +1718,30 @@ static void __attribute__((__noreturn__)) usage(void) fputs(_("List information about block devices.\n"), out); fputs(USAGE_OPTIONS, out); + fputs(_(" -D, --discard print discard capabilities\n"), out); + fputs(_(" -E, --dedup <column> de-duplicate output by <column>\n"), out); + fputs(_(" -I, --include <list> show only devices with specified major numbers\n"), out); + fputs(_(" -J, --json use JSON output format\n"), out); + fputs(_(" -O, --output-all output all columns\n"), out); + fputs(_(" -P, --pairs use key=\"value\" output format\n"), out); + fputs(_(" -S, --scsi output info about SCSI devices\n"), out); + fputs(_(" -T, --tree use tree format output\n"), out); fputs(_(" -a, --all print all devices\n"), out); fputs(_(" -b, --bytes print SIZE in bytes rather than in human readable format\n"), out); fputs(_(" -d, --nodeps don't print slaves or holders\n"), out); - fputs(_(" -D, --discard print discard capabilities\n"), out); - fputs(_(" -z, --zoned print zone model\n"), out); fputs(_(" -e, --exclude <list> exclude devices by major number (default: RAM disks)\n"), out); fputs(_(" -f, --fs output info about filesystems\n"), out); fputs(_(" -i, --ascii use ascii characters only\n"), out); - fputs(_(" -I, --include <list> show only devices with specified major numbers\n"), out); - fputs(_(" -J, --json use JSON output format\n"), out); fputs(_(" -l, --list use list format output\n"), out); - fputs(_(" -T, --tree use tree format output\n"), out); - fputs(_(" -M, --dedup <column> de-duplicate output by <column>\n"), out); + fputs(_(" -M, --merge group parents of sub-trees (usable for RAIDs, Multi-path)\n"), out); fputs(_(" -m, --perms output info about permissions\n"), out); fputs(_(" -n, --noheadings don't print headings\n"), out); fputs(_(" -o, --output <list> output columns\n"), out); - fputs(_(" -O, --output-all output all columns\n"), out); fputs(_(" -p, --paths print complete device path\n"), out); - fputs(_(" -P, --pairs use key=\"value\" output format\n"), out); fputs(_(" -r, --raw use raw output format\n"), out); fputs(_(" -s, --inverse inverse dependencies\n"), out); - fputs(_(" -S, --scsi output info about SCSI devices\n"), out); fputs(_(" -t, --topology output info about topology\n"), out); + fputs(_(" -z, --zoned print zone model\n"), out); fputs(_(" -x, --sort <column> sort output by <column>\n"), out); fputs(_(" --sysroot <dir> use specified directory as system root\n"), out); fputs(USAGE_SEPARATOR, out); @@ -1757,12 +1786,13 @@ int main(int argc, char *argv[]) { "bytes", no_argument, NULL, 'b' }, { "nodeps", no_argument, NULL, 'd' }, { "discard", no_argument, NULL, 'D' }, - { "dedup", required_argument, NULL, 'M' }, + { "dedup", required_argument, NULL, 'E' }, { "zoned", no_argument, NULL, 'z' }, { "help", no_argument, NULL, 'h' }, { "json", no_argument, NULL, 'J' }, { "output", required_argument, NULL, 'o' }, { "output-all", no_argument, NULL, 'O' }, + { "merge", no_argument, NULL, 'M' }, { "perms", no_argument, NULL, 'm' }, { "noheadings", no_argument, NULL, 'n' }, { "list", no_argument, NULL, 'l' }, @@ -1806,7 +1836,7 @@ int main(int argc, char *argv[]) lsblk_init_debug(); while((c = getopt_long(argc, argv, - "abdDze:fhJlnmM:o:OpPiI:rstVSTx:", longopts, NULL)) != -1) { + "abdDzE:e:fhJlnMmo:OpPiI:rstVSTx:", longopts, NULL)) != -1) { err_exclusive_options(c, longopts, excl, excl_st); @@ -1843,6 +1873,9 @@ int main(int argc, char *argv[]) case 'l': lsblk->flags &= ~LSBLK_TREE; /* disable the default */ break; + case 'M': + lsblk->merge = 1; + break; case 'n': lsblk->flags |= LSBLK_NOHEADINGS; break; @@ -1923,7 +1956,7 @@ int main(int argc, char *argv[]) case 'V': printf(UTIL_LINUX_VERSION); return EXIT_SUCCESS; - case 'M': + case 'E': lsblk->dedup_id = column_name_to_id(optarg, strlen(optarg)); if (lsblk->dedup_id >= 0) break; |