From 0b7dc91d3cf3b7e921937a4b112caddd3cf4080f Mon Sep 17 00:00:00 2001 From: Sebastien GODARD Date: Sat, 17 Jul 2021 08:26:23 +0200 Subject: [PATCH] iostat: Fix how device mapper names are taken into account Make sure iostat takes into account registered device mapper names when they are entered on the command line. Signed-off-by: Sebastien GODARD --- common.c | 5 ++++- iostat.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/common.c b/common.c index fa81c6c..7097e17 100644 --- a/common.c +++ b/common.c @@ -67,7 +67,10 @@ char sc_sa_restart[MAX_SGR_LEN] = C_LIGHT_RED; char sc_sa_comment[MAX_SGR_LEN] = C_LIGHT_YELLOW; char sc_normal[MAX_SGR_LEN] = C_NORMAL; -/* Type of persistent device names used in sar and iostat */ +/* + * Type of persistent device names in lowercase letters + * (e.g. "uuid", "label", "path"...) Used in sar and iostat. + */ char persistent_name_type[MAX_FILE_LEN]; /* diff --git a/iostat.c b/iostat.c index fa91464..6eddd8b 100644 --- a/iostat.c +++ b/iostat.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "version.h" #include "iostat.h" @@ -124,6 +125,44 @@ void set_disk_output_unit(void) } } +/* + *************************************************************************** + * Get device mapper name (e.g. "dm-0") from its registered name (e.g. + * "virtualhd-home"). + * + * IN: + * @name Registered name of the device (e.g. "virtualhd-home"). + * + * RETURNS: + * Name of the device mapper name (e.g. "dm-0"). + *************************************************************************** + */ +char *get_dm_name_from_registered_name(char *registered_name) +{ + int n; + char filen[PATH_MAX]; + char target[PATH_MAX]; + + /* + * The registered device name is a symlink pointing at its device mapper name + * in the /dev/mapper directory. + */ + n = snprintf(filen, sizeof(filen), "%s/%s", DEVMAP_DIR, registered_name); + if ((n >= sizeof(filen)) || access(filen, F_OK)) { + return (NULL); + } + + /* Read symlink */ + n = readlink(filen, target, PATH_MAX); + if ((n <= 0) || (n >= PATH_MAX)) + return (NULL); + + target[n] = '\0'; + + /* ... and get device mapper name it points at */ + return basename(target); +} + /* *************************************************************************** * SIGALRM signal handler. No need to reset the handler here. @@ -254,6 +293,7 @@ struct io_device *add_list_device(struct io_device **dlist, char *name, int dtyp { struct io_device *d, *ds; int i, rc = 0, maj_nr, min_nr; + char *dm_name; if (strnlen(name, MAX_NAME_LEN) == MAX_NAME_LEN) /* Device name is too long */ @@ -299,7 +339,23 @@ struct io_device *add_list_device(struct io_device **dlist, char *name, int dtyp } memset(d->dev_stats[i], 0, sizeof(struct io_stats)); } - strncpy(d->name, name, MAX_NAME_LEN); + if (DISPLAY_DEVMAP_NAME(flags)) { + /* + * Save device mapper name (e.g. "dm-0") instead of + * its registered name (e.g. "virtualhd-home") + * This is because we won't read stats for a file named "virtualhd-home" but + * for a file named "dm-0" (we will display "virtualhd-home" anyway at the end + * because option -N has been used). + */ + dm_name = get_dm_name_from_registered_name(name); + if (!dm_name) { + dm_name = name; + } + strncpy(d->name, dm_name, sizeof(d->name) - 1); + } + else { + strncpy(d->name, name, sizeof(d->name)); + } d->name[MAX_NAME_LEN - 1] = '\0'; d->exist = TRUE; d->next = ds; -- 2.49.0