ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/disk_stats.c
Revision: 1.41
Committed: Mon Nov 10 23:32:59 2003 UTC (20 years, 6 months ago) by ats
Content type: text/plain
Branch: MAIN
Changes since 1.40: +16 -23 lines
Log Message:
Factor out duplicated code that checks for valid FS types.

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