summaryrefslogtreecommitdiffstats
path: root/misc-utils
diff options
context:
space:
mode:
authorKarel Zak2018-10-18 12:39:41 +0200
committerKarel Zak2018-12-07 12:32:58 +0100
commitd81e32bde97e193ddd77ac9b4a85104b69730bca (patch)
treeb689fa1b3b0b8f5f8e515d7b46c20e743fb1d445 /misc-utils
parentlsblk: apply --nodeps to partitions too (diff)
downloadkernel-qcow2-util-linux-d81e32bde97e193ddd77ac9b4a85104b69730bca.tar.gz
kernel-qcow2-util-linux-d81e32bde97e193ddd77ac9b4a85104b69730bca.tar.xz
kernel-qcow2-util-linux-d81e32bde97e193ddd77ac9b4a85104b69730bca.zip
lsblk: make device_get_data() more generic
* independent on smartcols line * keep sort data optional Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'misc-utils')
-rw-r--r--misc-utils/lsblk.c134
-rw-r--r--misc-utils/lsblk.h2
2 files changed, 78 insertions, 58 deletions
diff --git a/misc-utils/lsblk.c b/misc-utils/lsblk.c
index d01ff1b35..5ce388b8b 100644
--- a/misc-utils/lsblk.c
+++ b/misc-utils/lsblk.c
@@ -592,14 +592,20 @@ static void set_sortdata_u64(struct libscols_line *ln, int col, uint64_t x)
scols_cell_set_userdata(ce, data);
}
-static void set_sortdata_u64_from_string(struct libscols_line *ln, int col, const char *str)
+/* do not modify *data on any error */
+static void str2u64(const char *str, uint64_t *data)
{
- uint64_t x;
+ uintmax_t num;
+ char *end = NULL;
- if (!str || sscanf(str, "%"SCNu64, &x) != 1)
+ errno = 0;
+ if (str == NULL || *str == '\0')
return;
+ num = strtoumax(str, &end, 10);
- set_sortdata_u64(ln, col, x);
+ if (errno || str == end || (end && *end))
+ return;
+ *data = num;
}
static void unref_sortdata(struct libscols_table *tb)
@@ -714,22 +720,19 @@ static uint64_t device_get_discard_granularity(struct lsblk_device *dev)
/*
- * Generates data (string) for column specified by column ID for specified device
+ * 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
+ * column.
*/
-static void set_scols_data(
- struct lsblk_device *dev,
- struct lsblk_device *parent,
- int col,
- int id,
- struct libscols_line *ln)
+static char *device_get_data(
+ struct lsblk_device *dev, /* device */
+ struct lsblk_device *parent, /* device parent as defined in the tree */
+ int id, /* column ID (COL_*) */
+ uint64_t *sortdata) /* returns sort data as number */
{
struct lsblk_devprop *prop;
- int sort = 0;
char *str = NULL;
- if (lsblk->sort_id == id)
- sort = 1;
-
switch(id) {
case COL_NAME:
str = dev->dm_name ? mk_dm_name(dev->dm_name) : mk_name(dev->name);
@@ -775,8 +778,8 @@ static void set_scols_data(
xasprintf(&str, "%u:%u", dev->maj, dev->min);
else
xasprintf(&str, "%3u:%-3u", dev->maj, dev->min);
- if (sort)
- set_sortdata_u64(ln, col, makedev(dev->maj, dev->min));
+ if (sortdata)
+ *sortdata = makedev(dev->maj, dev->min);
break;
case COL_FSTYPE:
prop = lsblk_device_get_properties(dev);
@@ -839,8 +842,8 @@ static void set_scols_data(
break;
case COL_RA:
ul_path_read_string(dev->sysfs, &str, "queue/read_ahead_kb");
- if (sort)
- set_sortdata_u64_from_string(ln, col, str);
+ if (sortdata)
+ str2u64(str, sortdata);
break;
case COL_RO:
str = xstrdup(is_readonly_device(dev) ? "1" : "0");
@@ -890,8 +893,8 @@ static void set_scols_data(
xasprintf(&str, "%ju", dev->size);
else
str = size_to_human_string(SIZE_SUFFIX_1LETTER, dev->size);
- if (sort)
- set_sortdata_u64(ln, col, dev->size);
+ if (sortdata)
+ *sortdata = dev->size;
break;
case COL_STATE:
if (!dev->partition && !dev->dm_name)
@@ -904,36 +907,36 @@ static void set_scols_data(
break;
case COL_ALIOFF:
ul_path_read_string(dev->sysfs, &str, "alignment_offset");
- if (sort)
- set_sortdata_u64_from_string(ln, col, str);
+ if (sortdata)
+ str2u64(str, sortdata);
break;
case COL_MINIO:
ul_path_read_string(dev->sysfs, &str, "queue/minimum_io_size");
- if (sort)
- set_sortdata_u64_from_string(ln, col, str);
+ if (sortdata)
+ str2u64(str, sortdata);
break;
case COL_OPTIO:
ul_path_read_string(dev->sysfs, &str, "queue/optimal_io_size");
- if (sort)
- set_sortdata_u64_from_string(ln, col, str);
+ if (sortdata)
+ str2u64(str, sortdata);
break;
case COL_PHYSEC:
ul_path_read_string(dev->sysfs, &str, "queue/physical_block_size");
- if (sort)
- set_sortdata_u64_from_string(ln, col, str);
+ if (sortdata)
+ str2u64(str, sortdata);
break;
case COL_LOGSEC:
ul_path_read_string(dev->sysfs, &str, "queue/logical_block_size");
- if (sort)
- set_sortdata_u64_from_string(ln, col, str);
+ if (sortdata)
+ str2u64(str, sortdata);
break;
case COL_SCHED:
str = get_scheduler(dev);
break;
case COL_RQ_SIZE:
ul_path_read_string(dev->sysfs, &str, "queue/nr_requests");
- if (sort)
- set_sortdata_u64_from_string(ln, col, str);
+ if (sortdata)
+ str2u64(str, sortdata);
break;
case COL_TYPE:
str = get_type(dev);
@@ -956,32 +959,32 @@ static void set_scols_data(
ul_path_read_string(dev->sysfs, &str, "discard_alignment");
if (!str)
str = xstrdup("0");
- if (sort)
- set_sortdata_u64_from_string(ln, col, str);
+ if (sortdata)
+ str2u64(str, sortdata);
break;
case COL_DGRAN:
if (lsblk->bytes) {
ul_path_read_string(dev->sysfs, &str, "queue/discard_granularity");
- if (sort)
- set_sortdata_u64_from_string(ln, col, str);
+ if (sortdata)
+ str2u64(str, sortdata);
} else {
uint64_t x = device_get_discard_granularity(dev);
str = size_to_human_string(SIZE_SUFFIX_1LETTER, x);
- if (sort)
- set_sortdata_u64(ln, col, x);
+ if (sortdata)
+ *sortdata = x;
}
break;
case COL_DMAX:
if (lsblk->bytes) {
ul_path_read_string(dev->sysfs, &str, "queue/discard_max_bytes");
- if (sort)
- set_sortdata_u64_from_string(ln, col, str);
+ if (sortdata)
+ str2u64(str, sortdata);
} else {
uint64_t x;
if (ul_path_read_u64(dev->sysfs, &x, "queue/discard_max_bytes") == 0) {
str = size_to_human_string(SIZE_SUFFIX_1LETTER, x);
- if (sort)
- set_sortdata_u64(ln, col, x);
+ if (sortdata)
+ *sortdata = x;
}
}
break;
@@ -994,15 +997,15 @@ static void set_scols_data(
case COL_WSAME:
if (lsblk->bytes) {
ul_path_read_string(dev->sysfs, &str, "queue/write_same_max_bytes");
- if (sort)
- set_sortdata_u64_from_string(ln, col, str);
+ if (sortdata)
+ str2u64(str, sortdata);
} else {
uint64_t x;
if (ul_path_read_u64(dev->sysfs, &x, "queue/write_same_max_bytes") == 0) {
str = size_to_human_string(SIZE_SUFFIX_1LETTER, x);
- if (sort)
- set_sortdata_u64(ln, col, x);
+ if (sortdata)
+ *sortdata = x;
}
}
if (!str)
@@ -1013,27 +1016,46 @@ static void set_scols_data(
break;
};
- if (str && scols_line_refer_data(ln, col, str))
- err(EXIT_FAILURE, _("failed to add output data"));
+ return str;
}
/*
* Adds data for all wanted columns about the device to the smartcols table
*/
-static void device_to_scols(struct lsblk_device *dev, struct lsblk_device *parent, struct libscols_table *tab)
+static void device_to_scols(
+ struct lsblk_device *dev,
+ struct lsblk_device *parent,
+ struct libscols_table *tab,
+ struct libscols_line *parent_line)
{
size_t i;
+ struct libscols_line *ln;
struct lsblk_iter itr;
struct lsblk_device *child = NULL;
ON_DBG(DEV, if (ul_path_isopen_dirfd(dev->sysfs)) ul_debugobj(dev, "%s ---> is open!", dev->name));
- dev->scols_line = scols_table_new_line(tab, parent ? parent->scols_line : NULL);
- if (!dev->scols_line)
+ ln = scols_table_new_line(tab, parent_line);
+ if (!ln)
err(EXIT_FAILURE, _("failed to allocate output line"));
- for (i = 0; i < ncolumns; i++)
- set_scols_data(dev, parent, i, get_column_id(i), dev->scols_line);
+ /* read column specific data and set it to smartcols table line */
+ for (i = 0; i < ncolumns; i++) {
+ char *data;
+ int id = get_column_id(i);
+
+ if (lsblk->sort_id != id)
+ data = device_get_data(dev, parent, id, NULL);
+ else {
+ uint64_t sortdata = (uint64_t) -1;
+
+ data = device_get_data(dev, parent, id, &sortdata);
+ if (data && sortdata != (uint64_t) -1)
+ set_sortdata_u64(ln, i, sortdata);
+ }
+ if (data && scols_line_refer_data(ln, i, data))
+ err(EXIT_FAILURE, _("failed to add output data"));
+ }
if (dev->npartitions == 0)
/* For partitions we often read from parental whole-disk sysfs,
@@ -1043,7 +1065,7 @@ static void device_to_scols(struct lsblk_device *dev, struct lsblk_device *paren
lsblk_reset_iter(&itr, LSBLK_ITER_FORWARD);
while (lsblk_device_next_child(dev, &itr, &child) == 0)
- device_to_scols(child, dev, tab);
+ device_to_scols(child, dev, tab, ln);
/* Let's be careful with number of open files */
ul_path_close_dirfd(dev->sysfs);
@@ -1060,7 +1082,7 @@ static void devtree_to_scols(struct lsblk_devtree *tr, struct libscols_table *ta
lsblk_reset_iter(&itr, LSBLK_ITER_FORWARD);
while (lsblk_devtree_next_root(tr, &itr, &dev) == 0)
- device_to_scols(dev, NULL, tab);
+ device_to_scols(dev, NULL, tab, NULL);
}
/*
diff --git a/misc-utils/lsblk.h b/misc-utils/lsblk.h
index 6cba502cf..9c311c4c2 100644
--- a/misc-utils/lsblk.h
+++ b/misc-utils/lsblk.h
@@ -85,8 +85,6 @@ struct lsblk_device {
struct lsblk_devtree *tree;
struct lsblk_devprop *properties;
- struct libscols_line *scols_line;
-
struct stat st;
char *name; /* kernel name in /sys/block */