ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/disk_stats.c
Revision: 1.5
Committed: Sun Feb 23 22:58:08 2003 UTC (21 years, 2 months ago) by pajs
Content type: text/plain
Branch: MAIN
Changes since 1.4: +73 -10 lines
Log Message:
Added a diff diskio_stats and fixed a bug. This is the last thing needed
for the solaris version of the new libstatgrab, bar bug fixes.

File Contents

# Content
1 /*
2 * i-scream central monitoring system
3 * http://www.i-scream.org.uk
4 * Copyright (C) 2000-2002 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 "statgrab.h"
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include "ukcprog.h"
29 #include <string.h>
30
31 #ifdef SOLARIS
32 #include <sys/mnttab.h>
33 #include <sys/types.h>
34 #include <sys/statvfs.h>
35 #include <kstat.h>
36
37 #define VALID_FS_TYPES {"ufs", "tmpfs"}
38
39 #endif
40
41 #define START_VAL 1
42
43 char *copy_string(char *orig_ptr, const char *newtext){
44
45 /* Maybe free if not NULL, and strdup rather than realloc and strcpy? */
46 orig_ptr=realloc(orig_ptr, (1+strlen(newtext)));
47 if(orig_ptr==NULL){
48 return NULL;
49 }
50 strcpy(orig_ptr, newtext);
51
52 return orig_ptr;
53 }
54
55
56 void init_disk_stat(int start, int end, disk_stat_t *disk_stats){
57
58 for(disk_stats+=start; start<=end; start++){
59 disk_stats->device_name=NULL;
60 disk_stats->fs_type=NULL;
61 disk_stats->mnt_point=NULL;
62
63 disk_stats++;
64 }
65 }
66
67 disk_stat_t *get_disk_stats(int *entries){
68
69 static disk_stat_t *disk_stats;
70 static int watermark=-1;
71
72 char *fs_types[] = VALID_FS_TYPES;
73 int x, valid_type;
74
75 int num_disks=0;
76 struct mnttab mp;
77 struct statvfs fs;
78 FILE *f;
79
80 disk_stat_t *disk_ptr;
81
82 if(watermark==-1){
83 disk_stats=malloc(START_VAL * sizeof(disk_stat_t));
84 if(disk_stats==NULL){
85 return NULL;
86 }
87 watermark=START_VAL;
88 init_disk_stat(0, watermark-1, disk_stats);
89 }
90
91
92 if ((f=fopen("/etc/mnttab", "r" ))==NULL){
93 return NULL;
94 }
95 while((getmntent(f, &mp)) == 0){
96 if ((statvfs(mp.mnt_mountp, &fs)) !=0){
97 continue;
98 }
99
100 valid_type=0;
101 for(x=0;x<((sizeof(fs_types))/(sizeof(char*)));x++){
102 if(strcmp(mp.mnt_fstype, fs_types[x]) ==0){
103 valid_type=1;
104 break;
105 }
106 }
107
108 if(valid_type){
109 if(num_disks>watermark-1){
110 disk_ptr=disk_stats;
111 if((disk_stats=realloc(disk_stats, (watermark*2 * sizeof(disk_stat_t))))==NULL){
112 disk_stats=disk_ptr;
113 return NULL;
114 }
115
116 watermark=watermark*2;
117 init_disk_stat(num_disks, watermark-1, disk_stats);
118 }
119
120 disk_ptr=disk_stats+num_disks;
121
122 /* Memory leak in event of realloc failing */
123 /* Maybe make this char[bigenough] and do strncpy's and put a null in the end?
124 Downside is its a bit hungry for a lot of mounts, as MNT_MAX_SIZE woul prob be upwards
125 of a k each */
126 if((disk_ptr->device_name=copy_string(disk_ptr->device_name, mp.mnt_special))==NULL){
127 return NULL;
128 }
129
130 if((disk_ptr->fs_type=copy_string(disk_ptr->fs_type, mp.mnt_fstype))==NULL){
131 return NULL;
132 }
133
134 if((disk_ptr->mnt_point=copy_string(disk_ptr->mnt_point, mp.mnt_mountp))==NULL){
135 return NULL;
136 }
137
138 disk_ptr->size = (long long)fs.f_frsize * (long long)fs.f_blocks;
139 disk_ptr->avail = (long long)fs.f_frsize * (long long)fs.f_bavail;
140 disk_ptr->used = (disk_ptr->size) - ((long long)fs.f_frsize * (long long)fs.f_bfree);
141
142 disk_ptr->total_inodes=(long long)fs.f_files;
143 disk_ptr->used_inodes=disk_ptr->total_inodes - (long long)fs.f_ffree;
144 disk_ptr->free_inodes=(long long)fs.f_favail;
145
146 num_disks++;
147 }
148 }
149
150 *entries=num_disks;
151
152 /* If this fails, there is very little i can do about it, so i'll ignore it :) */
153 fclose(f);
154
155 return disk_stats;
156
157 }
158
159 void diskio_stat_init(int start, int end, diskio_stat_t *diskio_stats){
160
161 for(diskio_stats+=start; start<end; start++){
162 diskio_stats->disk_name=NULL;
163
164 diskio_stats++;
165 }
166 }
167
168 diskio_stat_t *diskio_stat_malloc(int needed_entries, int *cur_entries, diskio_stat_t *diskio_stats){
169
170 if(diskio_stats==NULL){
171
172 if((diskio_stats=malloc(needed_entries * sizeof(diskio_stat_t)))==NULL){
173 return NULL;
174 }
175 diskio_stat_init(0, needed_entries, diskio_stats);
176 *cur_entries=needed_entries;
177
178 return diskio_stats;
179 }
180
181
182 if(*cur_entries<needed_entries){
183 diskio_stats=realloc(diskio_stats, (sizeof(diskio_stat_t)*needed_entries));
184 if(diskio_stats==NULL){
185 return NULL;
186 }
187 diskio_stat_init(*cur_entries, needed_entries, diskio_stats);
188 *cur_entries=needed_entries;
189 }
190
191 return diskio_stats;
192 }
193
194 static diskio_stat_t *diskio_stats=NULL;
195 static int num_diskio=0;
196
197 diskio_stat_t *get_diskio_stats(int *entries){
198
199 static int sizeof_diskio_stats=0;
200 diskio_stat_t *diskio_stats_ptr;
201
202 kstat_ctl_t *kc;
203 kstat_t *ksp;
204 kstat_io_t kios;
205
206 if ((kc = kstat_open()) == NULL) {
207 return NULL;
208 }
209
210 num_diskio=0;
211
212 for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
213 if (!strcmp(ksp->ks_class, "disk")) {
214
215 if(ksp->ks_type != KSTAT_TYPE_IO) continue;
216 /* We dont want metadevices appearins as num_diskio */
217 if(strcmp(ksp->ks_module, "md")==0) continue;
218 if((kstat_read(kc, ksp, &kios))==-1){
219 }
220
221 if((diskio_stats=diskio_stat_malloc(num_diskio+1, &sizeof_diskio_stats, diskio_stats))==NULL){
222 kstat_close(kc);
223 return NULL;
224 }
225 diskio_stats_ptr=diskio_stats+num_diskio;
226
227 diskio_stats_ptr->read_bytes=kios.nread;
228
229 diskio_stats_ptr->write_bytes=kios.nwritten;
230
231 if(diskio_stats_ptr->disk_name!=NULL) free(diskio_stats_ptr->disk_name);
232
233 diskio_stats_ptr->disk_name=strdup(ksp->ks_name);
234 num_diskio++;
235 }
236 }
237
238 kstat_close(kc);
239
240 *entries=num_diskio;
241
242 return diskio_stats;
243 }
244
245 diskio_stat_t *get_diskio_stat_diff(int *entries){
246 static diskio_stat_t *diskio_stats_diff=NULL;
247 static int sizeof_diskio_stats_diff=0;
248 diskio_stat_t *diskio_stats_diff_ptr, *diskio_stats_ptr;
249 int disks, x, y;
250
251 if(diskio_stats==NULL){
252 diskio_stats_ptr=get_diskio_stats(&disks);
253 *entries=disks;
254 return diskio_stats_ptr;
255 }
256
257 diskio_stats_diff=diskio_stat_malloc(num_diskio, &sizeof_diskio_stats_diff, diskio_stats_diff);
258 if(diskio_stats_diff==NULL){
259 return NULL;
260 }
261
262 diskio_stats_diff_ptr=diskio_stats_diff;
263 diskio_stats_ptr=diskio_stats;
264
265 for(disks=0;disks<num_diskio;disks++){
266 if(diskio_stats_diff_ptr->disk_name!=NULL){
267 free(diskio_stats_diff_ptr->disk_name);
268 }
269 diskio_stats_diff_ptr->disk_name=strdup(diskio_stats_ptr->disk_name);
270 diskio_stats_diff_ptr->read_bytes=diskio_stats_ptr->read_bytes;
271 diskio_stats_diff_ptr->write_bytes=diskio_stats_ptr->write_bytes;
272 diskio_stats_diff_ptr->systime=diskio_stats_ptr->systime;
273
274 diskio_stats_diff_ptr++;
275 diskio_stats_ptr++;
276 }
277
278 diskio_stats_ptr=get_diskio_stats(&disks);
279 diskio_stats_diff_ptr=diskio_stats_diff;
280
281 for(x=0;x<sizeof_diskio_stats_diff;x++){
282
283 if((strcmp(diskio_stats_diff_ptr->disk_name, diskio_stats_ptr->disk_name))==0){
284 diskio_stats_diff_ptr->read_bytes=diskio_stats_ptr->read_bytes-diskio_stats_diff_ptr->read_bytes;
285 diskio_stats_diff_ptr->write_bytes=diskio_stats_ptr->write_bytes-diskio_stats_diff_ptr->write_bytes;
286 diskio_stats_diff_ptr->systime=diskio_stats_ptr->systime-diskio_stats_diff_ptr->systime;
287 }else{
288 diskio_stats_ptr=diskio_stats;
289 for(y=0;y<disks;y++){
290 if((strcmp(diskio_stats_diff_ptr->disk_name, diskio_stats_ptr->disk_name))==0){
291 diskio_stats_diff_ptr->read_bytes=diskio_stats_ptr->read_bytes-diskio_stats_diff_ptr->read_bytes;
292 diskio_stats_diff_ptr->write_bytes=diskio_stats_ptr->write_bytes-diskio_stats_diff_ptr->write_bytes;
293 diskio_stats_diff_ptr->systime=diskio_stats_ptr->systime-diskio_stats_diff_ptr->systime;
294
295 break;
296 }
297
298 diskio_stats_ptr++;
299 }
300 }
301
302 diskio_stats_ptr++;
303 diskio_stats_diff_ptr++;
304
305 }
306
307 return diskio_stats_diff;
308 }