ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/disk_stats.c
Revision: 1.39
Committed: Mon Nov 10 21:07:04 2003 UTC (20 years, 6 months ago) by tdb
Content type: text/plain
Branch: MAIN
Changes since 1.38: +10 -2 lines
Log Message:
Add support for cygwin. This is a bit limited, there's a few things that
can't be retrieved on cygwin such as load averages, diskio, network io,
and process stats. The package compiles and runs, and both saidar and
statgrab work.

Taken from a patch submitted by Ron Arts <raarts@netland.nl>. Thanks Ron!

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