commit 4accbb2d37dc04dad87cdc4ffbf9021d10eadbf1
Author: Sebastien Godard <sysstat@orange.fr>
Date:   Sat Dec 11 21:49:22 2010 +0100

    No longer assume that device-mapper major number is 253.
    Get the real number from /proc/devices file.
    
    The sar, sadf and iostat commands used to assume that device-mapper
    major number was 253. This happened to be false sometimes. So get
    the real number from the /proc/devices file.
    
    From Mike Coleman <tutufan@gmail.com> 04/10/2010:
    
    The iostat program seems to assume that the major device number for
    devmap will always be 253.  This doesn't seem to be an official
    number, though, and I have a box where it actually ends up being 252,
    which breaks 'iostat -N'.
    
    It looks like this can be determined dynamically by looking at /proc/devices.

Index: sysstat-8.1.5/common.c
===================================================================
--- sysstat-8.1.5.orig/common.c	2015-05-06 13:50:32.941955842 +0200
+++ sysstat-8.1.5/common.c	2015-05-14 12:15:48.408943923 +0200
@@ -28,6 +28,7 @@
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <dirent.h>
+#include <limits.h>
 
 #include "version.h"
 #include "common.h"
@@ -269,6 +270,42 @@ int get_nfs_mount_nr(void)
 }
 
 /*
+ ***************************************************************************
+ * Read /proc/devices file and get device-mapper major number.
+ * If device-mapper entry is not found in file, assume it's
+ * not active.
+ *
+ * RETURNS:
+ * Device-mapper major number.
+ ***************************************************************************
+ */
+unsigned int get_devmap_major(void)
+{
+	FILE *fp;
+	char line[128];
+	/*
+	 * Linux 2.6 uses 12 bits for major number,
+	 * so devices with this major number shouldn't exist
+	 */
+	unsigned int dm_major = UINT_MAX;
+
+	if ((fp = fopen(DEVICES, "r")) == NULL)
+		return dm_major;
+
+	while (fgets(line, 128, fp) != NULL) {
+
+		if (strstr(line, "device-mapper")) {
+			/* Read device-mapper major number */
+			sscanf(line, "%u", &dm_major);
+		}
+	}
+
+	fclose(fp);
+
+	return dm_major;
+}
+
+/*
  ***************************************************************************
  * Print banner
  *
Index: sysstat-8.1.5/common.h
===================================================================
--- sysstat-8.1.5.orig/common.h	2015-05-05 16:52:59.931113375 +0200
+++ sysstat-8.1.5/common.h	2015-05-14 12:32:26.359078145 +0200
@@ -52,10 +52,10 @@
 #define NFSMOUNTSTATS	"/proc/self/mountstats"
 #define S_STAT		"stat"
 #define DEVMAP_DIR	"/dev/mapper"
+#define DEVICES		"/proc/devices"
 
 #define MAX_FILE_LEN	256
 #define MAX_PF_NAME	1024
-#define DEVMAP_MAJOR	253
 #define MAX_NAME_LEN	72
 
 #define NR_DISKS	4
@@ -158,6 +158,8 @@ extern char *
 	device_name(char *);
 extern void
 	get_HZ(void);
+extern unsigned int
+	get_devmap_major(void);
 extern unsigned long long
 	get_interval(unsigned long long, unsigned long long);
 extern void
Index: sysstat-8.1.5/iostat.c
===================================================================
--- sysstat-8.1.5.orig/iostat.c	2015-05-05 16:52:59.931113375 +0200
+++ sysstat-8.1.5/iostat.c	2015-05-14 10:13:49.579515594 +0200
@@ -63,6 +63,7 @@ int ionfs_nr = 0;	/* Nb of NFS mounted d
 int cpu_nr = 0;		/* Nb of processors on the machine */
 int dlist_idx = 0;	/* Nb of devices entered on the command line */
 int flags = 0;		/* Flag for common options and system state */
+unsigned int dm_major;	/* Device-mapper major number */
 
 long interval = 0;
 char timestamp[64];
@@ -848,7 +849,7 @@ void read_diskstats_stat(int curr)
 			}
 		}
 
-		if ((DISPLAY_DEVMAP_NAME(flags)) && (major == DEVMAP_MAJOR)) {
+		if ((DISPLAY_DEVMAP_NAME(flags)) && (major == dm_major)) {
 			/*
 			 * If the device is a device mapper device, try to get its
 			 * assigned name of its logical device.
@@ -918,7 +919,7 @@ void read_ppartitions_stat(int curr)
 			}
 		}
 
-		if ((DISPLAY_DEVMAP_NAME(flags)) && (major == DEVMAP_MAJOR)) {
+		if ((DISPLAY_DEVMAP_NAME(flags)) && (major == dm_major)) {
 			/* Get device mapper logical name */
 			dm_name = transform_devmapname(major, minor);
 			if (dm_name) {
@@ -1703,6 +1704,10 @@ int main(int argc, char **argv)
 		dlist_idx = 0;
 	}
 
+	if (DISPLAY_DEVMAP_NAME(flags)) {
+		dm_major = get_devmap_major();
+	}
+
 	/* Init structures according to machine architecture */
 	io_sys_init();
 
Index: sysstat-8.1.5/pr_stats.c
===================================================================
--- sysstat-8.1.5.orig/pr_stats.c	2015-05-07 10:45:12.907161015 +0200
+++ sysstat-8.1.5/pr_stats.c	2015-05-14 10:13:49.579515594 +0200
@@ -36,6 +36,7 @@
 #endif
 
 extern unsigned int flags;
+extern unsigned int dm_major;
 extern int  dis;
 extern char timestamp[][TIMESTAMP_LEN];
 extern struct stats_sum asum;
@@ -790,7 +791,7 @@ __print_funct_t print_disk_stats(struct
 		
 		dev_name = NULL;
 
-		if ((USE_PRETTY_OPTION(flags)) && (sdc->major == DEVMAP_MAJOR)) {
+		if ((USE_PRETTY_OPTION(flags)) && (sdc->major == dm_major)) {
 			dev_name = transform_devmapname(sdc->major, sdc->minor);
 		}
 
Index: sysstat-8.1.5/sadf.c
===================================================================
--- sysstat-8.1.5.orig/sadf.c	2015-05-05 16:52:59.931113375 +0200
+++ sysstat-8.1.5/sadf.c	2015-05-14 10:13:49.579515594 +0200
@@ -48,6 +48,7 @@ char *sccsid(void) { return (SCCSID); }
 long interval = -1, count = 0;
 
 unsigned int flags = 0;
+unsigned int dm_major;		/* Device-mapper major number */
 unsigned int format = 0;	/* Output format */
 
 /* File header */
@@ -1186,6 +1187,10 @@ int main(int argc, char **argv)
 		tm_end.tm_hour += 24;
 	}
 
+	if (USE_PRETTY_OPTION(flags)) {
+		dm_major = get_devmap_major();
+	}
+
 	/*
 	 * Display all the contents of the daily data file if the count parameter
 	 * was not set on the command line.
Index: sysstat-8.1.5/sar.c
===================================================================
--- sysstat-8.1.5.orig/sar.c	2015-05-05 16:52:59.931113375 +0200
+++ sysstat-8.1.5/sar.c	2015-05-14 10:13:49.580515609 +0200
@@ -50,6 +50,8 @@ long interval = -1, count = 0;
 int dis = TRUE;
 
 unsigned int flags = 0;
+unsigned int dm_major;	/* Device-mapper major number */
+
 char timestamp[2][TIMESTAMP_LEN];
 
 struct stats_sum asum;
@@ -1132,6 +1134,10 @@ int main(int argc, char **argv)
 		usage(argv[0]);
 	}
 
+	if (USE_PRETTY_OPTION(flags)) {
+		dm_major = get_devmap_major();
+	}
+	
 	if (!count) {
 		/*
 		 * count parameter not set: Display all the contents of the file
Index: sysstat-8.1.5/prf_stats.c
===================================================================
--- sysstat-8.1.5.orig/prf_stats.c	2015-05-05 16:53:07.585229687 +0200
+++ sysstat-8.1.5/prf_stats.c	2015-05-14 10:13:49.580515609 +0200
@@ -38,6 +38,7 @@
 static char *seps[] =  {"\t", ";"};
 
 extern unsigned int flags;
+extern unsigned int dm_major;
 
 /*
  ***************************************************************************
@@ -881,7 +882,7 @@ __print_funct_t render_disk_stats(struct
 
 		dev_name = NULL;
 
-		if ((USE_PRETTY_OPTION(flags)) && (sdc->major == DEVMAP_MAJOR)) {
+		if ((USE_PRETTY_OPTION(flags)) && (sdc->major == dm_major)) {
 			dev_name = transform_devmapname(sdc->major, sdc->minor);
 		}
 
@@ -1884,7 +1885,7 @@ __print_funct_t xml_print_disk_stats(str
 		
 		dev_name = NULL;
 
-		if ((USE_PRETTY_OPTION(flags)) && (sdc->major == DEVMAP_MAJOR)) {
+		if ((USE_PRETTY_OPTION(flags)) && (sdc->major == dm_major)) {
 			dev_name = transform_devmapname(sdc->major, sdc->minor);
 		}
 
