iostat didn't display target device information when a symbolic
link was specified as a parameter. This is now fixed.
Mail from Peter Schiffer <pschiffe@redhat.com> 30/01/2012
Hello Sebastien,
my name is Peter Schiffer and I am a new maintainer of sysstat package in RHEL and Fedora.
We have found the following issue:
iostat does not display target device information when a symbolic link is specified as a parameter
example:
Linux 2.6.32-202.el6.x86_64 (localhost.localdomain) 11/30/11 _x86_64_ (16 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.04 0.00 0.05 0.04 0.00 99.87
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
I am proposing one solution how this could be fixed. What is your opinion about it?
Thanks,
peter
symlinks.patch
diff -upr sysstat-10.0.3.old/common.c sysstat-10.0.3/common.c
--- sysstat-10.0.3.old/common.c 2011-11-20 16:38:04.
000000000 +0100
+++ sysstat-10.0.3/common.c 2012-01-30 15:54:28.
856597845 +0100
@@ -379,10 +379,10 @@ int get_win_height(void)
/*
***************************************************************************
- * Remove /dev from path name.
+ * Canonicalize and remove /dev from path name.
*
* IN:
- * @name Device name (may begins with "/dev/")
+ * @name Device name (may begins with "/dev/" or can be a symlink)
*
* RETURNS:
* Device basename.
@@ -390,10 +390,33 @@ int get_win_height(void)
*/
char *device_name(char *name)
{
- if (!strncmp(name, "/dev/", 5))
- return name + 5;
+ char *out;
+ char *resolved_name;
- return name;
+ /* realpath() creates new string, so we need to free it later. */
+ resolved_name = realpath(name, 0);
+
+ /* If path doesn't exists, just copy the input and return it. We have to
+ copy because result of this function is always freed. */
+ if (!resolved_name) {
+ out = (char *)calloc(1, sizeof(name));
+ strncpy(out, name, sizeof(name));
+
+ return out;
+ }
+
+ /* We need to copy the path without "/dev/" prefix because we cannot free
+ 'resolved_name + 5' string. */
+ if (!strncmp(resolved_name, "/dev/", 5)) {
+ out = (char *)calloc(1, sizeof(resolved_name) - 4);
+ strncpy(out, resolved_name + 5, sizeof(resolved_name) - 4);
+
+ free(resolved_name);
+
+ return out;
+ }
+
+ return resolved_name;
}
/*
diff -upr sysstat-10.0.3.old/iostat.c sysstat-10.0.3/iostat.c
--- sysstat-10.0.3.old/iostat.c 2011-11-20 16:38:04.
000000000 +0100
+++ sysstat-10.0.3/iostat.c 2012-01-30 15:57:41.
551553692 +0100
@@ -274,6 +274,8 @@ int update_dev_list(int *dlist_idx, char
strncpy(sdli->dev_name, device_name, MAX_NAME_LEN - 1);
}
+ free(device_name);
+
return i;
}