Skip to content

Commit f52d1d9

Browse files
committed
Add functionality for sorting disk_info list by any field, in either direction
1 parent 8009970 commit f52d1d9

File tree

2 files changed

+171
-6
lines changed

2 files changed

+171
-6
lines changed

src/output_fmt.c

Lines changed: 165 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ static const char* colors[_COLOR_MAX] =
4646
struct field
4747
{
4848
char* string;
49+
const void* sort_val;
4950
int len;
5051
enum COLOR color;
5152
bool bold;
@@ -67,7 +68,10 @@ get_field_port_id(
6768
int rc = -1;
6869

6970
if (-1 != (rc = asprintf(&f->string, "%s", port_id)))
70-
f->len = rc;
71+
{
72+
f->sort_val = f->string;
73+
f->len = rc;
74+
}
7175

7276
return rc;
7377
}
@@ -82,7 +86,10 @@ get_field_blk_dev(
8286
int rc = -1;
8387

8488
if (st)
85-
rc = asprintf(&f->string, "sd%s", scsi_target_get_blk_dev(st));
89+
{
90+
if (-1 != (rc = asprintf(&f->string, "sd%s", scsi_target_get_blk_dev(st))))
91+
f->sort_val = f->string;
92+
}
8693
else
8794
{
8895
if (-1 != (rc = asprintf(&f->string, "N/C")))
@@ -105,7 +112,10 @@ get_field_model(
105112
int rc = -1;
106113

107114
if (bdi->model != BLK_DEV_INFO_UNSET_STRING)
108-
rc = asprintf(&f->string, "%s", bdi->model);
115+
{
116+
if (-1 != (rc = asprintf(&f->string, "%s", bdi->model)))
117+
f->sort_val = f->string;
118+
}
109119
else
110120
rc = asprintf(&f->string, "%s", NA);
111121

@@ -130,7 +140,10 @@ get_field_serial(
130140
rc = asprintf(&f->string, "%s", NA);
131141

132142
if (-1 != rc)
133-
f->len = rc;
143+
{
144+
f->sort_val = f->string;
145+
f->len = rc;
146+
}
134147

135148
return rc;
136149
}
@@ -145,7 +158,10 @@ get_field_size(
145158
int rc = -1;
146159

147160
if (bdi->size_byt != BLK_DEV_INFO_UNSET_U64)
148-
rc = bytes_to_string(&f->string, bdi->size_byt);
161+
{
162+
if (-1 != (rc = bytes_to_string(&f->string, bdi->size_byt)))
163+
f->sort_val = &bdi->size_byt;
164+
}
149165
else
150166
rc = asprintf(&f->string, "%s", NA);
151167

@@ -165,7 +181,10 @@ get_field_age(
165181
int rc = -1;
166182

167183
if (bdi->smt_pwr_on_sec != BLK_DEV_INFO_UNSET_I64)
168-
rc = timespan_to_string(&f->string, bdi->smt_pwr_on_sec);
184+
{
185+
if (-1 != (rc = timespan_to_string(&f->string, bdi->smt_pwr_on_sec)))
186+
f->sort_val = &bdi->smt_pwr_on_sec;
187+
}
169188
else
170189
rc = asprintf(&f->string, "%s", NA);
171190

@@ -199,6 +218,8 @@ get_field_temp(
199218
f->color = COLOR_YELLOW;
200219
else
201220
f->color = COLOR_GREEN;
221+
222+
f->sort_val = &bdi->smt_temp_kel;
202223
}
203224
}
204225
else
@@ -230,6 +251,8 @@ get_field_bad_sect(
230251
}
231252
else if ( bdi->smt_bad_sect > 0)
232253
f->color = COLOR_YELLOW;
254+
255+
f->sort_val = &bdi->smt_bad_sect;
233256
}
234257
}
235258
else
@@ -433,6 +456,142 @@ output_fmt_print(
433456
}
434457
}
435458

459+
static int64_t disk_info_compare(
460+
enum FIELD sort_fld
461+
, int sort_dir
462+
, const struct disk_info* ldi
463+
, const struct disk_info* rdi
464+
)
465+
{
466+
/* sort_dir is used to force the N/A's to the bottom
467+
* regardless of the user selected sort direction */
468+
int64_t rc = 0;
469+
switch (sort_fld)
470+
{
471+
case FLD_PORT_ID:
472+
case FLD_BLK_DEV:
473+
case FLD_MODEL_NO:
474+
case FLD_SERIAL_NO:
475+
{
476+
const char* lhs = ldi->fields[sort_fld].sort_val;
477+
const char* rhs = rdi->fields[sort_fld].sort_val;
478+
if (lhs && rhs)
479+
rc = strcasecmp(lhs, rhs);
480+
else if (lhs)
481+
rc = sort_dir * -1;
482+
else if (rhs)
483+
rc = sort_dir * 1;
484+
break;
485+
}
486+
case FLD_SIZE_BYTES:
487+
{
488+
const uint64_t* ulhs = ldi->fields[sort_fld].sort_val;
489+
const uint64_t* urhs = rdi->fields[sort_fld].sort_val;
490+
if (ulhs && urhs)
491+
{
492+
const int64_t lhs = (int64_t)MIN(*ulhs, INT64_MAX);
493+
const int64_t rhs = (int64_t)MIN(*urhs, INT64_MAX);
494+
rc = lhs - rhs;
495+
}
496+
else if (ulhs)
497+
rc = sort_dir * -1;
498+
else if (urhs)
499+
rc = sort_dir * 1;
500+
break;
501+
}
502+
case FLD_PWR_ON_HRS:
503+
{
504+
const int64_t* lhs = ldi->fields[sort_fld].sort_val;
505+
const int64_t* rhs = rdi->fields[sort_fld].sort_val;
506+
if (lhs && rhs)
507+
rc = *lhs - *rhs;
508+
else if (lhs)
509+
rc = sort_dir * -1;
510+
else if (rhs)
511+
rc = sort_dir * 1;
512+
break;
513+
}
514+
case FLD_TEMP_mC:
515+
{
516+
const double* ulhs = ldi->fields[sort_fld].sort_val;
517+
const double* urhs = rdi->fields[sort_fld].sort_val;
518+
if (ulhs && urhs)
519+
{
520+
const int64_t lhs = (int64_t)MIN(*ulhs*1000.0, (double)INT64_MAX);
521+
const int64_t rhs = (int64_t)MIN(*urhs*1000.0, (double)INT64_MAX);
522+
rc = lhs - rhs;
523+
}
524+
else if (ulhs)
525+
rc = sort_dir * -1;
526+
else if (urhs)
527+
rc = sort_dir * 1;
528+
break;
529+
}
530+
case FLD_BAD_SECT:
531+
{
532+
const int64_t* lhs = ldi->fields[sort_fld].sort_val;
533+
const int64_t* rhs = rdi->fields[sort_fld].sort_val;
534+
if (lhs && rhs)
535+
rc = *lhs - *rhs;
536+
else if (lhs)
537+
rc = sort_dir * -1;
538+
else if (rhs)
539+
rc = sort_dir * 1;
540+
break;
541+
}
542+
default:
543+
break;
544+
}
545+
return rc;
546+
}
547+
548+
void output_fmt_sort(
549+
enum FIELD sort_fld
550+
, int sort_dir
551+
)
552+
{
553+
if (FLD_INVALID != sort_fld)
554+
{
555+
struct disk_info* prev = NULL;
556+
struct disk_info* disk = disks;
557+
558+
while (disk)
559+
{
560+
struct disk_info* n_prev = disk;
561+
struct disk_info* needle = disk->next;
562+
563+
while (needle)
564+
{
565+
int64_t dir = sort_dir * disk_info_compare(sort_fld, sort_dir, disk, needle);
566+
567+
/* Try to do something sane with equivalent values */
568+
if (0 == dir)
569+
dir = sort_dir * disk_info_compare(FLD_BLK_DEV, sort_dir, disk, needle);
570+
if (0 == dir)
571+
dir = sort_dir * disk_info_compare(FLD_PORT_ID, sort_dir, disk, needle);
572+
573+
if (0 < dir)
574+
{
575+
/* remove needle */
576+
n_prev->next = needle->next;
577+
/* insert needle at head */
578+
if (!prev)
579+
disks = needle;
580+
else
581+
prev->next = needle;
582+
needle->next = disk;
583+
/* needle is now the min value */
584+
disk = needle;
585+
}
586+
n_prev = needle;
587+
needle = needle->next;
588+
}
589+
prev = disk;
590+
disk = disk->next;
591+
}
592+
}
593+
}
594+
436595
bool
437596
output_fmt_add_dev(
438597
const char* port_id

src/output_fmt.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ output_fmt_add_dev(
3636
, const struct scsi_target* st
3737
);
3838

39+
void
40+
output_fmt_sort(
41+
enum FIELD sort_fld
42+
, int sort_dir
43+
);
44+
3945
void
4046
output_fmt_deinit(
4147
);

0 commit comments

Comments
 (0)