ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/disk_stats.c
Revision: 1.31
Committed: Sun Oct 19 02:03:02 2003 UTC (20 years, 7 months ago) by ats
Content type: text/plain
Branch: MAIN
Changes since 1.30: +13 -5 lines
Log Message:
Initial support for NetBSD. This adds NetBSD support for everything
except diskio stats (since they're even more disturbingly complex to get
at on NetBSD than the three OSs we already support). Tested against
NetBSD 1.6 on i386.

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