ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/disk_stats.c
Revision: 1.26
Committed: Wed Oct 8 09:20:56 2003 UTC (20 years, 7 months ago) by tdb
Content type: text/plain
Branch: MAIN
Changes since 1.25: +1 -151 lines
Log Message:
Unroll Pete's commits for doing drive mappings on Solaris. It doesn't
work right and he wants to start again. Also, we don't want it in the
next release :) This effectively removes revisions 1.22 and 1.23.

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