@@ -46,6 +46,7 @@ static const char* colors[_COLOR_MAX] =
46
46
struct field
47
47
{
48
48
char * string ;
49
+ const void * sort_val ;
49
50
int len ;
50
51
enum COLOR color ;
51
52
bool bold ;
@@ -67,7 +68,10 @@ get_field_port_id(
67
68
int rc = -1 ;
68
69
69
70
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
+ }
71
75
72
76
return rc ;
73
77
}
@@ -82,7 +86,10 @@ get_field_blk_dev(
82
86
int rc = -1 ;
83
87
84
88
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
+ }
86
93
else
87
94
{
88
95
if (-1 != (rc = asprintf (& f -> string , "N/C" )))
@@ -105,7 +112,10 @@ get_field_model(
105
112
int rc = -1 ;
106
113
107
114
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
+ }
109
119
else
110
120
rc = asprintf (& f -> string , "%s" , NA );
111
121
@@ -130,7 +140,10 @@ get_field_serial(
130
140
rc = asprintf (& f -> string , "%s" , NA );
131
141
132
142
if (-1 != rc )
133
- f -> len = rc ;
143
+ {
144
+ f -> sort_val = f -> string ;
145
+ f -> len = rc ;
146
+ }
134
147
135
148
return rc ;
136
149
}
@@ -145,7 +158,10 @@ get_field_size(
145
158
int rc = -1 ;
146
159
147
160
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
+ }
149
165
else
150
166
rc = asprintf (& f -> string , "%s" , NA );
151
167
@@ -165,7 +181,10 @@ get_field_age(
165
181
int rc = -1 ;
166
182
167
183
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
+ }
169
188
else
170
189
rc = asprintf (& f -> string , "%s" , NA );
171
190
@@ -199,6 +218,8 @@ get_field_temp(
199
218
f -> color = COLOR_YELLOW ;
200
219
else
201
220
f -> color = COLOR_GREEN ;
221
+
222
+ f -> sort_val = & bdi -> smt_temp_kel ;
202
223
}
203
224
}
204
225
else
@@ -230,6 +251,8 @@ get_field_bad_sect(
230
251
}
231
252
else if ( bdi -> smt_bad_sect > 0 )
232
253
f -> color = COLOR_YELLOW ;
254
+
255
+ f -> sort_val = & bdi -> smt_bad_sect ;
233
256
}
234
257
}
235
258
else
@@ -433,6 +456,142 @@ output_fmt_print(
433
456
}
434
457
}
435
458
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
+
436
595
bool
437
596
output_fmt_add_dev (
438
597
const char * port_id
0 commit comments