ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/tools.c
Revision: 1.14
Committed: Thu Nov 13 17:02:46 2003 UTC (20 years, 6 months ago) by pajs
Content type: text/plain
Branch: MAIN
Changes since 1.13: +194 -0 lines
Log Message:
Basic implementation of name mapping for solaris. The code is ugly, mostly
because its initially taken from a sun example, and modified. It needs tiding
somewhat. I'm not sure if tools.c is the right place for this, i guess it could
go in disk_stats.c, but its doing a specific job, and we could right another
mini-program which does the disk mappings.

Comments welcome about the general implementation.

Should we call build_mapping if the user calls get_svr_from_bsd and
build_mapping hasn't been run before? Or should we force them to use the
init function? (Bare in mind, on some systems, to do the mappings correctly
the program will require to be root. (Only ones with a /dev/osa , so everything
with an A1000 for e.g.)

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 <string.h>
27 #include <stdlib.h>
28 #include <sys/types.h>
29 #include <regex.h>
30 #ifdef ALLBSD
31 #include <fcntl.h>
32 #include <kvm.h>
33 #endif
34 #ifdef NETBSD
35 #include <uvm/uvm_extern.h>
36 #endif
37
38 #include "tools.h"
39
40 #ifdef SOLARIS
41 #include <libdevinfo.h>
42 #include <kstat.h>
43 #include <unistd.h>
44 #include <ctype.h>
45 #include <sys/types.h>
46 #include <sys/dkio.h>
47 #include <sys/stat.h>
48 #include <fcntl.h>
49 #include <sys/fcntl.h>
50 #include <dirent.h>
51 #endif
52
53 #ifdef SOLARIS
54 struct map{
55 char *bsd;
56 char *svr;
57
58 struct map *next;
59 };
60 typedef struct map mapping_t;
61
62 static mapping_t *mapping = NULL;
63
64 char *get_svr_from_bsd(char *bsd){
65 mapping_t *map_ptr;
66 for(map_ptr = mapping; map_ptr != NULL; map_ptr = map_ptr->next)
67 if(!strcmp(map_ptr->bsd, bsd)) return map_ptr->svr;
68
69 return bsd;
70 }
71
72 void add_mapping(char *bsd, char *svr){
73 mapping_t *map_ptr;
74 mapping_t *map_end_ptr;
75
76 bsd = strdup(bsd);
77 svr = strdup(svr);
78
79 if (mapping == NULL){
80 printf("New malloc\n");
81 mapping = malloc(sizeof(mapping_t));
82 if (mapping == NULL) return;
83 map_ptr = mapping;
84 }else{
85 /* See if its already been added */
86 for(map_ptr = mapping; map_ptr != NULL; map_ptr = map_ptr->next){
87 if( (!strcmp(map_ptr->bsd, bsd)) || (!strcmp(map_ptr->svr, svr)) ){
88 printf("%s matches %s\n", map_ptr->bsd, bsd);
89 return;
90 }
91 map_end_ptr = map_ptr;
92 }
93
94 /* We've reached end of list and not found the entry.. So we need to malloc
95 * new mapping_t
96 */
97 map_end_ptr->next = malloc(sizeof(mapping_t));
98 printf("Second malloc\n");
99 if (map_end_ptr->next == NULL) return;
100 map_ptr = map_end_ptr->next;
101 }
102
103 printf("Adding %s\n", bsd);
104 map_ptr->next = NULL;
105 map_ptr->bsd = bsd;
106 map_ptr->svr = svr;
107
108 return;
109 }
110
111 char *read_dir(char *disk_path){
112 DIR *dirp;
113 struct dirent *dp;
114 struct stat stbuf;
115 char *svr_name;
116 char current_dir[MAXPATHLEN];
117 char file_name[MAXPATHLEN];
118 char temp_name[MAXPATHLEN];
119 char dir_dname[MAXPATHLEN];
120 char *dsk_dir;
121 int x;
122
123 dsk_dir = "/dev/osa/dev/dsk";
124 strncpy(current_dir, dsk_dir, sizeof current_dir);
125 if ((dirp = opendir(current_dir)) == NULL){
126 dsk_dir = "/dev/dsk";
127 snprintf(current_dir, sizeof current_dir, "%s", dsk_dir);
128 if ((dirp = opendir(current_dir)) == NULL){
129 return NULL;
130 }
131 }
132
133 while ((dp = readdir(dirp)) != NULL){
134 snprintf(temp_name, sizeof temp_name, "../..%s", disk_path);
135 snprintf(dir_dname, sizeof dir_dname, "%s/%s", dsk_dir, dp->d_name);
136 stat(dir_dname,&stbuf);
137
138 if (S_ISBLK(stbuf.st_mode)){
139 x = readlink(dir_dname, file_name, sizeof(file_name));
140 file_name[x] = '\0';
141 if (strcmp(file_name, temp_name) == 0) {
142 svr_name = strdup(dp->d_name);
143 closedir(dirp);
144 return svr_name;
145 }
146 }
147 closedir(dirp);
148 }
149 return NULL;
150 }
151
152
153
154 int get_alias(char *alias){
155 char file[MAXPATHLEN];
156 di_node_t root_node;
157 di_node_t node;
158 di_minor_t minor = DI_MINOR_NIL;
159 char tmpnode[MAXPATHLEN];
160 char *phys_path;
161 char *minor_name;
162 char *value;
163 int instance;
164 if ((root_node = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) {
165 fprintf(stderr, "di_init() failed\n");
166 exit(1);
167 }
168 node = di_drv_first_node(alias, root_node);
169 while (node != DI_NODE_NIL) {
170 if ((minor = di_minor_next(node, DI_MINOR_NIL)) != DI_MINOR_NIL) {
171 instance = di_instance(node);
172 phys_path = di_devfs_path(node);
173 minor_name = di_minor_name(minor);
174 strcpy(tmpnode, alias);
175 sprintf(tmpnode, "%s%d", tmpnode, instance);
176 strcpy(file, "/devices");
177 strcat(file, phys_path);
178 strcat(file, ":");
179 strcat(file, minor_name);
180 value = read_dir(file);
181 if (value != NULL){
182 add_mapping(tmpnode, value);
183 }
184 di_devfs_path_free(phys_path);
185 node = di_drv_next_node(node);
186 }else{
187 node = di_drv_next_node(node);
188 }
189 } /* End of the while loop */
190 di_fini(root_node);
191 return (-1);
192 }
193
194 void build_mapping(){
195 char device_name[512];
196 int x;
197 kstat_ctl_t *kc;
198 kstat_t *ksp;
199 kstat_io_t kios;
200
201 if ((kc = kstat_open()) == NULL) {
202 return NULL;
203 }
204
205 for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
206 if (!strcmp(ksp->ks_class, "disk")) {
207
208 if(ksp->ks_type != KSTAT_TYPE_IO) continue;
209 /* We dont want metadevices appearins as num_diskio */
210 if(strcmp(ksp->ks_module, "md")==0) continue;
211 if((kstat_read(kc, ksp, &kios))==-1) continue;
212 strncpy(device_name, ksp->ks_name, sizeof device_name);
213 for(x=0;x<(sizeof device_name);x++){
214 if( isdigit((int)device_name[x]) ) break;
215 }
216 if(x == sizeof device_name) x--;
217 device_name[x] = '\0';
218 get_alias(device_name);
219 }
220 }
221
222 return;
223 }
224
225 #endif
226
227
228
229 char *f_read_line(FILE *f, const char *string){
230 /* Max line length. 8k should be more than enough */
231 static char line[8192];
232
233 while((fgets(line, sizeof(line), f))!=NULL){
234 if(strncmp(string, line, strlen(string))==0){
235 return line;
236 }
237 }
238
239 return NULL;
240 }
241
242 char *get_string_match(char *line, regmatch_t *match){
243 int len=match->rm_eo - match->rm_so;
244 char *match_string=malloc(len+1);
245
246 match_string=strncpy(match_string, line+match->rm_so, len);
247 match_string[len]='\0';
248
249 return match_string;
250 }
251
252
253
254 #ifndef HAVE_ATOLL
255 static long long atoll(const char *s) {
256 long long value = 0;
257 int isneg = 0;
258
259 while (*s == ' ' || *s == '\t') {
260 s++;
261 }
262 if (*s == '-') {
263 isneg = 1;
264 s++;
265 }
266 while (*s >= '0' && *s <= '9') {
267 value = (10 * value) + (*s - '0');
268 s++;
269 }
270 return (isneg ? -value : value);
271 }
272 #endif
273
274 long long get_ll_match(char *line, regmatch_t *match){
275 char *ptr;
276 long long num;
277
278 ptr=line+match->rm_so;
279 num=atoll(ptr);
280
281 return num;
282 }
283
284 #ifdef ALLBSD
285 kvm_t *get_kvm() {
286 static kvm_t *kvmd = NULL;
287
288 if (kvmd != NULL) {
289 return kvmd;
290 }
291
292 kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, NULL);
293 return kvmd;
294 }
295 #endif
296
297 #ifdef NETBSD
298 struct uvmexp *get_uvmexp() {
299 static u_long addr = 0;
300 static struct uvmexp uvm;
301 kvm_t *kvmd = get_kvm();
302
303 if (kvmd == NULL) {
304 return NULL;
305 }
306
307 if (addr == 0) {
308 struct nlist symbols[] = {
309 { "_uvmexp" },
310 { NULL }
311 };
312
313 if (kvm_nlist(kvmd, symbols) != 0) {
314 return NULL;
315 }
316 addr = symbols[0].n_value;
317 }
318
319 if (kvm_read(kvmd, addr, &uvm, sizeof uvm) != sizeof uvm) {
320 return NULL;
321 }
322 return &uvm;
323 }
324 #endif
325
326 int statgrab_init(){
327 #ifdef ALLBSD
328 {
329 kvm_t *kvmd = get_kvm();
330 if (kvmd == NULL) return 1;
331 }
332 #endif
333 #ifdef NETBSD
334 {
335 struct uvmexp *uvm = get_uvmexp();
336 if (uvm == NULL) return 1;
337 }
338 #endif
339 #ifdef SOLARIS
340 build_mapping();
341 #endif
342 return 0;
343 }