[legal] seed the copyright headers
[platform/upstream/multipath-tools.git] / libmultipath / config.c
1 /*
2  * Copyright (c) 2004, 2005 Christophe Varoqui
3  * Copyright (c) 2005 Benjamin Marzinski, Redhat
4  * Copyright (c) 2005 Edward Goggin, EMC
5  */
6 #include <stdio.h>
7 #include <string.h>
8
9 #include "regex.h"
10 #include "memory.h"
11 #include "util.h"
12 #include "debug.h"
13 #include "parser.h"
14 #include "dict.h"
15 #include "hwtable.h"
16 #include "vector.h"
17 #include "blacklist.h"
18 #include "defaults.h"
19 #include "config.h"
20
21 #include "../libcheckers/checkers.h"
22
23 struct hwentry *
24 find_hwe (vector hwtable, char * vendor, char * product)
25 {
26         int i;
27         struct hwentry *hwe, *ret = NULL;
28         regex_t vre, pre;
29
30         vector_foreach_slot (hwtable, hwe, i) {
31                 if (regcomp(&vre, hwe->vendor, REG_EXTENDED|REG_NOSUB))
32                         break;
33                 if (regcomp(&pre, hwe->product, REG_EXTENDED|REG_NOSUB)) {
34                         regfree(&vre);
35                         break;
36                 }
37                 if (!regexec(&vre, vendor, 0, NULL, 0) &&
38                     !regexec(&pre, product, 0, NULL, 0))
39                         ret = hwe;
40                 
41                 regfree(&pre);
42                 regfree(&vre);
43
44                 if (ret)
45                         break;
46         }
47         return ret;
48 }
49
50 extern struct mpentry *
51 find_mpe (char * wwid)
52 {
53         int i;
54         struct mpentry * mpe;
55
56         if (!wwid)
57                 return NULL;
58
59         vector_foreach_slot (conf->mptable, mpe, i)
60                 if (mpe->wwid && !strcmp(mpe->wwid, wwid))
61                         return mpe;
62
63         return NULL;
64 }
65
66 extern char *
67 get_mpe_wwid (char * alias)
68 {
69         int i;
70         struct mpentry * mpe;
71
72         if (!alias)
73                 return NULL;
74
75         vector_foreach_slot (conf->mptable, mpe, i)
76                 if (mpe->alias && strcmp(mpe->alias, alias) == 0)
77                         return mpe->wwid;
78
79         return NULL;
80 }
81
82 void
83 free_hwe (struct hwentry * hwe)
84 {
85         if (!hwe)
86                 return;
87
88         if (hwe->vendor)
89                 FREE(hwe->vendor);
90
91         if (hwe->product)
92                 FREE(hwe->product);
93
94         if (hwe->selector)
95                 FREE(hwe->selector);
96
97         if (hwe->getuid)
98                 FREE(hwe->getuid);
99
100         if (hwe->getprio)
101                 FREE(hwe->getprio);
102
103         if (hwe->features)
104                 FREE(hwe->features);
105
106         if (hwe->hwhandler)
107                 FREE(hwe->hwhandler);
108
109         FREE(hwe);
110 }
111
112 void
113 free_hwtable (vector hwtable)
114 {
115         int i;
116         struct hwentry * hwe;
117
118         if (!hwtable)
119                 return;
120
121         vector_foreach_slot (hwtable, hwe, i)
122                 free_hwe(hwe);
123
124         vector_free(hwtable);
125 }
126
127 void
128 free_mpe (struct mpentry * mpe)
129 {
130         if (!mpe)
131                 return;
132
133         if (mpe->wwid)
134                 FREE(mpe->wwid);
135
136         if (mpe->selector)
137                 FREE(mpe->selector);
138
139         if (mpe->getuid)
140                 FREE(mpe->getuid);
141
142         if (mpe->alias)
143                 FREE(mpe->alias);
144
145         FREE(mpe);
146 }
147
148 void
149 free_mptable (vector mptable)
150 {
151         int i;
152         struct mpentry * mpe;
153
154         if (!mptable)
155                 return;
156
157         vector_foreach_slot (mptable, mpe, i)
158                 free_mpe(mpe);
159
160         vector_free(mptable);
161 }
162
163 struct mpentry *
164 alloc_mpe (void)
165 {
166         struct mpentry * mpe = (struct mpentry *)
167                                 MALLOC(sizeof(struct mpentry));
168
169         return mpe;
170 }
171
172 static struct hwentry *
173 alloc_hwe (void)
174 {
175         struct hwentry * hwe = (struct hwentry *)
176                                 MALLOC(sizeof(struct hwentry));
177
178         return hwe;
179 }
180
181 static char *
182 set_param_str(char * str)
183 {
184         char * dst;
185         int len;
186
187         if (!str)
188                 return NULL;
189
190         len = strlen(str);
191
192         if (!len)
193                 return NULL;
194
195         dst = (char *)MALLOC(len + 1);
196
197         if (!dst)
198                 return NULL;
199
200         strcpy(dst, str);
201         return dst;
202 }
203
204 static int
205 dup_hwe (vector hwtable, char * vendor, char * product)
206 {
207         struct hwentry * hwe = find_hwe(hwtable, vendor, product);
208
209         if (hwe)
210                 return 1;
211
212         return 0;
213 }
214
215 int
216 store_hwe (vector hwtable, char * vendor, char * product, int pgp,
217            char * getuid)
218 {
219         struct hwentry * hwe;
220
221         if (dup_hwe(hwtable, vendor, product))
222                 return 0;
223
224         hwe = alloc_hwe();
225
226         if (!hwe)
227                 return 1;
228
229         hwe->vendor = set_param_str(vendor);
230
231         if (!hwe->vendor)
232                 goto out;
233         
234         hwe->product = set_param_str(product);
235
236         if (!hwe->product)
237                 goto out;
238         
239         if (pgp)
240                 hwe->pgpolicy = pgp;
241
242         if (getuid)
243                 hwe->getuid = set_param_str(getuid);
244         else
245                 hwe->getuid = set_default(DEFAULT_GETUID);
246
247         if (!hwe->getuid)
248                 goto out;
249         
250         if (!vector_alloc_slot(hwtable))
251                 goto out;
252
253         vector_set_slot(hwtable, hwe);
254         return 0;
255 out:
256         free_hwe(hwe);
257         return 1;
258 }
259
260 int
261 store_hwe_ext (vector hwtable, char * vendor, char * product, int pgp,
262            char * getuid, char * getprio, char * hwhandler,
263            char * features, char * checker, int pgfailback)
264 {
265         struct hwentry * hwe;
266
267         if (dup_hwe(hwtable, vendor, product))
268                 return 0;
269         
270         hwe = alloc_hwe();
271
272         if (!hwe)
273                 return 1;
274
275         hwe->vendor = set_param_str(vendor);
276
277         if (!hwe->vendor)
278                 goto out;
279         
280         hwe->product = set_param_str(product);
281
282         if (!hwe->product)
283                 goto out;
284         
285         if (pgp)
286                 hwe->pgpolicy = pgp;
287
288         if (getuid)
289                 hwe->getuid = set_param_str(getuid);
290         else
291                 hwe->getuid = set_default(DEFAULT_GETUID);
292
293         if (!hwe->getuid)
294                 goto out;
295         
296         if (getprio)
297                 hwe->getprio = set_param_str(getprio);
298         else
299                 hwe->getprio = NULL;
300
301         if (hwhandler)  
302                 hwe->hwhandler = set_param_str(hwhandler);
303         else
304                 hwe->hwhandler = set_default(DEFAULT_HWHANDLER);
305
306         if (!hwe->hwhandler)
307                 goto out;
308
309         if (features)
310                 hwe->features = set_param_str(features);
311         else
312                 hwe->features = set_default(DEFAULT_FEATURES);
313
314         if (!hwe->features)
315                 goto out;
316
317         if (checker)
318                 hwe->checker_index = get_checker_id(checker);
319         else
320                 hwe->checker_index = get_checker_id(DEFAULT_CHECKER);
321
322         hwe->pgfailback = pgfailback;
323
324         if (!vector_alloc_slot(hwtable))
325                 goto out;
326
327         vector_set_slot(hwtable, hwe);
328         return 0;
329 out:
330         free_hwe(hwe);
331         return 1;
332 }
333
334 struct config *
335 alloc_config (void)
336 {
337         return (struct config *)MALLOC(sizeof(struct config));
338 }
339
340 void
341 free_config (struct config * conf)
342 {
343         if (!conf)
344                 return;
345
346         if (conf->dev)
347                 FREE(conf->dev);
348
349         if (conf->udev_dir)
350                 FREE(conf->udev_dir);
351
352         if (conf->selector)
353                 FREE(conf->selector);
354
355         if (conf->default_getuid)
356                 FREE(conf->default_getuid);
357
358         if (conf->default_getprio)
359                 FREE(conf->default_getprio);
360
361         if (conf->features)
362                 FREE(conf->features);
363
364         if (conf->default_hwhandler)
365                 FREE(conf->default_hwhandler);
366
367         free_blacklist(conf->blist);
368         free_mptable(conf->mptable);
369         free_hwtable(conf->hwtable);
370
371         FREE(conf);
372 }
373
374 int
375 load_config (char * file)
376 {
377         if (!conf)
378                 conf = alloc_config();
379
380         if (!conf)
381                 return 1;
382
383         /*
384          * internal defaults
385          */
386         if (!conf->verbosity)
387                 conf->verbosity = 2;
388
389         conf->dev_type = DEV_NONE;
390         conf->minio = 1000;
391         conf->bindings_file = DEFAULT_BINDINGS_FILE;
392
393         /*
394          * read the config file
395          */
396         if (filepresent(file)) {
397                 if (init_data(file, init_keywords)) {
398                         condlog(0, "error parsing config file");
399                         goto out;
400                 }
401         }
402         
403         /*
404          * fill the voids left in the config file
405          */
406         if (conf->hwtable == NULL) {
407                 conf->hwtable = vector_alloc();
408                 
409                 if (!conf->hwtable)
410                         goto out;
411                 
412         }
413         if (setup_default_hwtable(conf->hwtable))
414                 goto out;
415
416         if (conf->blist == NULL) {
417                 conf->blist = vector_alloc();
418                 
419                 if (!conf->blist)
420                         goto out;
421                 
422                 if (setup_default_blist(conf->blist))
423                         goto out;
424         }
425         if (conf->mptable == NULL) {
426                 conf->mptable = vector_alloc();
427
428                 if (!conf->mptable)
429                         goto out;
430         }
431         if (conf->selector == NULL)
432                 conf->selector = set_default(DEFAULT_SELECTOR);
433
434         if (conf->udev_dir == NULL)
435                 conf->udev_dir = set_default(DEFAULT_UDEVDIR);
436
437         if (conf->default_getuid == NULL)
438                 conf->default_getuid = set_default(DEFAULT_GETUID);
439
440         if (conf->features == NULL)
441                 conf->features = set_default(DEFAULT_FEATURES);
442
443         if (conf->default_hwhandler == NULL)
444                 conf->default_hwhandler = set_default(DEFAULT_HWHANDLER);
445
446         if (!conf->selector  || !conf->udev_dir         ||
447             !conf->default_getuid    || !conf->features ||
448             !conf->default_hwhandler)
449                 goto out;
450
451         if (!conf->default_checker_index)
452                 conf->default_checker_index = READSECTOR0;
453
454         return 0;
455 out:
456         free_config(conf);
457         return 1;
458 }
459