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

# User Rev Content
1 tdb 1.5 /*
2     * i-scream central monitoring system
3 tdb 1.6 * http://www.i-scream.org
4     * Copyright (C) 2000-2003 i-scream
5 tdb 1.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 pajs 1.1 #include <stdio.h>
26     #include <string.h>
27 pajs 1.3 #include <stdlib.h>
28     #include <sys/types.h>
29     #include <regex.h>
30 ats 1.9 #ifdef ALLBSD
31 ats 1.8 #include <fcntl.h>
32     #include <kvm.h>
33     #endif
34 ats 1.9 #ifdef NETBSD
35     #include <uvm/uvm_extern.h>
36     #endif
37 pajs 1.1
38 ats 1.7 #include "tools.h"
39    
40 pajs 1.14 #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 pajs 1.1 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 pajs 1.2 while((fgets(line, sizeof(line), f))!=NULL){
234 pajs 1.1 if(strncmp(string, line, strlen(string))==0){
235     return line;
236     }
237     }
238    
239     return NULL;
240 pajs 1.3 }
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 ats 1.7
252 pajs 1.14
253    
254 ats 1.13 #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 pajs 1.3 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 ats 1.8 }
283    
284 ats 1.9 #ifdef ALLBSD
285 ats 1.8 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 pajs 1.1 }
295 pajs 1.4 #endif
296 ats 1.9
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 pajs 1.10 int statgrab_init(){
327 pajs 1.11 #ifdef ALLBSD
328     {
329     kvm_t *kvmd = get_kvm();
330     if (kvmd == NULL) return 1;
331     }
332 pajs 1.10 #endif
333     #ifdef NETBSD
334 pajs 1.11 {
335     struct uvmexp *uvm = get_uvmexp();
336     if (uvm == NULL) return 1;
337     }
338 pajs 1.14 #endif
339     #ifdef SOLARIS
340     build_mapping();
341 pajs 1.10 #endif
342     return 0;
343     }