ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/disk_stats.c
Revision: 1.32
Committed: Sun Oct 19 11:15:30 2003 UTC (20 years, 7 months ago) by ats
Content type: text/plain
Branch: MAIN
Changes since 1.31: +5 -1 lines
Log Message:
Update the Linux VALID_FS_TYPES list based on the writable disk-based
filesystems in 2.4.22 (plus xfs and jfs).

File Contents

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