disk reporting in /proc/stat

Terje Malmedal (tm@odin.funcom.com)
Tue, 7 Oct 1997 14:16:50 +0200


Linux will by default not report statistics for more than the four
first disks in the system. This patch increases that to eight. Which
is what I need. If anybody needs more all they need to do is to change
DK_NDRIVE in kernel_stat.h

I'm also including a patch against ftp.feral.com:/pub/linux/iostat.c
to make it understand the new format.

diff -ur linux-2.1.57/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- linux-2.1.57/drivers/block/ll_rw_blk.c Sat Aug 16 18:53:08 1997
+++ linux/drivers/block/ll_rw_blk.c Sun Oct 5 16:57:33 1997
@@ -252,7 +252,7 @@
switch (MAJOR(req->rq_dev)) {
case SCSI_DISK_MAJOR:
disk_index = (MINOR(req->rq_dev) & 0x0070) >> 4;
- if (disk_index < 4)
+ if (disk_index < DK_NDRIVE)
drive_stat_acct(req->cmd, req->nr_sectors, disk_index);
break;
case IDE0_MAJOR: /* same as HD_MAJOR */
diff -ur linux-2.1.57/fs/proc/array.c linux/fs/proc/array.c
--- linux-2.1.57/fs/proc/array.c Sun Sep 21 19:50:01 1997
+++ linux/fs/proc/array.c Tue Oct 7 13:48:20 1997
@@ -28,6 +28,11 @@
*
* Yves Arrouye : remove removal of trailing spaces in get_array.
* <Yves.Arrouye@marin.fdn.fr>
+ *
+ * Terje Malmedal : Increased number of disks reported on in /proc/stat
+ * to eight. To increase it further change DK_NDRIVE
+ * in kernel_stat.h.
+ * <tm@funcom.com>
*/

#include <linux/types.h>
@@ -210,7 +215,17 @@

static int get_kstat(char * buffer)
{
- int i, len;
+ static char* disk_params[] = {
+ "disk",
+ "disk_rio","disk_wio",
+ "disk_rblk","disk_wblk"
+ };
+ int* disk_info[] = {
+ kstat.dk_drive,
+ kstat.dk_drive_rio,kstat.dk_drive_wio,
+ kstat.dk_drive_rblk,kstat.dk_drive_wblk
+ };
+ int i, j, len;
unsigned sum = 0;
extern unsigned long total_forks;
unsigned long ticks;
@@ -219,29 +234,21 @@
for (i = 0 ; i < NR_IRQS ; i++)
sum += kstat.interrupts[i];
len = sprintf(buffer,
- "cpu %u %u %u %lu\n"
- "disk %u %u %u %u\n"
- "disk_rio %u %u %u %u\n"
- "disk_wio %u %u %u %u\n"
- "disk_rblk %u %u %u %u\n"
- "disk_wblk %u %u %u %u\n"
- "page %u %u\n"
- "swap %u %u\n"
- "intr %u",
+ "cpu %u %u %u %lu\n",
kstat.cpu_user,
kstat.cpu_nice,
kstat.cpu_system,
- ticks - (kstat.cpu_user + kstat.cpu_nice + kstat.cpu_system),
- kstat.dk_drive[0], kstat.dk_drive[1],
- kstat.dk_drive[2], kstat.dk_drive[3],
- kstat.dk_drive_rio[0], kstat.dk_drive_rio[1],
- kstat.dk_drive_rio[2], kstat.dk_drive_rio[3],
- kstat.dk_drive_wio[0], kstat.dk_drive_wio[1],
- kstat.dk_drive_wio[2], kstat.dk_drive_wio[3],
- kstat.dk_drive_rblk[0], kstat.dk_drive_rblk[1],
- kstat.dk_drive_rblk[2], kstat.dk_drive_rblk[3],
- kstat.dk_drive_wblk[0], kstat.dk_drive_wblk[1],
- kstat.dk_drive_wblk[2], kstat.dk_drive_wblk[3],
+ ticks - (kstat.cpu_user + kstat.cpu_nice + kstat.cpu_system));
+ for (j = 0; j < 5; j++) {
+ len += sprintf(buffer + len , disk_params[j] );
+ for (i = 0; i < DK_NDRIVE; i++)
+ len += sprintf(buffer + len," %u",disk_info[j][i]);
+ len += sprintf(buffer + len , "\n" );
+ }
+ len += sprintf(buffer + len,
+ "page %u %u\n"
+ "swap %u %u\n"
+ "intr %u",
kstat.pgpgin,
kstat.pgpgout,
kstat.pswpin,
diff -ur linux-2.1.57/include/linux/kernel_stat.h linux/include/linux/kernel_stat.h
--- linux-2.1.57/include/linux/kernel_stat.h Tue Jul 1 00:23:12 1997
+++ linux/include/linux/kernel_stat.h Sun Oct 5 17:29:10 1997
@@ -9,7 +9,7 @@
* used by rstatd/perfmeter
*/

-#define DK_NDRIVE 4
+#define DK_NDRIVE 8

struct kernel_stat {
unsigned int cpu_user, cpu_nice, cpu_system;

----------------------------------------------------------------------------
And now the patch against iostat.c

--- iostat.c.org Tue Oct 7 12:46:17 1997
+++ iostat.c Tue Oct 7 13:28:25 1997
@@ -60,15 +60,17 @@
#define STATFILE "/proc/stat"
#endif

-#define DK_NDRIVE 4
+#define DK_NDRIVE 64
#define CPU_USER 0
#define CPU_NICE 1
#define CPU_SYSTEM 2
#define CPU_IDLE 3

-static int get_stats(unsigned int cpu[4], unsigned int dk[4]);
+static int get_stats(unsigned int cpu[4], unsigned int dk[DK_NDRIVE]);
static void print_hdr(void);

+static int num_drives;
+
static inline double
totcpu(unsigned int c[4])
{
@@ -100,7 +102,7 @@
return (1);
}
print_hdr();
- for (i = 0; i < DK_NDRIVE; i++)
+ for (i = 0; i < num_drives; i++)
fprintf(stdout, "% 8d", odk_drive[i]);
lctime = ctime = totcpu(ocpu_times);
fprintf(stdout, " %2.0f %2.0f %2.0f %2.0f\n",
@@ -114,9 +116,9 @@
sleep(sleepincr);
if (get_stats(cpu_times, dk_drive))
break;
- for (i = 0; i < DK_NDRIVE; i++)
+ for (i = 0; i < num_drives; i++)
odk_drive[i] = dk_drive[i] - odk_drive[i];
- for (i = 0; i < DK_NDRIVE; i++) {
+ for (i = 0; i < num_drives; i++) {
fprintf(stdout, "%8.0f",
(double) odk_drive[i] / (double) sleepincr);
odk_drive[i] = dk_drive[i];
@@ -147,6 +149,8 @@
int gotcpu, gotdk;
char lbuf[132];
FILE *statfp;
+ int i;
+ char *num;

statfp = fopen(STATFILE, "r");
if (statfp == NULL) {
@@ -168,9 +172,13 @@
continue;
}
if (strncmp(lbuf, "disk", 4) == 0) {
- if (sscanf(lbuf+5, "%u %u %u %u\n",
- &dk[0], &dk[1], &dk[2], &dk[3]) != 4) {
- fprintf(stderr, "bad disk line in %s\n", STATFILE);
+ i = 0;
+ num = strtok(lbuf," ");
+ while((num = strtok(NULL," ")) && i < DK_NDRIVE) {
+ dk[i] = atoi(num);
+ if(dk[i] > 0)
+ num_drives = i+1;
+ i++;
}
gotdk++;
continue;
@@ -184,7 +192,7 @@
print_hdr(void)
{
int i;
- for (i = 0; i < DK_NDRIVE; i++) {
+ for (i = 0; i < num_drives; i++) {
(void) fprintf(stdout, " dk%d", i);
}
fprintf(stdout, " us ni sy id\n");

-- 
 - Terje
tm@funcom.com