2 * Copyright (c) 2004, 2005 Christophe Varoqui
3 * Copyright (c) 2005 Benjamin Marzinski, Redhat
4 * Copyright (c) 2005 Edward Goggin, EMC
20 #include "blacklist.h"
23 #include "devmapper.h"
26 hwe_strmatch (struct hwentry *hwe1, struct hwentry *hwe2)
28 if (hwe1->vendor && hwe2->vendor && strcmp(hwe1->vendor, hwe2->vendor))
31 if (hwe1->product && hwe2->product && strcmp(hwe1->product, hwe2->product))
34 if (hwe1->revision && hwe2->revision && strcmp(hwe1->revision, hwe2->revision))
40 static struct hwentry *
41 find_hwe_strmatch (vector hwtable, struct hwentry *hwe)
44 struct hwentry *tmp, *ret = NULL;
46 vector_foreach_slot (hwtable, tmp, i) {
47 if (hwe_strmatch(tmp, hwe))
56 hwe_regmatch (struct hwentry *hwe1, struct hwentry *hwe2)
58 regex_t vre, pre, rre;
62 regcomp(&vre, hwe1->vendor, REG_EXTENDED|REG_NOSUB))
66 regcomp(&pre, hwe1->product, REG_EXTENDED|REG_NOSUB))
70 regcomp(&rre, hwe1->revision, REG_EXTENDED|REG_NOSUB))
73 if ((!hwe1->vendor || !hwe2->vendor ||
74 !regexec(&vre, hwe2->vendor, 0, NULL, 0)) &&
75 (!hwe1->product || !hwe2->product ||
76 !regexec(&pre, hwe2->product, 0, NULL, 0)) &&
77 (!hwe1->revision || !hwe2->revision ||
78 !regexec(&rre, hwe2->revision, 0, NULL, 0)))
94 find_hwe (vector hwtable, char * vendor, char * product, char * revision)
97 struct hwentry hwe, *tmp, *ret = NULL;
100 hwe.product = product;
101 hwe.revision = revision;
103 * Search backwards here.
104 * User modified entries are attached at the end of
105 * the list, so we have to check them first before
106 * continuing to the generic entries
108 vector_foreach_slot_backwards (hwtable, tmp, i) {
109 if (hwe_regmatch(tmp, &hwe))
117 extern struct mpentry *
118 find_mpe (char * wwid)
121 struct mpentry * mpe;
126 vector_foreach_slot (conf->mptable, mpe, i)
127 if (mpe->wwid && !strcmp(mpe->wwid, wwid))
134 get_mpe_wwid (char * alias)
137 struct mpentry * mpe;
142 vector_foreach_slot (conf->mptable, mpe, i)
143 if (mpe->alias && strcmp(mpe->alias, alias) == 0)
150 free_hwe (struct hwentry * hwe)
164 if (hwe->uid_attribute)
165 FREE(hwe->uid_attribute);
171 FREE(hwe->hwhandler);
176 if (hwe->checker_name)
177 FREE(hwe->checker_name);
180 FREE(hwe->prio_name);
183 FREE(hwe->prio_args);
185 if (hwe->alias_prefix)
186 FREE(hwe->alias_prefix);
189 FREE(hwe->bl_product);
195 free_hwtable (vector hwtable)
198 struct hwentry * hwe;
203 vector_foreach_slot (hwtable, hwe, i)
206 vector_free(hwtable);
210 free_mpe (struct mpentry * mpe)
221 if (mpe->uid_attribute)
222 FREE(mpe->uid_attribute);
228 FREE(mpe->prio_name);
231 FREE(mpe->prio_args);
237 free_mptable (vector mptable)
240 struct mpentry * mpe;
245 vector_foreach_slot (mptable, mpe, i)
248 vector_free(mptable);
254 struct mpentry * mpe = (struct mpentry *)
255 MALLOC(sizeof(struct mpentry));
263 struct hwentry * hwe = (struct hwentry *)
264 MALLOC(sizeof(struct hwentry));
270 set_param_str(char * str)
283 dst = (char *)MALLOC(len + 1);
292 #define merge_str(s) \
293 if (!dst->s && src->s) { \
294 if (!(dst->s = set_param_str(src->s))) \
298 #define merge_num(s) \
299 if (!dst->s && src->s) \
304 merge_hwe (struct hwentry * dst, struct hwentry * src)
309 merge_str(uid_attribute);
311 merge_str(hwhandler);
313 merge_str(checker_name);
314 merge_str(prio_name);
315 merge_str(prio_args);
316 merge_str(alias_prefix);
317 merge_str(bl_product);
319 merge_num(pgfailback);
320 merge_num(rr_weight);
321 merge_num(no_path_retry);
324 merge_num(pg_timeout);
325 merge_num(flush_on_last_del);
326 merge_num(fast_io_fail);
333 store_hwe (vector hwtable, struct hwentry * dhwe)
335 struct hwentry * hwe;
337 if (find_hwe_strmatch(hwtable, dhwe))
340 if (!(hwe = alloc_hwe()))
343 if (!dhwe->vendor || !(hwe->vendor = set_param_str(dhwe->vendor)))
346 if (!dhwe->product || !(hwe->product = set_param_str(dhwe->product)))
349 if (dhwe->revision && !(hwe->revision = set_param_str(dhwe->revision)))
352 if (dhwe->uid_attribute && !(hwe->uid_attribute = set_param_str(dhwe->uid_attribute)))
355 if (dhwe->features && !(hwe->features = set_param_str(dhwe->features)))
358 if (dhwe->hwhandler && !(hwe->hwhandler = set_param_str(dhwe->hwhandler)))
361 if (dhwe->selector && !(hwe->selector = set_param_str(dhwe->selector)))
364 if (dhwe->checker_name && !(hwe->checker_name = set_param_str(dhwe->checker_name)))
367 if (dhwe->prio_name && !(hwe->prio_name = set_param_str(dhwe->prio_name)))
370 if (dhwe->prio_args && !(hwe->prio_args = set_param_str(dhwe->prio_args)))
373 if (dhwe->alias_prefix && !(hwe->alias_prefix = set_param_str(dhwe->alias_prefix)))
376 hwe->pgpolicy = dhwe->pgpolicy;
377 hwe->pgfailback = dhwe->pgfailback;
378 hwe->rr_weight = dhwe->rr_weight;
379 hwe->no_path_retry = dhwe->no_path_retry;
380 hwe->minio = dhwe->minio;
381 hwe->minio_rq = dhwe->minio_rq;
383 if (dhwe->bl_product && !(hwe->bl_product = set_param_str(dhwe->bl_product)))
386 if (!vector_alloc_slot(hwtable))
389 vector_set_slot(hwtable, hwe);
397 factorize_hwtable (vector hw, int n)
399 struct hwentry *hwe1, *hwe2;
402 vector_foreach_slot(hw, hwe1, i) {
406 vector_foreach_slot_after(hw, hwe2, j) {
407 if (hwe_regmatch(hwe1, hwe2))
410 merge_hwe(hwe2, hwe1);
419 return (struct config *)MALLOC(sizeof(struct config));
423 free_config (struct config * conf)
432 udev_unref(conf->udev);
435 FREE(conf->udev_dir);
437 if (conf->multipath_dir)
438 FREE(conf->multipath_dir);
441 FREE(conf->selector);
443 if (conf->uid_attribute)
444 FREE(conf->uid_attribute);
447 FREE(conf->features);
450 FREE(conf->hwhandler);
452 if (conf->bindings_file)
453 FREE(conf->bindings_file);
456 FREE(conf->prio_name);
458 if (conf->alias_prefix)
459 FREE(conf->alias_prefix);
462 FREE(conf->prio_args);
464 if (conf->checker_name)
465 FREE(conf->checker_name);
466 if (conf->reservation_key)
467 FREE(conf->reservation_key);
469 free_blacklist(conf->blist_devnode);
470 free_blacklist(conf->blist_wwid);
471 free_blacklist_device(conf->blist_device);
473 free_blacklist(conf->elist_devnode);
474 free_blacklist(conf->elist_wwid);
475 free_blacklist_device(conf->elist_device);
477 free_mptable(conf->mptable);
478 free_hwtable(conf->hwtable);
479 free_keywords(conf->keywords);
484 load_config (char * file)
487 conf = alloc_config();
495 if (!conf->verbosity)
496 conf->verbosity = DEFAULT_VERBOSITY;
498 conf->udev = udev_new();
499 conf->dmrq = dm_drv_get_rq();
500 conf->dev_type = DEV_NONE;
501 conf->minio = DEFAULT_MINIO;
502 conf->minio_rq = DEFAULT_MINIO_RQ;
503 get_sys_max_fds(&conf->max_fds);
504 conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE);
505 conf->bindings_read_only = 0;
506 conf->multipath_dir = set_default(DEFAULT_MULTIPATHDIR);
507 conf->features = set_default(DEFAULT_FEATURES);
508 conf->flush_on_last_del = 0;
509 conf->attribute_flags = 0;
510 conf->reassign_maps = DEFAULT_REASSIGN_MAPS;
511 conf->checkint = DEFAULT_CHECKINT;
512 conf->max_checkint = MAX_CHECKINT(conf->checkint);
515 * preload default hwtable
517 if (conf->hwtable == NULL) {
518 conf->hwtable = vector_alloc();
523 if (setup_default_hwtable(conf->hwtable))
527 * read the config file
529 set_current_keywords(&conf->keywords);
531 if (filepresent(file)) {
532 int builtin_hwtable_size;
534 builtin_hwtable_size = VECTOR_SIZE(conf->hwtable);
535 if (init_data(file, init_keywords)) {
536 condlog(0, "error parsing config file");
539 if (VECTOR_SIZE(conf->hwtable) > builtin_hwtable_size) {
541 * remove duplica in hwtable. config file
542 * takes precedence over build-in hwtable
544 factorize_hwtable(conf->hwtable, builtin_hwtable_size);
552 * fill the voids left in the config file
554 if (conf->blist_devnode == NULL) {
555 conf->blist_devnode = vector_alloc();
557 if (!conf->blist_devnode)
560 if (conf->blist_wwid == NULL) {
561 conf->blist_wwid = vector_alloc();
563 if (!conf->blist_wwid)
566 if (conf->blist_device == NULL) {
567 conf->blist_device = vector_alloc();
569 if (!conf->blist_device)
572 if (setup_default_blist(conf))
575 if (conf->elist_devnode == NULL) {
576 conf->elist_devnode = vector_alloc();
578 if (!conf->elist_devnode)
581 if (conf->elist_wwid == NULL) {
582 conf->elist_wwid = vector_alloc();
584 if (!conf->elist_wwid)
588 if (conf->elist_device == NULL) {
589 conf->elist_device = vector_alloc();
591 if (!conf->elist_device)
595 if (conf->mptable == NULL) {
596 conf->mptable = vector_alloc();
600 if (conf->udev_dir == NULL)
601 conf->udev_dir = set_default(DEFAULT_UDEVDIR);
603 if (conf->bindings_file == NULL)
604 conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE);
606 if (!conf->udev_dir || !conf->multipath_dir ||
607 !conf->bindings_file)