ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/disk_stats.c
Revision: 1.29
Committed: Sat Oct 18 22:16:44 2003 UTC (20 years, 7 months ago) by ats
Content type: text/plain
Branch: MAIN
Changes since 1.28: +4 -1 lines
Log Message:
Fix a little bit of slightly-confused comment formatting.

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