From cff5911b624c50a9dabf203f889e43955d88f1a3 Mon Sep 17 00:00:00 2001 From: Sebastien GODARD Date: Wed, 14 Jul 2021 11:29:53 +0200 Subject: [PATCH] iostat: Always display persistent names with option -j When a persistent name (e.g. UUID) is entered on the command line, iostat displayed the real name of the device instead of its persistent name, e.g.: $ iostat -d -j UUID 65ccf2b5-50de-4f89-bf8e-e3e88eae4c63 Linux 5.12.14-200.fc33.x86_64 (linux-1.home) 07/14/2021 _x86_64_ (8 CPU) tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd Device 1.89 6.73 0.00 31799.48 58452 12 276250680 sda Fix this so that the persistent name appears in the report: $ iostat -d -j UUID 65ccf2b5-50de-4f89-bf8e-e3e88eae4c63 Linux 5.12.14-200.fc33.x86_64 (linux-1.home) 07/14/2021 _x86_64_ (8 CPU) tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd Device 1.88 6.66 0.00 31489.67 58452 12 276250680 65ccf2b5-50de-4f89-bf8e-e3e88eae4c63 Signed-off-by: Sebastien GODARD --- iostat.c | 145 +++++++++++++++++++++++++------------------------------ iostat.h | 4 +- 2 files changed, 70 insertions(+), 79 deletions(-) diff --git a/iostat.c b/iostat.c index 330f8c1..fa91464 100644 --- a/iostat.c +++ b/iostat.c @@ -185,6 +185,47 @@ void set_devices_nonexistent(struct io_device *dlist) } } +/* + *************************************************************************** + * Get device major and minor numbers. + * + * IN: + * @filename Name of the device ("sda", "/dev/sdb1"...) + * + * OUT: + * @major Major number of the device. + * @minor Minor number of the device. + * + * RETURNS: + * 0 on success, and -1 otherwise. + *************************************************************************** + */ +int get_major_minor_nr(char filename[], int *major, int *minor) +{ + struct stat statbuf; + char *bang; + char dfile[MAX_PF_NAME]; + + snprintf(dfile, sizeof(dfile), "%s%s", filename[0] == '/' ? "" : SLASH_DEV, filename); + dfile[sizeof(dfile) - 1] = '\0'; + + while ((bang = strchr(dfile, '!'))) { + /* + * Some devices may have had a slash replaced with a bang character (eg. cciss!c0d0...) + * Restore their original names so that they can be found in /dev directory. + */ + *bang = '/'; + } + + if (__stat(dfile, &statbuf) < 0) + return -1; + + *major = __major(statbuf.st_rdev); + *minor = __minor(statbuf.st_rdev); + + return 0; +} + /* *************************************************************************** * Check if a device is present in the list, and add it if requested. @@ -196,6 +237,10 @@ void set_devices_nonexistent(struct io_device *dlist) * @dtype T_PART_DEV (=2) if the device and all its partitions should * also be read (option -p used), T_GROUP (=3) if it's a group * name, and 0 otherwise. + * @major Major number of the device (set to UKWN_MAJ_NR by caller if + * unknown: In this case, major and minor numbers will be + * determined here). + * @minor Minor number of the device. * * RETURNS: * Pointer on the io_device structure in the list where the device is located @@ -204,10 +249,11 @@ void set_devices_nonexistent(struct io_device *dlist) * don't want to add it. *************************************************************************** */ -struct io_device *add_list_device(struct io_device **dlist, char *name, int dtype) +struct io_device *add_list_device(struct io_device **dlist, char *name, int dtype, + int major, int minor) { struct io_device *d, *ds; - int i, rc = 0; + int i, rc = 0, maj_nr, min_nr; if (strnlen(name, MAX_NAME_LEN) == MAX_NAME_LEN) /* Device name is too long */ @@ -277,50 +323,22 @@ struct io_device *add_list_device(struct io_device **dlist, char *name, int dtyp /* This is a partition (T_PART) */ d->dev_tp = T_PART; } - } - - return d; -} - -/* - *************************************************************************** - * Get device major and minor numbers. - * - * IN: - * @filename Name of the device ("sda", "/dev/sdb1"...) - * - * OUT: - * @major Major number of the device. - * @minor Minor number of the device. - * - * RETURNS: - * 0 on success, and -1 otherwise. - *************************************************************************** - */ -int get_major_minor_nr(char filename[], int *major, int *minor) -{ - struct stat statbuf; - char *bang; - char dfile[MAX_PF_NAME]; - - snprintf(dfile, sizeof(dfile), "%s%s", filename[0] == '/' ? "" : SLASH_DEV, filename); - dfile[sizeof(dfile) - 1] = '\0'; - while ((bang = strchr(dfile, '!'))) { - /* - * Some devices may have had a slash replaced with a bang character (eg. cciss!c0d0...) - * Restore their original names so that they can be found in /dev directory. - */ - *bang = '/'; + /* Save major and minor numbers */ + if (major != UKWN_MAJ_NR) { + d->major = major; + d->minor = minor; + } + else { + /* Look for device major and minor numbers */ + if (get_major_minor_nr(d->name, &maj_nr, &min_nr) == 0) { + d->major = maj_nr; + d->minor = min_nr; + } + } } - if (__stat(dfile, &statbuf) < 0) - return -1; - - *major = __major(statbuf.st_rdev); - *minor = __minor(statbuf.st_rdev); - - return 0; + return d; } /* @@ -466,7 +484,6 @@ int read_sysfs_device_part_stat_work(int curr, char *dname, char *sysdev) struct io_stats sdev; struct io_device *d; char dfile[MAX_PF_NAME], filename[MAX_PF_NAME + 512]; - int major, minor; snprintf(dfile, sizeof(dfile), "%s/%s/%s", sysdev, __BLOCK, dname); dfile[sizeof(dfile) - 1] = '\0'; @@ -487,17 +504,9 @@ int read_sysfs_device_part_stat_work(int curr, char *dname, char *sysdev) if (read_sysfs_file_stat_work(filename, &sdev) < 0) continue; - d = add_list_device(&dev_list, drd->d_name, 0); + d = add_list_device(&dev_list, drd->d_name, 0, UKWN_MAJ_NR, 0); if (d != NULL) { *(d->dev_stats[curr]) = sdev; - - if (!d->major) { - /* Get major and minor numbers for given device */ - if (get_major_minor_nr(d->name, &major, &minor) == 0) { - d->major = major; - d->minor = minor; - } - } } } @@ -557,7 +566,6 @@ int read_sysfs_all_devices_stat_work(int curr, char *sysblock) struct io_stats sdev; struct io_device *d; char dfile[MAX_PF_NAME]; - int major, minor; /* Open __sys/block directory */ if ((dir = __opendir(sysblock)) == NULL) @@ -575,17 +583,9 @@ int read_sysfs_all_devices_stat_work(int curr, char *sysblock) if (read_sysfs_file_stat_work(dfile, &sdev) < 0) continue; - d = add_list_device(&dev_list, drd->d_name, 0); + d = add_list_device(&dev_list, drd->d_name, 0, UKWN_MAJ_NR, 0); if (d != NULL) { *(d->dev_stats[curr]) = sdev; - - if (!d->major) { - /* Get major and minor numbers for given device */ - if (get_major_minor_nr(d->name, &major, &minor) == 0) { - d->major = major; - d->minor = minor; - } - } } } @@ -643,15 +643,6 @@ int read_sysfs_all_devices_stat(int curr) int read_sysfs_part_stat_work(int curr, struct io_device *d, char *sysdev) { char dfile[MAX_PF_NAME]; - int major, minor; - - if (!d->major) { - /* Get major and minor numbers for given device */ - if (get_major_minor_nr(d->name, &major, &minor) < 0) - return -1; - d->major = major; - d->minor = minor; - } /* Read stats for device */ snprintf(dfile, sizeof(dfile), "%s/%s/%d:%d/%s", @@ -817,11 +808,9 @@ void read_diskstats_stat_work(int curr, char *diskstats) /* Unknown entry: Ignore it */ continue; - d = add_list_device(&dev_list, dev_name, 0); + d = add_list_device(&dev_list, dev_name, 0, major, minor); if (d != NULL) { *d->dev_stats[curr] = sdev; - d->major = major; - d->minor = minor; } } fclose(fp); @@ -2046,7 +2035,7 @@ int main(int argc, char **argv) } } /* Store device name */ - add_list_device(&dev_list, devname, T_PART_DEV); + add_list_device(&dev_list, devname, T_PART_DEV, 0, 0); } } opt++; @@ -2067,7 +2056,7 @@ int main(int argc, char **argv) * and one for the trailing '\0'. */ snprintf(group_name, MAX_NAME_LEN, " %-.*s", MAX_NAME_LEN - 2, argv[opt++]); - add_list_device(&dev_list, group_name, T_GROUP); + add_list_device(&dev_list, group_name, T_GROUP, 0, 0); } else if (!strcmp(argv[opt], "--human")) { @@ -2256,7 +2245,7 @@ int main(int argc, char **argv) devname = persist_devname; } } - add_list_device(&dev_list, devname, 0); + add_list_device(&dev_list, devname, 0, UKWN_MAJ_NR, 0); } else { flags |= I_D_ALL_DEVICES; diff --git a/iostat.h b/iostat.h index c051db1..261271c 100644 --- a/iostat.h +++ b/iostat.h @@ -60,6 +60,8 @@ #define T_PART_DEV 2 #define T_GROUP 3 +#define UKWN_MAJ_NR 0 + /* Environment variable */ #define ENV_POSIXLY_CORRECT "POSIXLY_CORRECT" @@ -117,7 +119,7 @@ struct io_device { int dev_tp; /* TRUE if device exists in /proc/diskstats or /sys. Don't apply for groups. */ int exist; - /* major and minor numbers are set only for partitions (T_PART), not whole devices */ + /* major and minor numbers (not set for T_GROUP "devices") */ int major; int minor; struct io_stats *dev_stats[2]; -- 2.40.0