aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2023-09-27 14:14:44 +0200
committerKarel Zak <kzak@redhat.com>2023-11-20 22:25:46 +0100
commitaf5fa636b3910058242f1aa36868b54d2c821dd4 (patch)
treedc831fc87c542fbf2fa5502abc80e1a3121a9000
parent98c12238b3194cadd6eb0df5704f32903f611cdc (diff)
downloadutil-linux-af5fa636b3910058242f1aa36868b54d2c821dd4.tar.gz
lsblk: define cell data-types, use raw data for SIZEs
Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r--misc-utils/lsblk.c80
-rw-r--r--misc-utils/lsblk.h1
2 files changed, 60 insertions, 21 deletions
diff --git a/misc-utils/lsblk.c b/misc-utils/lsblk.c
index 4552487cbf..cd4142c984 100644
--- a/misc-utils/lsblk.c
+++ b/misc-utils/lsblk.c
@@ -659,16 +659,28 @@ static void unref_rawdata(struct libscols_table *tb)
struct libscols_iter *itr;
struct libscols_line *ln;
- if (!tb || !lsblk->sort_col)
+ if (!tb || !lsblk->rawdata)
return;
+
itr = scols_new_iter(SCOLS_ITER_FORWARD);
if (!itr)
return;
+
while (scols_table_next_line(tb, itr, &ln) == 0) {
- struct libscols_cell *ce = scols_line_get_column_cell(ln,
- lsblk->sort_col);
- void *data = scols_cell_get_userdata(ce);
- free(data);
+ size_t i;
+
+ for (i = 0; i < ncolumns; i++) {
+ struct libscols_column *cl = scols_table_get_column(tb, i);
+ struct libscols_cell *ce;
+ void *data;
+
+ if (cl != lsblk->sort_col && !scols_column_has_datafunc(cl))
+ continue;
+
+ ce = scols_line_get_column_cell(ln, cl);
+ data = scols_cell_get_userdata(ce);
+ free(data);
+ }
}
scols_free_iter(itr);
@@ -1240,19 +1252,19 @@ static void device_fill_scols_cell(struct lsblk_device *dev,
size_t colnum)
{
struct libscols_cell *ce;
+ struct libscols_column *cl = scols_table_get_column(lsblk->table, colnum);
char *data;
size_t datasiz = 0;
int rc, id = get_column_id(colnum);
- if (lsblk->sort_id != id)
- data = device_get_data(dev, parent, id, NULL, &datasiz);
- else {
+ if (lsblk->sort_id == id || scols_column_has_datafunc(cl)) {
uint64_t rawdata = (uint64_t) -1;
data = device_get_data(dev, parent, id, &rawdata, &datasiz);
if (data && rawdata != (uint64_t) -1)
set_rawdata_u64(ln, colnum, rawdata);
- }
+ } else
+ data = device_get_data(dev, parent, id, NULL, &datasiz);
if (!data)
return;
@@ -2043,6 +2055,13 @@ static int cmp_u64_cells(struct libscols_cell *a,
return *adata == *bdata ? 0 : *adata >= *bdata ? 1 : -1;
}
+static void *get_u64_cell(const struct libscols_column *cl __attribute__((__unused__)),
+ struct libscols_cell *ce,
+ void *data __attribute__((__unused__)))
+{
+ return scols_cell_get_userdata(ce);
+}
+
static void device_set_dedupkey(
struct lsblk_device *dev,
struct lsblk_device *parent,
@@ -2188,22 +2207,29 @@ static void set_column_type(const struct colinfo *ci, struct libscols_column *cl
{
switch (ci->type) {
case COLTYPE_SIZE:
+ /* See init_scols_filter(), it may overwrite the type */
if (!lsblk->bytes)
break;
/* fallthrough */
case COLTYPE_NUM:
scols_column_set_json_type(cl, SCOLS_JSON_NUMBER);
- break;
+ scols_column_set_data_type(cl, SCOLS_DATA_U64);
+ return;
case COLTYPE_BOOL:
scols_column_set_json_type(cl, SCOLS_JSON_BOOLEAN);
- break;
+ scols_column_set_data_type(cl, SCOLS_DATA_BOOLEAN);
+ return;
default:
- if (fl & SCOLS_FL_WRAP)
- scols_column_set_json_type(cl, SCOLS_JSON_ARRAY_STRING);
- else
- scols_column_set_json_type(cl, SCOLS_JSON_STRING);
break;
}
+
+ /* default */
+ if (fl & SCOLS_FL_WRAP)
+ scols_column_set_json_type(cl, SCOLS_JSON_ARRAY_STRING);
+ else
+ scols_column_set_json_type(cl, SCOLS_JSON_STRING);
+
+ scols_column_set_data_type(cl, SCOLS_DATA_STRING);
}
static void init_scols_filter(struct libscols_table *tb, struct libscols_filter *f)
@@ -2217,13 +2243,13 @@ static void init_scols_filter(struct libscols_table *tb, struct libscols_filter
while (scols_filter_next_holder(f, itr, &name, 0) == 0) {
struct libscols_column *col = scols_table_get_column_by_name(tb, name);
+ int id = column_name_to_id(name, strlen(name));
+ const struct colinfo *ci = id >= 0 ? &infos[id] : NULL;
- if (!col) {
- int id = column_name_to_id(name, strlen(name));
- const struct colinfo *ci = id >= 0 ? &infos[id] : NULL;
+ if (!ci)
+ goto fail;
- if (!ci)
- goto fail;
+ if (!col) {
add_column(id);
col = scols_table_new_column(lsblk->table, ci->name,
ci->whint, SCOLS_FL_HIDDEN);
@@ -2232,6 +2258,17 @@ static void init_scols_filter(struct libscols_table *tb, struct libscols_filter
set_column_type(ci, col, ci->flags);
}
+
+ /* For sizes use rawdata (u64) rather than strings from table */
+ if (ci->type == COLTYPE_SIZE
+ && !lsblk->bytes
+ && !scols_column_has_datafunc(col)) {
+
+ scols_column_set_data_type(col, SCOLS_DATA_U64);
+ scols_column_set_datafunc(col, get_u64_cell, NULL);
+ lsblk->rawdata = 1;
+ }
+
scols_filter_assign_column(f, itr, name, col);
}
@@ -2691,6 +2728,7 @@ int main(int argc, char *argv[])
}
if (!lsblk->sort_col && lsblk->sort_id == id) {
lsblk->sort_col = cl;
+ lsblk->rawdata = 1;
scols_column_set_cmpfunc(cl,
ci->type == COLTYPE_NUM ? cmp_u64_cells :
ci->type == COLTYPE_SIZE ? cmp_u64_cells :
@@ -2756,7 +2794,7 @@ int main(int argc, char *argv[])
if (lsblk->ncts)
print_counters();
leave:
- if (lsblk->sort_col)
+ if (lsblk->rawdata)
unref_rawdata(lsblk->table);
scols_unref_table(lsblk->table);
diff --git a/misc-utils/lsblk.h b/misc-utils/lsblk.h
index e98183f08d..a2d9a009ea 100644
--- a/misc-utils/lsblk.h
+++ b/misc-utils/lsblk.h
@@ -61,6 +61,7 @@ struct lsblk {
unsigned int virtio:1; /* print virtio device only */
unsigned int paths:1; /* print devnames with "/dev" prefix */
unsigned int sort_hidden:1; /* sort column not between output columns */
+ unsigned int rawdata : 1; /* has rawdata in cell userdata */
unsigned int dedup_hidden :1; /* deduplication column not between output columns */
unsigned int force_tree_order:1;/* sort lines by parent->tree relation */
unsigned int noempty:1; /* hide empty devices */