--- libmultipath/config.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++- libmultipath/config.h | 1 libmultipath/dict.c | 38 +++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) Index: multipath-tools-130222/libmultipath/config.c =================================================================== --- multipath-tools-130222.orig/libmultipath/config.c +++ multipath-tools-130222/libmultipath/config.c @@ -113,6 +113,8 @@ find_hwe (vector hwtable, char * vendor, * continuing to the generic entries */ vector_foreach_slot_backwards (hwtable, tmp, i) { + if (tmp->all_devs == 1) + continue; if (hwe_regmatch(tmp, &hwe)) continue; ret = tmp; @@ -348,6 +350,62 @@ merge_hwe (struct hwentry * dst, struct return 0; } +#define overwrite_str(s) \ +do { \ + if (src->s) { \ + if (dst->s) \ + FREE(dst->s); \ + if (!(dst->s = set_param_str(src->s))) \ + return 1; \ + } \ +} while(0) + +#define overwrite_num(s) \ +do { \ + if (src->s) \ + dst->s = src->s; \ +} while(0) + +static int +overwrite_hwe (struct hwentry * dst, struct hwentry * src) +{ + overwrite_str(vendor); + overwrite_str(product); + overwrite_str(revision); + overwrite_str(uid_attribute); + overwrite_str(features); + overwrite_str(hwhandler); + overwrite_str(selector); + overwrite_str(checker_name); + overwrite_str(prio_name); + overwrite_str(prio_args); + overwrite_str(alias_prefix); + overwrite_str(bl_product); + overwrite_num(pgpolicy); + overwrite_num(pgfailback); + overwrite_num(rr_weight); + overwrite_num(no_path_retry); + overwrite_num(minio); + overwrite_num(minio_rq); + overwrite_num(pg_timeout); + overwrite_num(flush_on_last_del); + overwrite_num(fast_io_fail); + overwrite_num(dev_loss); + overwrite_num(user_friendly_names); + overwrite_num(retain_hwhandler); + overwrite_num(detect_prio); + + /* + * Make sure features is consistent with + * no_path_retry + */ + if (dst->no_path_retry == NO_PATH_RETRY_FAIL) + remove_feature(&dst->features, "queue_if_no_path"); + else if (dst->no_path_retry != NO_PATH_RETRY_UNDEF) + add_feature(&dst->features, "queue_if_no_path"); + return 0; +} + int store_hwe (vector hwtable, struct hwentry * dhwe) { @@ -431,7 +489,11 @@ restart: break; j = n; vector_foreach_slot_after(hw, hwe2, j) { - if (conf->hw_strmatch) { + if (hwe2->all_devs == 1) { + overwrite_hwe(hwe1, hwe2); + continue; + } + else if (conf->hw_strmatch) { if (hwe_strmatch(hwe2, hwe1)) continue; } Index: multipath-tools-130222/libmultipath/config.h =================================================================== --- multipath-tools-130222.orig/libmultipath/config.h +++ multipath-tools-130222/libmultipath/config.h @@ -47,6 +47,7 @@ struct hwentry { char * prio_args; char * alias_prefix; + int all_devs; int pgpolicy; int pgfailback; int rr_weight; Index: multipath-tools-130222/libmultipath/dict.c =================================================================== --- multipath-tools-130222.orig/libmultipath/dict.c +++ multipath-tools-130222/libmultipath/dict.c @@ -918,6 +918,32 @@ device_handler(vector strvec) } static int +all_devs_handler(vector strvec) +{ + char * buff; + struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable); + + if (!hwe) + return 1; + + buff = set_value(strvec); + if (!buff) + return 1; + + if ((strlen(buff) == 2 && !strcmp(buff, "no")) || + (strlen(buff) == 1 && !strcmp(buff, "0"))) + hwe->all_devs = 0; + else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) || + (strlen(buff) == 1 && !strcmp(buff, "1"))) + hwe->all_devs = 1; + else + hwe->all_devs = 0; + + FREE(buff); + return 0; +} + +static int vendor_handler(vector strvec) { struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable); @@ -2182,6 +2208,17 @@ snprint_hw_dev_loss(char * buff, int len } static int +snprint_hw_all_devs (char *buff, int len, void *data) +{ + struct hwentry * hwe = (struct hwentry *)data; + + if (!hwe->all_devs) + return 0; + + return snprintf(buff, len, "yes"); +} + +static int snprint_hw_vendor (char * buff, int len, void * data) { struct hwentry * hwe = (struct hwentry *)data; @@ -2968,6 +3005,7 @@ init_keywords(void) install_keyword_root("devices", &devices_handler); install_keyword_multi("device", &device_handler, NULL); install_sublevel(); + install_keyword("all_devs", &all_devs_handler, &snprint_hw_all_devs); install_keyword("vendor", &vendor_handler, &snprint_hw_vendor); install_keyword("product", &product_handler, &snprint_hw_product); install_keyword("revision", &revision_handler, &snprint_hw_revision);