ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/disk_stats.c
Revision: 1.34
Committed: Sun Oct 19 12:04:05 2003 UTC (20 years, 6 months ago) by ats
Content type: text/plain
Branch: MAIN
Changes since 1.33: +67 -3 lines
Log Message:
Implement diskio stats on NetBSD. Tested on 1.6, but should work on 1.6.1
(and give more useful output, since 1.6.1 seperates read and write statistics).

File Contents

# User Rev Content
1 pajs 1.1 /*
2     * i-scream central monitoring system
3 tdb 1.18 * http://www.i-scream.org
4     * Copyright (C) 2000-2003 i-scream
5 pajs 1.1 *
6     * This program is free software; you can redistribute it and/or
7     * modify it under the terms of the GNU General Public License
8     * as published by the Free Software Foundation; either version 2
9     * of the License, or (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19     */
20    
21     #ifdef HAVE_CONFIG_H
22     #include "config.h"
23     #endif
24    
25 pajs 1.17 #include <stdio.h>
26 pajs 1.1 #include <stdlib.h>
27     #include <string.h>
28 tdb 1.7 #include "statgrab.h"
29 pajs 1.1
30     #ifdef SOLARIS
31     #include <sys/mnttab.h>
32     #include <sys/statvfs.h>
33 pajs 1.4 #include <kstat.h>
34 pajs 1.1 #define VALID_FS_TYPES {"ufs", "tmpfs"}
35     #endif
36    
37 pajs 1.9 #ifdef LINUX
38 ats 1.30 #include <time.h>
39 pajs 1.9 #include <sys/vfs.h>
40     #include <mntent.h>
41 pajs 1.10 #include "tools.h"
42 ats 1.32 #define VALID_FS_TYPES {"adfs", "affs", "befs", "bfs", "efs", "ext2", \
43     "ext3", "vxfs", "hfs", "hfsplus", "hpfs", "jffs", \
44     "jffs2", "minix", "msdos", "ntfs", "qnx4", "ramfs", \
45     "rootfs", "reiserfs", "sysv", "v7", "udf", "ufs", \
46     "umsdos", "vfat", "xfs", "jfs"}
47 pajs 1.9 #endif
48    
49 ats 1.31 #ifdef ALLBSD
50 pajs 1.16 #include <sys/param.h>
51     #include <sys/ucred.h>
52     #include <sys/mount.h>
53 ats 1.31 #define VALID_FS_TYPES {"ufs", "mfs", "ffs"}
54     #endif
55     #ifdef FREEBSD
56 pajs 1.17 #include <sys/dkstat.h>
57     #include <devstat.h>
58 pajs 1.16 #endif
59 ats 1.34 #ifdef NETBSD
60     #include <sys/param.h>
61     #include <sys/sysctl.h>
62     #include <sys/disk.h>
63     #endif
64 ats 1.31
65 pajs 1.1 #define START_VAL 1
66    
67     char *copy_string(char *orig_ptr, const char *newtext){
68    
69     /* Maybe free if not NULL, and strdup rather than realloc and strcpy? */
70     orig_ptr=realloc(orig_ptr, (1+strlen(newtext)));
71     if(orig_ptr==NULL){
72     return NULL;
73     }
74     strcpy(orig_ptr, newtext);
75    
76     return orig_ptr;
77     }
78    
79    
80     void init_disk_stat(int start, int end, disk_stat_t *disk_stats){
81    
82     for(disk_stats+=start; start<=end; start++){
83     disk_stats->device_name=NULL;
84     disk_stats->fs_type=NULL;
85     disk_stats->mnt_point=NULL;
86    
87     disk_stats++;
88     }
89     }
90    
91     disk_stat_t *get_disk_stats(int *entries){
92    
93     static disk_stat_t *disk_stats;
94     static int watermark=-1;
95    
96     char *fs_types[] = VALID_FS_TYPES;
97     int x, valid_type;
98     int num_disks=0;
99 pajs 1.16 #if defined(LINUX) || defined (SOLARIS)
100 pajs 1.1 FILE *f;
101 pajs 1.16 #endif
102 pajs 1.1
103     disk_stat_t *disk_ptr;
104    
105 pajs 1.9 #ifdef SOLARIS
106 tdb 1.13 struct mnttab mp;
107 pajs 1.9 struct statvfs fs;
108     #endif
109     #ifdef LINUX
110     struct mntent *mp;
111     struct statfs fs;
112     #endif
113 ats 1.31 #ifdef ALLBSD
114 pajs 1.16 int nummnt;
115     struct statfs *mp;
116     #endif
117 pajs 1.9
118 pajs 1.1 if(watermark==-1){
119     disk_stats=malloc(START_VAL * sizeof(disk_stat_t));
120     if(disk_stats==NULL){
121     return NULL;
122     }
123     watermark=START_VAL;
124     init_disk_stat(0, watermark-1, disk_stats);
125     }
126 ats 1.31 #ifdef ALLBSD
127 pajs 1.16 nummnt=getmntinfo(&mp , MNT_LOCAL);
128     if (nummnt<=0){
129     return NULL;
130     }
131     for(;nummnt--; mp++){
132     valid_type=0;
133     for(x=0;x<((sizeof(fs_types))/(sizeof(char*)));x++){
134     if(strcmp(mp->f_fstypename, fs_types[x]) ==0){
135     valid_type=1;
136     break;
137     }
138     }
139     #endif
140    
141 pajs 1.9 #ifdef LINUX
142     if ((f=setmntent("/etc/mtab", "r" ))==NULL){
143     return NULL;
144     }
145 pajs 1.1
146 pajs 1.9 while((mp=getmntent(f))){
147     if((statfs(mp->mnt_dir, &fs)) !=0){
148     continue;
149     }
150 pajs 1.1
151 pajs 1.9 valid_type=0;
152     for(x=0;x<((sizeof(fs_types))/(sizeof(char*)));x++){
153     if(strcmp(mp->mnt_type, fs_types[x]) ==0){
154     valid_type=1;
155     break;
156     }
157     }
158     #endif
159    
160     #ifdef SOLARIS
161 pajs 1.1 if ((f=fopen("/etc/mnttab", "r" ))==NULL){
162     return NULL;
163     }
164     while((getmntent(f, &mp)) == 0){
165     if ((statvfs(mp.mnt_mountp, &fs)) !=0){
166     continue;
167     }
168     valid_type=0;
169     for(x=0;x<((sizeof(fs_types))/(sizeof(char*)));x++){
170     if(strcmp(mp.mnt_fstype, fs_types[x]) ==0){
171     valid_type=1;
172     break;
173     }
174     }
175 pajs 1.9 #endif
176 pajs 1.1
177     if(valid_type){
178     if(num_disks>watermark-1){
179     disk_ptr=disk_stats;
180     if((disk_stats=realloc(disk_stats, (watermark*2 * sizeof(disk_stat_t))))==NULL){
181     disk_stats=disk_ptr;
182     return NULL;
183     }
184    
185     watermark=watermark*2;
186     init_disk_stat(num_disks, watermark-1, disk_stats);
187     }
188    
189     disk_ptr=disk_stats+num_disks;
190 ats 1.31 #ifdef ALLBSD
191 pajs 1.16 if((disk_ptr->device_name=copy_string(disk_ptr->device_name, mp->f_mntfromname))==NULL){
192     return NULL;
193     }
194    
195     if((disk_ptr->fs_type=copy_string(disk_ptr->fs_type, mp->f_fstypename))==NULL){
196     return NULL;
197     }
198    
199     if((disk_ptr->mnt_point=copy_string(disk_ptr->mnt_point, mp->f_mntonname))==NULL){
200     return NULL;
201     }
202    
203     disk_ptr->size = (long long)mp->f_bsize * (long long) mp->f_blocks;
204     disk_ptr->avail = (long long)mp->f_bsize * (long long) mp->f_bavail;
205     disk_ptr->used = (disk_ptr->size) - ((long long)mp->f_bsize * (long long)mp->f_bfree);
206    
207     disk_ptr->total_inodes=(long long)mp->f_files;
208     disk_ptr->free_inodes=(long long)mp->f_ffree;
209     /* Freebsd doesn't have a "available" inodes */
210     disk_ptr->used_inodes=disk_ptr->total_inodes-disk_ptr->free_inodes;
211     #endif
212 pajs 1.9 #ifdef LINUX
213     if((disk_ptr->device_name=copy_string(disk_ptr->device_name, mp->mnt_fsname))==NULL){
214     return NULL;
215     }
216    
217     if((disk_ptr->fs_type=copy_string(disk_ptr->fs_type, mp->mnt_type))==NULL){
218     return NULL;
219     }
220    
221     if((disk_ptr->mnt_point=copy_string(disk_ptr->mnt_point, mp->mnt_dir))==NULL){
222     return NULL;
223     }
224     disk_ptr->size = (long long)fs.f_bsize * (long long)fs.f_blocks;
225     disk_ptr->avail = (long long)fs.f_bsize * (long long)fs.f_bavail;
226     disk_ptr->used = (disk_ptr->size) - ((long long)fs.f_bsize * (long long)fs.f_bfree);
227    
228     disk_ptr->total_inodes=(long long)fs.f_files;
229     disk_ptr->free_inodes=(long long)fs.f_ffree;
230     /* Linux doesn't have a "available" inodes */
231     disk_ptr->used_inodes=disk_ptr->total_inodes-disk_ptr->free_inodes;
232     #endif
233    
234     #ifdef SOLARIS
235 pajs 1.1 /* Memory leak in event of realloc failing */
236     /* Maybe make this char[bigenough] and do strncpy's and put a null in the end?
237 pajs 1.9 * Downside is its a bit hungry for a lot of mounts, as MNT_MAX_SIZE would prob
238     * be upwards of a k each
239     */
240 pajs 1.1 if((disk_ptr->device_name=copy_string(disk_ptr->device_name, mp.mnt_special))==NULL){
241     return NULL;
242     }
243    
244     if((disk_ptr->fs_type=copy_string(disk_ptr->fs_type, mp.mnt_fstype))==NULL){
245     return NULL;
246     }
247    
248     if((disk_ptr->mnt_point=copy_string(disk_ptr->mnt_point, mp.mnt_mountp))==NULL){
249     return NULL;
250     }
251    
252     disk_ptr->size = (long long)fs.f_frsize * (long long)fs.f_blocks;
253     disk_ptr->avail = (long long)fs.f_frsize * (long long)fs.f_bavail;
254     disk_ptr->used = (disk_ptr->size) - ((long long)fs.f_frsize * (long long)fs.f_bfree);
255    
256     disk_ptr->total_inodes=(long long)fs.f_files;
257     disk_ptr->used_inodes=disk_ptr->total_inodes - (long long)fs.f_ffree;
258     disk_ptr->free_inodes=(long long)fs.f_favail;
259 pajs 1.9 #endif
260 pajs 1.1 num_disks++;
261     }
262     }
263    
264     *entries=num_disks;
265    
266     /* If this fails, there is very little i can do about it, so i'll ignore it :) */
267 pajs 1.16 #if defined(LINUX) || defined(SOLARIS)
268 pajs 1.1 fclose(f);
269 pajs 1.16 #endif
270 pajs 1.1
271     return disk_stats;
272    
273     }
274 pajs 1.4 void diskio_stat_init(int start, int end, diskio_stat_t *diskio_stats){
275    
276     for(diskio_stats+=start; start<end; start++){
277     diskio_stats->disk_name=NULL;
278    
279     diskio_stats++;
280     }
281     }
282    
283     diskio_stat_t *diskio_stat_malloc(int needed_entries, int *cur_entries, diskio_stat_t *diskio_stats){
284    
285     if(diskio_stats==NULL){
286    
287     if((diskio_stats=malloc(needed_entries * sizeof(diskio_stat_t)))==NULL){
288     return NULL;
289     }
290     diskio_stat_init(0, needed_entries, diskio_stats);
291     *cur_entries=needed_entries;
292    
293     return diskio_stats;
294     }
295    
296    
297     if(*cur_entries<needed_entries){
298     diskio_stats=realloc(diskio_stats, (sizeof(diskio_stat_t)*needed_entries));
299     if(diskio_stats==NULL){
300     return NULL;
301     }
302     diskio_stat_init(*cur_entries, needed_entries, diskio_stats);
303     *cur_entries=needed_entries;
304     }
305    
306     return diskio_stats;
307     }
308    
309     static diskio_stat_t *diskio_stats=NULL;
310 pajs 1.5 static int num_diskio=0;
311 pajs 1.4
312 ats 1.20 #ifdef LINUX
313     typedef struct {
314     int major;
315     int minor;
316     } partition;
317     #endif
318    
319 tdb 1.3 diskio_stat_t *get_diskio_stats(int *entries){
320 pajs 1.2
321 pajs 1.4 static int sizeof_diskio_stats=0;
322     diskio_stat_t *diskio_stats_ptr;
323    
324 pajs 1.10 #ifdef SOLARIS
325 pajs 1.4 kstat_ctl_t *kc;
326     kstat_t *ksp;
327     kstat_io_t kios;
328 pajs 1.10 #endif
329     #ifdef LINUX
330     FILE *f;
331     char *line_ptr;
332     int major, minor;
333     char dev_letter;
334 ats 1.20 int has_pp_stats = 1;
335     static partition *parts = NULL;
336     static int alloc_parts = 0;
337     int i, n;
338     time_t now;
339 pajs 1.10 #endif
340 pajs 1.17 #ifdef FREEBSD
341 ats 1.21 static struct statinfo stats;
342     static int stats_init = 0;
343 pajs 1.17 int counter;
344     struct device_selection *dev_sel = NULL;
345     int n_selected, n_selections;
346     long sel_gen;
347     struct devstat *dev_ptr;
348 ats 1.31 #endif
349     #ifdef NETBSD
350 ats 1.34 struct disk_sysctl *stats;
351     int num_disks, i;
352     int mib[3];
353     size_t size;
354 pajs 1.17 #endif
355 ats 1.34
356 pajs 1.10 num_diskio=0;
357 ats 1.34
358     #ifdef NETBSD
359     mib[0] = CTL_HW;
360     mib[1] = HW_DISKSTATS;
361     mib[2] = sizeof(struct disk_sysctl);
362    
363     if (sysctl(mib, 3, NULL, &size, NULL, 0) < 0) {
364     return NULL;
365     }
366     num_disks = size / sizeof(struct disk_sysctl);
367    
368     stats = malloc(size);
369     if (stats == NULL) {
370     return NULL;
371     }
372    
373     if (sysctl(mib, 3, stats, &size, NULL, 0) < 0) {
374     return NULL;
375     }
376    
377     for (i = 0; i < num_disks; i++) {
378     u_int64_t rbytes, wbytes;
379    
380     #ifdef HAVE_DK_RBYTES
381     rbytes = stats[i].dk_rbytes;
382     wbytes = stats[i].dk_wbytes;
383     #else
384     /* Before 1.6.1, NetBSD merged reads and writes. */
385     rbytes = wbytes = stats[i].dk_bytes;
386     #endif
387    
388     /* Don't keep stats for disks that have never been used. */
389     if (rbytes == 0 && wbytes == 0) {
390     continue;
391     }
392    
393     diskio_stats = diskio_stat_malloc(num_diskio + 1,
394     &sizeof_diskio_stats,
395     diskio_stats);
396     if (diskio_stats == NULL) {
397     return NULL;
398     }
399     diskio_stats_ptr = diskio_stats + num_diskio;
400    
401     diskio_stats_ptr->read_bytes = rbytes;
402     diskio_stats_ptr->write_bytes = wbytes;
403     if (diskio_stats_ptr->disk_name != NULL) {
404     free(diskio_stats_ptr->disk_name);
405     }
406     diskio_stats_ptr->disk_name = strdup(stats[i].dk_name);
407     diskio_stats_ptr->systime = time(NULL);
408    
409     num_diskio++;
410     }
411    
412     free(stats);
413     #endif
414 pajs 1.4
415 pajs 1.17 #ifdef FREEBSD
416 ats 1.21 if (!stats_init) {
417     stats.dinfo=malloc(sizeof(struct devinfo));
418 ats 1.33 if(stats.dinfo==NULL) return NULL;
419 tdb 1.25 bzero(stats.dinfo, sizeof(struct devinfo));
420 ats 1.21 stats_init = 1;
421     }
422 pajs 1.28 #ifdef FREEBSD5
423     if ((devstat_getdevs(NULL, &stats)) < 0) return NULL;
424 ats 1.29 /* Not aware of a get all devices, so i said 999. If we ever
425     * find a machine with more than 999 disks, then i'll change
426     * this number :)
427     */
428 pajs 1.28 if (devstat_selectdevs(&dev_sel, &n_selected, &n_selections, &sel_gen, stats.dinfo->generation, stats.dinfo->devices, stats.dinfo->numdevs, NULL, 0, NULL, 0, DS_SELECT_ONLY, 999, 1) < 0) return NULL;
429     #else
430 pajs 1.17 if ((getdevs(&stats)) < 0) return NULL;
431     /* Not aware of a get all devices, so i said 999. If we ever
432     * find a machine with more than 999 disks, then i'll change
433     * this number :)
434     */
435     if (selectdevs(&dev_sel, &n_selected, &n_selections, &sel_gen, stats.dinfo->generation, stats.dinfo->devices, stats.dinfo->numdevs, NULL, 0, NULL, 0, DS_SELECT_ONLY, 999, 1) < 0) return NULL;
436 pajs 1.27 #endif
437 pajs 1.17
438     for(counter=0;counter<stats.dinfo->numdevs;counter++){
439     dev_ptr=&stats.dinfo->devices[dev_sel[counter].position];
440    
441     /* Throw away devices that have done nothing, ever.. Eg "odd"
442     * devices.. like mem, proc.. and also doesn't report floppy
443     * drives etc unless they are doing stuff :)
444     */
445 pajs 1.27 #ifdef FREEBSD5
446     if((dev_ptr->bytes[DEVSTAT_READ]==0) && (dev_ptr->bytes[DEVSTAT_WRITE]==0)) continue;
447     #else
448 pajs 1.17 if((dev_ptr->bytes_read==0) && (dev_ptr->bytes_written==0)) continue;
449 pajs 1.27 #endif
450 pajs 1.17 if((diskio_stats=diskio_stat_malloc(num_diskio+1, &sizeof_diskio_stats, diskio_stats))==NULL){
451     return NULL;
452     }
453     diskio_stats_ptr=diskio_stats+num_diskio;
454 pajs 1.27
455     #ifdef FREEBSD5
456     diskio_stats_ptr->read_bytes=dev_ptr->bytes[DEVSTAT_READ];
457     diskio_stats_ptr->write_bytes=dev_ptr->bytes[DEVSTAT_WRITE];
458     #else
459 pajs 1.17 diskio_stats_ptr->read_bytes=dev_ptr->bytes_read;
460     diskio_stats_ptr->write_bytes=dev_ptr->bytes_written;
461 pajs 1.27 #endif
462 pajs 1.17 if(diskio_stats_ptr->disk_name!=NULL) free(diskio_stats_ptr->disk_name);
463     asprintf((&diskio_stats_ptr->disk_name), "%s%d", dev_ptr->device_name, dev_ptr->unit_number);
464     diskio_stats_ptr->systime=time(NULL);
465    
466     num_diskio++;
467     }
468     free(dev_sel);
469    
470     #endif
471 pajs 1.10 #ifdef SOLARIS
472 pajs 1.4 if ((kc = kstat_open()) == NULL) {
473     return NULL;
474     }
475    
476     for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
477     if (!strcmp(ksp->ks_class, "disk")) {
478    
479     if(ksp->ks_type != KSTAT_TYPE_IO) continue;
480 pajs 1.5 /* We dont want metadevices appearins as num_diskio */
481 pajs 1.4 if(strcmp(ksp->ks_module, "md")==0) continue;
482     if((kstat_read(kc, ksp, &kios))==-1){
483     }
484    
485 pajs 1.5 if((diskio_stats=diskio_stat_malloc(num_diskio+1, &sizeof_diskio_stats, diskio_stats))==NULL){
486 pajs 1.4 kstat_close(kc);
487     return NULL;
488     }
489 pajs 1.5 diskio_stats_ptr=diskio_stats+num_diskio;
490 pajs 1.4
491     diskio_stats_ptr->read_bytes=kios.nread;
492    
493     diskio_stats_ptr->write_bytes=kios.nwritten;
494    
495     if(diskio_stats_ptr->disk_name!=NULL) free(diskio_stats_ptr->disk_name);
496    
497 tdb 1.26 diskio_stats_ptr->disk_name=strdup(ksp->ks_name);
498 pajs 1.14 diskio_stats_ptr->systime=time(NULL);
499 pajs 1.5 num_diskio++;
500 pajs 1.4 }
501     }
502    
503     kstat_close(kc);
504 pajs 1.10 #endif
505 pajs 1.4
506 pajs 1.10 #ifdef LINUX
507 ats 1.20 num_diskio = 0;
508     n = 0;
509 pajs 1.10
510 ats 1.20 /* Read /proc/partitions to find what devices exist. Recent 2.4 kernels
511     have statistics in here too, so we can use those directly. */
512 pajs 1.10
513 ats 1.20 f = fopen("/proc/partitions", "r");
514     if (f == NULL) goto out;
515     now = time(NULL);
516    
517     while ((line_ptr = f_read_line(f, "")) != NULL) {
518     char name[20];
519     char *s;
520     long long rsect, wsect;
521    
522     int nr = sscanf(line_ptr,
523     " %d %d %*d %19s %*d %*d %lld %*d %*d %*d %lld",
524     &major, &minor, name, &rsect, &wsect);
525     if (nr < 3) continue;
526     if (nr < 5) {
527     has_pp_stats = 0;
528     rsect = 0;
529     wsect = 0;
530     }
531    
532     /* Skip device names ending in numbers, since they're
533     partitions. */
534     s = name;
535     while (*s != '\0') s++;
536     --s;
537     if (*s >= '0' && *s <= '9') continue;
538    
539     diskio_stats = diskio_stat_malloc(n + 1, &sizeof_diskio_stats,
540     diskio_stats);
541     if (diskio_stats == NULL) goto out;
542     if (n >= alloc_parts) {
543     alloc_parts += 16;
544     parts = realloc(parts, alloc_parts * sizeof *parts);
545     if (parts == NULL) {
546     alloc_parts = 0;
547     goto out;
548     }
549 pajs 1.11 }
550 pajs 1.12
551 ats 1.20 if (diskio_stats[n].disk_name != NULL)
552     free(diskio_stats[n].disk_name);
553     diskio_stats[n].disk_name = strdup(name);
554     diskio_stats[n].read_bytes = rsect * 512;
555     diskio_stats[n].write_bytes = wsect * 512;
556     diskio_stats[n].systime = now;
557     parts[n].major = major;
558     parts[n].minor = minor;
559 pajs 1.10
560 ats 1.20 n++;
561     }
562 pajs 1.10
563 ats 1.20 if (!has_pp_stats) {
564     /* This is an older kernel without stats in /proc/partitions.
565     Read what we can from /proc/stat instead. */
566    
567     f = fopen("/proc/stat", "r");
568     if (f == NULL) goto out;
569     now = time(NULL);
570    
571     line_ptr = f_read_line(f, "disk_io:");
572     if (line_ptr == NULL) goto out;
573    
574     while((line_ptr=strchr(line_ptr, ' '))!=NULL){
575     long long rsect, wsect;
576    
577     if (*++line_ptr == '\0') break;
578    
579     if((sscanf(line_ptr,
580     "(%d,%d):(%*d, %*d, %lld, %*d, %lld)",
581     &major, &minor, &rsect, &wsect)) != 4) {
582     continue;
583     }
584 pajs 1.10
585 ats 1.20 /* Find the corresponding device from earlier.
586     Just to add to the fun, "minor" is actually the disk
587     number, not the device minor, so we need to figure
588     out the real minor number based on the major!
589     This list is not exhaustive; if you're running
590     an older kernel you probably don't have fancy
591     I2O hardware anyway... */
592     switch (major) {
593     case 3:
594     case 21:
595 pajs 1.10 case 22:
596 ats 1.20 case 33:
597     case 34:
598     case 36:
599     case 56:
600     case 57:
601     case 88:
602     case 89:
603     case 90:
604     case 91:
605     minor *= 64;
606 pajs 1.11 break;
607 ats 1.20 case 9:
608     case 43:
609 pajs 1.11 break;
610 pajs 1.10 default:
611 ats 1.20 minor *= 16;
612 pajs 1.11 break;
613 ats 1.20 }
614     for (i = 0; i < n; i++) {
615     if (major == parts[i].major
616     && minor == parts[i].minor)
617     break;
618     }
619     if (i == n) continue;
620    
621     /* We read the number of blocks. Blocks are stored in
622     512 bytes */
623     diskio_stats[i].read_bytes = rsect * 512;
624     diskio_stats[i].write_bytes = wsect * 512;
625     diskio_stats[i].systime = now;
626 pajs 1.10 }
627     }
628 pajs 1.16
629 ats 1.20 num_diskio = n;
630     out:
631     if (f != NULL) fclose(f);
632 pajs 1.10
633     #endif
634 pajs 1.5 *entries=num_diskio;
635 pajs 1.4
636     return diskio_stats;
637 pajs 1.5 }
638    
639 pajs 1.6 diskio_stat_t *get_diskio_stats_diff(int *entries){
640 pajs 1.5 static diskio_stat_t *diskio_stats_diff=NULL;
641     static int sizeof_diskio_stats_diff=0;
642     diskio_stat_t *diskio_stats_diff_ptr, *diskio_stats_ptr;
643     int disks, x, y;
644    
645     if(diskio_stats==NULL){
646     diskio_stats_ptr=get_diskio_stats(&disks);
647     *entries=disks;
648     return diskio_stats_ptr;
649     }
650    
651     diskio_stats_diff=diskio_stat_malloc(num_diskio, &sizeof_diskio_stats_diff, diskio_stats_diff);
652     if(diskio_stats_diff==NULL){
653     return NULL;
654     }
655    
656     diskio_stats_diff_ptr=diskio_stats_diff;
657     diskio_stats_ptr=diskio_stats;
658    
659     for(disks=0;disks<num_diskio;disks++){
660     if(diskio_stats_diff_ptr->disk_name!=NULL){
661     free(diskio_stats_diff_ptr->disk_name);
662     }
663     diskio_stats_diff_ptr->disk_name=strdup(diskio_stats_ptr->disk_name);
664     diskio_stats_diff_ptr->read_bytes=diskio_stats_ptr->read_bytes;
665     diskio_stats_diff_ptr->write_bytes=diskio_stats_ptr->write_bytes;
666     diskio_stats_diff_ptr->systime=diskio_stats_ptr->systime;
667    
668     diskio_stats_diff_ptr++;
669     diskio_stats_ptr++;
670     }
671    
672     diskio_stats_ptr=get_diskio_stats(&disks);
673     diskio_stats_diff_ptr=diskio_stats_diff;
674    
675     for(x=0;x<sizeof_diskio_stats_diff;x++){
676    
677     if((strcmp(diskio_stats_diff_ptr->disk_name, diskio_stats_ptr->disk_name))==0){
678     diskio_stats_diff_ptr->read_bytes=diskio_stats_ptr->read_bytes-diskio_stats_diff_ptr->read_bytes;
679     diskio_stats_diff_ptr->write_bytes=diskio_stats_ptr->write_bytes-diskio_stats_diff_ptr->write_bytes;
680     diskio_stats_diff_ptr->systime=diskio_stats_ptr->systime-diskio_stats_diff_ptr->systime;
681     }else{
682     diskio_stats_ptr=diskio_stats;
683     for(y=0;y<disks;y++){
684     if((strcmp(diskio_stats_diff_ptr->disk_name, diskio_stats_ptr->disk_name))==0){
685     diskio_stats_diff_ptr->read_bytes=diskio_stats_ptr->read_bytes-diskio_stats_diff_ptr->read_bytes;
686     diskio_stats_diff_ptr->write_bytes=diskio_stats_ptr->write_bytes-diskio_stats_diff_ptr->write_bytes;
687     diskio_stats_diff_ptr->systime=diskio_stats_ptr->systime-diskio_stats_diff_ptr->systime;
688    
689     break;
690     }
691    
692     diskio_stats_ptr++;
693     }
694     }
695    
696     diskio_stats_ptr++;
697     diskio_stats_diff_ptr++;
698    
699     }
700 pajs 1.8
701     *entries=sizeof_diskio_stats_diff;
702 pajs 1.5 return diskio_stats_diff;
703 pajs 1.2 }