ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/disk_stats.c
Revision: 1.40
Committed: Mon Nov 10 23:25:45 2003 UTC (20 years, 6 months ago) by ats
Content type: text/plain
Branch: MAIN
Changes since 1.39: +14 -11 lines
Log Message:
Make Cygwin its own platform, rather than defining LINUX. This stops
libstatgrab from trying to fetch stats that Cygwin doesn't have.

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