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