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

# Content
1 /*
2 * i-scream central monitoring system
3 * http://www.i-scream.org
4 * Copyright (C) 2000-2003 i-scream
5 *
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 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include "statgrab.h"
29
30 #ifdef SOLARIS
31 #include <sys/mnttab.h>
32 #include <sys/statvfs.h>
33 #include <kstat.h>
34 #define VALID_FS_TYPES {"ufs", "tmpfs"}
35 #endif
36
37 #ifdef LINUX
38 #include <time.h>
39 #include <sys/vfs.h>
40 #include <mntent.h>
41 #include "tools.h"
42 #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 #endif
48
49 #ifdef ALLBSD
50 #include <sys/param.h>
51 #include <sys/ucred.h>
52 #include <sys/mount.h>
53 #endif
54 #ifdef FREEBSD
55 #include <sys/dkstat.h>
56 #include <devstat.h>
57 #define VALID_FS_TYPES {"ufs", "mfs"}
58 #endif
59 #ifdef NETBSD
60 #include <sys/param.h>
61 #include <sys/sysctl.h>
62 #include <sys/disk.h>
63 #define VALID_FS_TYPES {"ffs", "mfs", "msdos", "lfs", "adosfs", "ext2fs", \
64 "ntfs"}
65 #endif
66
67 #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 #if defined(LINUX) || defined (SOLARIS)
102 FILE *f;
103 #endif
104
105 disk_stat_t *disk_ptr;
106
107 #ifdef SOLARIS
108 struct mnttab mp;
109 struct statvfs fs;
110 #endif
111 #ifdef LINUX
112 struct mntent *mp;
113 struct statfs fs;
114 #endif
115 #ifdef ALLBSD
116 int nummnt;
117 struct statfs *mp;
118 #endif
119
120 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 #ifdef ALLBSD
129 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 #ifdef LINUX
144 if ((f=setmntent("/etc/mtab", "r" ))==NULL){
145 return NULL;
146 }
147
148 while((mp=getmntent(f))){
149 if((statfs(mp->mnt_dir, &fs)) !=0){
150 continue;
151 }
152
153 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 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 #endif
178
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 #ifdef ALLBSD
193 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 #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 /* 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 * 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 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 #endif
262 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 #if defined(LINUX) || defined(SOLARIS)
270 fclose(f);
271 #endif
272
273 return disk_stats;
274
275 }
276 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 static int num_diskio=0;
313
314 #ifdef LINUX
315 typedef struct {
316 int major;
317 int minor;
318 } partition;
319 #endif
320
321 diskio_stat_t *get_diskio_stats(int *entries){
322
323 static int sizeof_diskio_stats=0;
324 diskio_stat_t *diskio_stats_ptr;
325
326 #ifdef SOLARIS
327 kstat_ctl_t *kc;
328 kstat_t *ksp;
329 kstat_io_t kios;
330 #endif
331 #ifdef LINUX
332 FILE *f;
333 char *line_ptr;
334 int major, minor;
335 char dev_letter;
336 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 #endif
342 #ifdef FREEBSD
343 static struct statinfo stats;
344 static int stats_init = 0;
345 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 #endif
351 #ifdef NETBSD
352 struct disk_sysctl *stats;
353 int num_disks, i;
354 int mib[3];
355 size_t size;
356 #endif
357
358 num_diskio=0;
359
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
417 #ifdef FREEBSD
418 if (!stats_init) {
419 stats.dinfo=malloc(sizeof(struct devinfo));
420 if(stats.dinfo==NULL) return NULL;
421 bzero(stats.dinfo, sizeof(struct devinfo));
422 stats_init = 1;
423 }
424 #ifdef FREEBSD5
425 if ((devstat_getdevs(NULL, &stats)) < 0) return NULL;
426 /* 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 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 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 #endif
439
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 #ifdef FREEBSD5
448 if((dev_ptr->bytes[DEVSTAT_READ]==0) && (dev_ptr->bytes[DEVSTAT_WRITE]==0)) continue;
449 #else
450 if((dev_ptr->bytes_read==0) && (dev_ptr->bytes_written==0)) continue;
451 #endif
452 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
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 diskio_stats_ptr->read_bytes=dev_ptr->bytes_read;
462 diskio_stats_ptr->write_bytes=dev_ptr->bytes_written;
463 #endif
464 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 #ifdef SOLARIS
474 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 /* We dont want metadevices appearins as num_diskio */
483 if(strcmp(ksp->ks_module, "md")==0) continue;
484 if((kstat_read(kc, ksp, &kios))==-1){
485 }
486
487 if((diskio_stats=diskio_stat_malloc(num_diskio+1, &sizeof_diskio_stats, diskio_stats))==NULL){
488 kstat_close(kc);
489 return NULL;
490 }
491 diskio_stats_ptr=diskio_stats+num_diskio;
492
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 diskio_stats_ptr->disk_name=strdup(ksp->ks_name);
500 diskio_stats_ptr->systime=time(NULL);
501 num_diskio++;
502 }
503 }
504
505 kstat_close(kc);
506 #endif
507
508 #ifdef LINUX
509 num_diskio = 0;
510 n = 0;
511
512 /* 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
515 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 }
552
553 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
562 n++;
563 }
564
565 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
587 /* 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 case 22:
598 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 break;
609 case 9:
610 case 43:
611 break;
612 default:
613 minor *= 16;
614 break;
615 }
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 }
629 }
630
631 num_diskio = n;
632 out:
633 if (f != NULL) fclose(f);
634
635 #endif
636 *entries=num_diskio;
637
638 return diskio_stats;
639 }
640
641 diskio_stat_t *get_diskio_stats_diff(int *entries){
642 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
703 *entries=sizeof_diskio_stats_diff;
704 return diskio_stats_diff;
705 }