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