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