ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/disk_stats.c
Revision: 1.38
Committed: Fri Oct 24 17:46:44 2003 UTC (20 years, 6 months ago) by ats
Content type: text/plain
Branch: MAIN
Changes since 1.37: +20 -11 lines
Log Message:
Support disk IO statistics on Linux 2.6.
Remove a couple of unused variables.

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 #ifndef LINUX
326 diskio_stat_t *diskio_stats_ptr;
327 #endif
328
329 #ifdef SOLARIS
330 kstat_ctl_t *kc;
331 kstat_t *ksp;
332 kstat_io_t kios;
333 #endif
334 #ifdef LINUX
335 FILE *f;
336 char *line_ptr;
337 int major, minor;
338 int has_pp_stats = 1;
339 static partition *parts = NULL;
340 static int alloc_parts = 0;
341 int i, n;
342 time_t now;
343 const char *format;
344 #endif
345 #ifdef FREEBSD
346 static struct statinfo stats;
347 static int stats_init = 0;
348 int counter;
349 struct device_selection *dev_sel = NULL;
350 int n_selected, n_selections;
351 long sel_gen;
352 struct devstat *dev_ptr;
353 #endif
354 #ifdef NETBSD
355 struct disk_sysctl *stats;
356 int num_disks, i;
357 int mib[3];
358 size_t size;
359 #endif
360
361 num_diskio=0;
362
363 #ifdef NETBSD
364 mib[0] = CTL_HW;
365 mib[1] = HW_DISKSTATS;
366 mib[2] = sizeof(struct disk_sysctl);
367
368 if (sysctl(mib, 3, NULL, &size, NULL, 0) < 0) {
369 return NULL;
370 }
371 num_disks = size / sizeof(struct disk_sysctl);
372
373 stats = malloc(size);
374 if (stats == NULL) {
375 return NULL;
376 }
377
378 if (sysctl(mib, 3, stats, &size, NULL, 0) < 0) {
379 return NULL;
380 }
381
382 for (i = 0; i < num_disks; i++) {
383 u_int64_t rbytes, wbytes;
384
385 #ifdef HAVE_DK_RBYTES
386 rbytes = stats[i].dk_rbytes;
387 wbytes = stats[i].dk_wbytes;
388 #else
389 /* Before 1.7, NetBSD merged reads and writes. */
390 rbytes = wbytes = stats[i].dk_bytes;
391 #endif
392
393 /* Don't keep stats for disks that have never been used. */
394 if (rbytes == 0 && wbytes == 0) {
395 continue;
396 }
397
398 diskio_stats = diskio_stat_malloc(num_diskio + 1,
399 &sizeof_diskio_stats,
400 diskio_stats);
401 if (diskio_stats == NULL) {
402 return NULL;
403 }
404 diskio_stats_ptr = diskio_stats + num_diskio;
405
406 diskio_stats_ptr->read_bytes = rbytes;
407 diskio_stats_ptr->write_bytes = wbytes;
408 if (diskio_stats_ptr->disk_name != NULL) {
409 free(diskio_stats_ptr->disk_name);
410 }
411 diskio_stats_ptr->disk_name = strdup(stats[i].dk_name);
412 diskio_stats_ptr->systime = time(NULL);
413
414 num_diskio++;
415 }
416
417 free(stats);
418 #endif
419
420 #ifdef FREEBSD
421 if (!stats_init) {
422 stats.dinfo=malloc(sizeof(struct devinfo));
423 if(stats.dinfo==NULL) return NULL;
424 bzero(stats.dinfo, sizeof(struct devinfo));
425 stats_init = 1;
426 }
427 #ifdef FREEBSD5
428 if ((devstat_getdevs(NULL, &stats)) < 0) return NULL;
429 /* Not aware of a get all devices, so i said 999. If we ever
430 * find a machine with more than 999 disks, then i'll change
431 * this number :)
432 */
433 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;
434 #else
435 if ((getdevs(&stats)) < 0) return NULL;
436 /* Not aware of a get all devices, so i said 999. If we ever
437 * find a machine with more than 999 disks, then i'll change
438 * this number :)
439 */
440 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;
441 #endif
442
443 for(counter=0;counter<stats.dinfo->numdevs;counter++){
444 dev_ptr=&stats.dinfo->devices[dev_sel[counter].position];
445
446 /* Throw away devices that have done nothing, ever.. Eg "odd"
447 * devices.. like mem, proc.. and also doesn't report floppy
448 * drives etc unless they are doing stuff :)
449 */
450 #ifdef FREEBSD5
451 if((dev_ptr->bytes[DEVSTAT_READ]==0) && (dev_ptr->bytes[DEVSTAT_WRITE]==0)) continue;
452 #else
453 if((dev_ptr->bytes_read==0) && (dev_ptr->bytes_written==0)) continue;
454 #endif
455 if((diskio_stats=diskio_stat_malloc(num_diskio+1, &sizeof_diskio_stats, diskio_stats))==NULL){
456 return NULL;
457 }
458 diskio_stats_ptr=diskio_stats+num_diskio;
459
460 #ifdef FREEBSD5
461 diskio_stats_ptr->read_bytes=dev_ptr->bytes[DEVSTAT_READ];
462 diskio_stats_ptr->write_bytes=dev_ptr->bytes[DEVSTAT_WRITE];
463 #else
464 diskio_stats_ptr->read_bytes=dev_ptr->bytes_read;
465 diskio_stats_ptr->write_bytes=dev_ptr->bytes_written;
466 #endif
467 if(diskio_stats_ptr->disk_name!=NULL) free(diskio_stats_ptr->disk_name);
468 asprintf((&diskio_stats_ptr->disk_name), "%s%d", dev_ptr->device_name, dev_ptr->unit_number);
469 diskio_stats_ptr->systime=time(NULL);
470
471 num_diskio++;
472 }
473 free(dev_sel);
474
475 #endif
476 #ifdef SOLARIS
477 if ((kc = kstat_open()) == NULL) {
478 return NULL;
479 }
480
481 for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
482 if (!strcmp(ksp->ks_class, "disk")) {
483
484 if(ksp->ks_type != KSTAT_TYPE_IO) continue;
485 /* We dont want metadevices appearins as num_diskio */
486 if(strcmp(ksp->ks_module, "md")==0) continue;
487 if((kstat_read(kc, ksp, &kios))==-1){
488 }
489
490 if((diskio_stats=diskio_stat_malloc(num_diskio+1, &sizeof_diskio_stats, diskio_stats))==NULL){
491 kstat_close(kc);
492 return NULL;
493 }
494 diskio_stats_ptr=diskio_stats+num_diskio;
495
496 diskio_stats_ptr->read_bytes=kios.nread;
497
498 diskio_stats_ptr->write_bytes=kios.nwritten;
499
500 if(diskio_stats_ptr->disk_name!=NULL) free(diskio_stats_ptr->disk_name);
501
502 diskio_stats_ptr->disk_name=strdup(ksp->ks_name);
503 diskio_stats_ptr->systime=time(NULL);
504 num_diskio++;
505 }
506 }
507
508 kstat_close(kc);
509 #endif
510
511 #ifdef LINUX
512 num_diskio = 0;
513 n = 0;
514
515 /* Read /proc/partitions to find what devices exist. Recent 2.4 kernels
516 have statistics in here too, so we can use those directly.
517 2.6 kernels have /proc/diskstats instead with almost (but not quite)
518 the same format. */
519
520 f = fopen("/proc/diskstats", "r");
521 format = " %d %d %19s %*d %*d %lld %*d %*d %*d %lld";
522 if (f == NULL) {
523 f = fopen("/proc/partitions", "r");
524 format = " %d %d %*d %19s %*d %*d %lld %*d %*d %*d %lld";
525 }
526 if (f == NULL) goto out;
527 now = time(NULL);
528
529 while ((line_ptr = f_read_line(f, "")) != NULL) {
530 char name[20];
531 char *s;
532 long long rsect, wsect;
533
534 int nr = sscanf(line_ptr, format,
535 &major, &minor, name, &rsect, &wsect);
536 if (nr < 3) continue;
537
538 /* Skip device names ending in numbers, since they're
539 partitions. */
540 s = name;
541 while (*s != '\0') s++;
542 --s;
543 if (*s >= '0' && *s <= '9') continue;
544
545 if (nr < 5) {
546 has_pp_stats = 0;
547 rsect = 0;
548 wsect = 0;
549 }
550
551 diskio_stats = diskio_stat_malloc(n + 1, &sizeof_diskio_stats,
552 diskio_stats);
553 if (diskio_stats == NULL) goto out;
554 if (n >= alloc_parts) {
555 alloc_parts += 16;
556 parts = realloc(parts, alloc_parts * sizeof *parts);
557 if (parts == NULL) {
558 alloc_parts = 0;
559 goto out;
560 }
561 }
562
563 if (diskio_stats[n].disk_name != NULL)
564 free(diskio_stats[n].disk_name);
565 diskio_stats[n].disk_name = strdup(name);
566 diskio_stats[n].read_bytes = rsect * 512;
567 diskio_stats[n].write_bytes = wsect * 512;
568 diskio_stats[n].systime = now;
569 parts[n].major = major;
570 parts[n].minor = minor;
571
572 n++;
573 }
574
575 if (!has_pp_stats) {
576 /* This is an older kernel without stats in /proc/partitions.
577 Read what we can from /proc/stat instead. */
578
579 f = fopen("/proc/stat", "r");
580 if (f == NULL) goto out;
581 now = time(NULL);
582
583 line_ptr = f_read_line(f, "disk_io:");
584 if (line_ptr == NULL) goto out;
585
586 while((line_ptr=strchr(line_ptr, ' '))!=NULL){
587 long long rsect, wsect;
588
589 if (*++line_ptr == '\0') break;
590
591 if((sscanf(line_ptr,
592 "(%d,%d):(%*d, %*d, %lld, %*d, %lld)",
593 &major, &minor, &rsect, &wsect)) != 4) {
594 continue;
595 }
596
597 /* Find the corresponding device from earlier.
598 Just to add to the fun, "minor" is actually the disk
599 number, not the device minor, so we need to figure
600 out the real minor number based on the major!
601 This list is not exhaustive; if you're running
602 an older kernel you probably don't have fancy
603 I2O hardware anyway... */
604 switch (major) {
605 case 3:
606 case 21:
607 case 22:
608 case 33:
609 case 34:
610 case 36:
611 case 56:
612 case 57:
613 case 88:
614 case 89:
615 case 90:
616 case 91:
617 minor *= 64;
618 break;
619 case 9:
620 case 43:
621 break;
622 default:
623 minor *= 16;
624 break;
625 }
626 for (i = 0; i < n; i++) {
627 if (major == parts[i].major
628 && minor == parts[i].minor)
629 break;
630 }
631 if (i == n) continue;
632
633 /* We read the number of blocks. Blocks are stored in
634 512 bytes */
635 diskio_stats[i].read_bytes = rsect * 512;
636 diskio_stats[i].write_bytes = wsect * 512;
637 diskio_stats[i].systime = now;
638 }
639 }
640
641 num_diskio = n;
642 out:
643 if (f != NULL) fclose(f);
644
645 #endif
646 *entries=num_diskio;
647
648 return diskio_stats;
649 }
650
651 diskio_stat_t *get_diskio_stats_diff(int *entries){
652 static diskio_stat_t *diskio_stats_diff=NULL;
653 static int sizeof_diskio_stats_diff=0;
654 diskio_stat_t *diskio_stats_diff_ptr, *diskio_stats_ptr;
655 int disks, x, y;
656
657 if(diskio_stats==NULL){
658 diskio_stats_ptr=get_diskio_stats(&disks);
659 *entries=disks;
660 return diskio_stats_ptr;
661 }
662
663 diskio_stats_diff=diskio_stat_malloc(num_diskio, &sizeof_diskio_stats_diff, diskio_stats_diff);
664 if(diskio_stats_diff==NULL){
665 return NULL;
666 }
667
668 diskio_stats_diff_ptr=diskio_stats_diff;
669 diskio_stats_ptr=diskio_stats;
670
671 for(disks=0;disks<num_diskio;disks++){
672 if(diskio_stats_diff_ptr->disk_name!=NULL){
673 free(diskio_stats_diff_ptr->disk_name);
674 }
675 diskio_stats_diff_ptr->disk_name=strdup(diskio_stats_ptr->disk_name);
676 diskio_stats_diff_ptr->read_bytes=diskio_stats_ptr->read_bytes;
677 diskio_stats_diff_ptr->write_bytes=diskio_stats_ptr->write_bytes;
678 diskio_stats_diff_ptr->systime=diskio_stats_ptr->systime;
679
680 diskio_stats_diff_ptr++;
681 diskio_stats_ptr++;
682 }
683
684 diskio_stats_ptr=get_diskio_stats(&disks);
685 diskio_stats_diff_ptr=diskio_stats_diff;
686
687 for(x=0;x<sizeof_diskio_stats_diff;x++){
688
689 if((strcmp(diskio_stats_diff_ptr->disk_name, diskio_stats_ptr->disk_name))==0){
690 diskio_stats_diff_ptr->read_bytes=diskio_stats_ptr->read_bytes-diskio_stats_diff_ptr->read_bytes;
691 diskio_stats_diff_ptr->write_bytes=diskio_stats_ptr->write_bytes-diskio_stats_diff_ptr->write_bytes;
692 diskio_stats_diff_ptr->systime=diskio_stats_ptr->systime-diskio_stats_diff_ptr->systime;
693 }else{
694 diskio_stats_ptr=diskio_stats;
695 for(y=0;y<disks;y++){
696 if((strcmp(diskio_stats_diff_ptr->disk_name, diskio_stats_ptr->disk_name))==0){
697 diskio_stats_diff_ptr->read_bytes=diskio_stats_ptr->read_bytes-diskio_stats_diff_ptr->read_bytes;
698 diskio_stats_diff_ptr->write_bytes=diskio_stats_ptr->write_bytes-diskio_stats_diff_ptr->write_bytes;
699 diskio_stats_diff_ptr->systime=diskio_stats_ptr->systime-diskio_stats_diff_ptr->systime;
700
701 break;
702 }
703
704 diskio_stats_ptr++;
705 }
706 }
707
708 diskio_stats_ptr++;
709 diskio_stats_diff_ptr++;
710
711 }
712
713 *entries=sizeof_diskio_stats_diff;
714 return diskio_stats_diff;
715 }