]> granicus.if.org Git - sysstat/commit
iostat didn't display target device information when a symbolic
authorSebastien Godard <sysstat@orange.fr>
Tue, 7 Feb 2012 21:14:12 +0000 (22:14 +0100)
committerSebastien Godard <sysstat@orange.fr>
Tue, 7 Feb 2012 21:14:12 +0000 (22:14 +0100)
commit8e96493c4ea3a5c47819acf4a1153a0d802bd802
treeb8ea98a88c49345cc8b0dfcb76c2908b5f33afac
parent50ec564fbdce084052c7844b84850e06bf9e2428
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;
 }
CHANGES
CREDITS
common.c