ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/tools.c
Revision: 1.16
Committed: Thu Nov 20 12:13:12 2003 UTC (20 years, 5 months ago) by tdb
Content type: text/plain
Branch: MAIN
Changes since 1.15: +2 -6 lines
Log Message:
Turn on the solaris disk mapping code. Fix some minor bugs, and remove
some debugging code.

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