ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/disk_stats.c
Revision: 1.36
Committed: Sun Oct 19 21:12:43 2003 UTC (20 years, 6 months ago) by ats
Content type: text/plain
Branch: MAIN
Changes since 1.35: +2 -1 lines
Log Message:
Update VALID_FS_TYPES for FreeBSD (at least, those that I can see from
a quick look at src/sys).

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