ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/disk_stats.c
Revision: 1.35
Committed: Sun Oct 19 21:06:55 2003 UTC (20 years, 6 months ago) by ats
Content type: text/plain
Branch: MAIN
Changes since 1.34: +3 -1 lines
Log Message:
Update VALID_FS_TYPES for NetBSD.

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