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 ((hwe2->vendor && !hwe1->vendor) ||
29 (hwe1->vendor && (!hwe2->vendor ||
30 strcmp(hwe1->vendor, hwe2->vendor))))
33 if ((hwe2->product && !hwe1->product) ||
34 (hwe1->product && (!hwe2->product ||
35 strcmp(hwe1->product, hwe2->product))))
38 if ((hwe2->revision && !hwe1->revision) ||
39 (hwe1->revision && (!hwe2->revision ||
40 strcmp(hwe1->revision, hwe2->revision))))
46 static struct hwentry *
47 find_hwe_strmatch (vector hwtable, struct hwentry *hwe)
50 struct hwentry *tmp, *ret = NULL;
52 vector_foreach_slot (hwtable, tmp, i) {
53 if (hwe_strmatch(tmp, hwe))
62 hwe_regmatch (struct hwentry *hwe1, struct hwentry *hwe2)
64 regex_t vre, pre, rre;
68 regcomp(&vre, hwe1->vendor, REG_EXTENDED|REG_NOSUB))
72 regcomp(&pre, hwe1->product, REG_EXTENDED|REG_NOSUB))
76 regcomp(&rre, hwe1->revision, REG_EXTENDED|REG_NOSUB))
79 if ((!hwe1->vendor || !hwe2->vendor ||
80 !regexec(&vre, hwe2->vendor, 0, NULL, 0)) &&
81 (!hwe1->product || !hwe2->product ||
82 !regexec(&pre, hwe2->product, 0, NULL, 0)) &&
83 (!hwe1->revision || !hwe2->revision ||
84 !regexec(&rre, hwe2->revision, 0, NULL, 0)))
100 find_hwe (vector hwtable, char * vendor, char * product, char * revision)
103 struct hwentry hwe, *tmp, *ret = NULL;
106 hwe.product = product;
107 hwe.revision = revision;
109 * Search backwards here.
110 * User modified entries are attached at the end of
111 * the list, so we have to check them first before
112 * continuing to the generic entries
114 vector_foreach_slot_backwards (hwtable, tmp, i) {
115 if (hwe_regmatch(tmp, &hwe))
123 extern struct mpentry *
124 find_mpe (char * wwid)
127 struct mpentry * mpe;
132 vector_foreach_slot (conf->mptable, mpe, i)
133 if (mpe->wwid && !strcmp(mpe->wwid, wwid))
140 get_mpe_wwid (char * alias)
143 struct mpentry * mpe;
148 vector_foreach_slot (conf->mptable, mpe, i)
149 if (mpe->alias && strcmp(mpe->alias, alias) == 0)
156 free_hwe (struct hwentry * hwe)
170 if (hwe->uid_attribute)
171 FREE(hwe->uid_attribute);
177 FREE(hwe->hwhandler);
182 if (hwe->checker_name)
183 FREE(hwe->checker_name);
186 FREE(hwe->prio_name);
189 FREE(hwe->prio_args);
191 if (hwe->alias_prefix)
192 FREE(hwe->alias_prefix);
195 FREE(hwe->bl_product);
201 free_hwtable (vector hwtable)
204 struct hwentry * hwe;
209 vector_foreach_slot (hwtable, hwe, i)
212 vector_free(hwtable);
216 free_mpe (struct mpentry * mpe)
227 if (mpe->uid_attribute)
228 FREE(mpe->uid_attribute);
234 FREE(mpe->prio_name);
237 FREE(mpe->prio_args);
243 free_mptable (vector mptable)
246 struct mpentry * mpe;
251 vector_foreach_slot (mptable, mpe, i)
254 vector_free(mptable);
260 struct mpentry * mpe = (struct mpentry *)
261 MALLOC(sizeof(struct mpentry));
269 struct hwentry * hwe = (struct hwentry *)
270 MALLOC(sizeof(struct hwentry));
276 set_param_str(char * str)
289 dst = (char *)MALLOC(len + 1);
298 #define merge_str(s) \
299 if (!dst->s && src->s) { \
300 if (!(dst->s = set_param_str(src->s))) \
304 #define merge_num(s) \
305 if (!dst->s && src->s) \
310 merge_hwe (struct hwentry * dst, struct hwentry * src)
315 merge_str(uid_attribute);
317 merge_str(hwhandler);
319 merge_str(checker_name);
320 merge_str(prio_name);
321 merge_str(prio_args);
322 merge_str(alias_prefix);
323 merge_str(bl_product);
325 merge_num(pgfailback);
326 merge_num(rr_weight);
327 merge_num(no_path_retry);
330 merge_num(pg_timeout);
331 merge_num(flush_on_last_del);
332 merge_num(fast_io_fail);
334 merge_num(user_friendly_names);
335 merge_num(retain_hwhandler);
336 merge_num(detect_prio);
339 * Make sure features is consistent with
342 if (dst->no_path_retry == NO_PATH_RETRY_FAIL)
343 remove_feature(&dst->features, "queue_if_no_path");
344 else if (dst->no_path_retry != NO_PATH_RETRY_UNDEF)
345 add_feature(&dst->features, "queue_if_no_path");
351 store_hwe (vector hwtable, struct hwentry * dhwe)
353 struct hwentry * hwe;
355 if (find_hwe_strmatch(hwtable, dhwe))
358 if (!(hwe = alloc_hwe()))
361 if (!dhwe->vendor || !(hwe->vendor = set_param_str(dhwe->vendor)))
364 if (!dhwe->product || !(hwe->product = set_param_str(dhwe->product)))
367 if (dhwe->revision && !(hwe->revision = set_param_str(dhwe->revision)))
370 if (dhwe->uid_attribute && !(hwe->uid_attribute = set_param_str(dhwe->uid_attribute)))
373 if (dhwe->features && !(hwe->features = set_param_str(dhwe->features)))
376 if (dhwe->hwhandler && !(hwe->hwhandler = set_param_str(dhwe->hwhandler)))
379 if (dhwe->selector && !(hwe->selector = set_param_str(dhwe->selector)))
382 if (dhwe->checker_name && !(hwe->checker_name = set_param_str(dhwe->checker_name)))
385 if (dhwe->prio_name && !(hwe->prio_name = set_param_str(dhwe->prio_name)))
388 if (dhwe->prio_args && !(hwe->prio_args = set_param_str(dhwe->prio_args)))
391 if (dhwe->alias_prefix && !(hwe->alias_prefix = set_param_str(dhwe->alias_prefix)))
394 hwe->pgpolicy = dhwe->pgpolicy;
395 hwe->pgfailback = dhwe->pgfailback;
396 hwe->rr_weight = dhwe->rr_weight;
397 hwe->no_path_retry = dhwe->no_path_retry;
398 hwe->minio = dhwe->minio;
399 hwe->minio_rq = dhwe->minio_rq;
400 hwe->pg_timeout = dhwe->pg_timeout;
401 hwe->flush_on_last_del = dhwe->flush_on_last_del;
402 hwe->fast_io_fail = dhwe->fast_io_fail;
403 hwe->dev_loss = dhwe->dev_loss;
404 hwe->user_friendly_names = dhwe->user_friendly_names;
405 hwe->retain_hwhandler = dhwe->retain_hwhandler;
406 hwe->detect_prio = dhwe->detect_prio;
408 if (dhwe->bl_product && !(hwe->bl_product = set_param_str(dhwe->bl_product)))
411 if (!vector_alloc_slot(hwtable))
414 vector_set_slot(hwtable, hwe);
422 factorize_hwtable (vector hw, int n)
424 struct hwentry *hwe1, *hwe2;
427 vector_foreach_slot(hw, hwe1, i) {
431 vector_foreach_slot_after(hw, hwe2, j) {
432 if (hwe_regmatch(hwe1, hwe2))
435 merge_hwe(hwe2, hwe1);
436 if (hwe_strmatch(hwe2, hwe1) == 0) {
437 vector_del_slot(hw, i);
451 return (struct config *)MALLOC(sizeof(struct config));
455 free_config (struct config * conf)
464 udev_unref(conf->udev);
466 if (conf->multipath_dir)
467 FREE(conf->multipath_dir);
470 FREE(conf->selector);
472 if (conf->uid_attribute)
473 FREE(conf->uid_attribute);
476 FREE(conf->features);
479 FREE(conf->hwhandler);
481 if (conf->bindings_file)
482 FREE(conf->bindings_file);
484 if (conf->wwids_file)
485 FREE(conf->wwids_file);
487 FREE(conf->prio_name);
489 if (conf->alias_prefix)
490 FREE(conf->alias_prefix);
493 FREE(conf->prio_args);
495 if (conf->checker_name)
496 FREE(conf->checker_name);
497 if (conf->reservation_key)
498 FREE(conf->reservation_key);
500 free_blacklist(conf->blist_devnode);
501 free_blacklist(conf->blist_wwid);
502 free_blacklist_device(conf->blist_device);
504 free_blacklist(conf->elist_devnode);
505 free_blacklist(conf->elist_wwid);
506 free_blacklist_device(conf->elist_device);
508 free_mptable(conf->mptable);
509 free_hwtable(conf->hwtable);
510 free_keywords(conf->keywords);
515 load_config (char * file)
518 conf = alloc_config();
526 if (!conf->verbosity)
527 conf->verbosity = DEFAULT_VERBOSITY;
529 conf->udev = udev_new();
530 dm_drv_version(conf->version, TGT_MPATH);
531 conf->dev_type = DEV_NONE;
532 conf->minio = DEFAULT_MINIO;
533 conf->minio_rq = DEFAULT_MINIO_RQ;
534 get_sys_max_fds(&conf->max_fds);
535 conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE);
536 conf->wwids_file = set_default(DEFAULT_WWIDS_FILE);
537 conf->bindings_read_only = 0;
538 conf->multipath_dir = set_default(DEFAULT_MULTIPATHDIR);
539 conf->features = set_default(DEFAULT_FEATURES);
540 conf->flush_on_last_del = 0;
541 conf->attribute_flags = 0;
542 conf->reassign_maps = DEFAULT_REASSIGN_MAPS;
543 conf->checkint = DEFAULT_CHECKINT;
544 conf->max_checkint = MAX_CHECKINT(conf->checkint);
545 conf->fast_io_fail = DEFAULT_FAST_IO_FAIL;
546 conf->retain_hwhandler = DEFAULT_RETAIN_HWHANDLER;
547 conf->detect_prio = DEFAULT_DETECT_PRIO;
550 * preload default hwtable
552 if (conf->hwtable == NULL) {
553 conf->hwtable = vector_alloc();
558 if (setup_default_hwtable(conf->hwtable))
562 * read the config file
564 set_current_keywords(&conf->keywords);
566 if (filepresent(file)) {
567 int builtin_hwtable_size;
569 builtin_hwtable_size = VECTOR_SIZE(conf->hwtable);
570 if (init_data(file, init_keywords)) {
571 condlog(0, "error parsing config file");
574 if (VECTOR_SIZE(conf->hwtable) > builtin_hwtable_size) {
576 * remove duplica in hwtable. config file
577 * takes precedence over build-in hwtable
579 factorize_hwtable(conf->hwtable, builtin_hwtable_size);
587 * fill the voids left in the config file
589 if (conf->blist_devnode == NULL) {
590 conf->blist_devnode = vector_alloc();
592 if (!conf->blist_devnode)
595 if (conf->blist_wwid == NULL) {
596 conf->blist_wwid = vector_alloc();
598 if (!conf->blist_wwid)
601 if (conf->blist_device == NULL) {
602 conf->blist_device = vector_alloc();
604 if (!conf->blist_device)
607 if (setup_default_blist(conf))
610 if (conf->elist_devnode == NULL) {
611 conf->elist_devnode = vector_alloc();
613 if (!conf->elist_devnode)
616 if (conf->elist_wwid == NULL) {
617 conf->elist_wwid = vector_alloc();
619 if (!conf->elist_wwid)
623 if (conf->elist_device == NULL) {
624 conf->elist_device = vector_alloc();
626 if (!conf->elist_device)
630 if (conf->mptable == NULL) {
631 conf->mptable = vector_alloc();
635 if (conf->bindings_file == NULL)
636 conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE);
638 if (!conf->multipath_dir || !conf->bindings_file ||