ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/disk_stats.c
Revision: 1.30
Committed: Sun Oct 19 00:10:30 2003 UTC (20 years, 7 months ago) by ats
Content type: text/plain
Branch: MAIN
Changes since 1.29: +1 -0 lines
Log Message:
Fix warning when building on Linux.

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