From ecd2a9152e7b8942588d95fba55149304501fa60 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 19 2015 16:09:01 +0000 Subject: import device-mapper-multipath-0.4.9-85.el7 --- diff --git a/SOURCES/0102-RHBZ-631009-deferred-remove.patch b/SOURCES/0102-RHBZ-631009-deferred-remove.patch index 1e1367a..9e40337 100644 --- a/SOURCES/0102-RHBZ-631009-deferred-remove.patch +++ b/SOURCES/0102-RHBZ-631009-deferred-remove.patch @@ -1,19 +1,19 @@ --- - libmultipath/Makefile | 6 ++ - libmultipath/config.c | 3 + - libmultipath/config.h | 3 + + libmultipath/Makefile | 6 + + libmultipath/config.c | 3 + libmultipath/config.h | 3 libmultipath/configure.c | 1 libmultipath/defaults.h | 1 - libmultipath/devmapper.c | 130 +++++++++++++++++++++++++++++++++++++++------ - libmultipath/devmapper.h | 12 ++-- - libmultipath/dict.c | 116 +++++++++++++++++++++++++++++++++++++++- - libmultipath/propsel.c | 28 +++++++++ + libmultipath/devmapper.c | 142 ++++++++++++++++++++++++++++++++++++++++----- + libmultipath/devmapper.h | 11 ++- + libmultipath/dict.c | 116 ++++++++++++++++++++++++++++++++++++ + libmultipath/propsel.c | 28 ++++++++ libmultipath/propsel.h | 1 libmultipath/structs.h | 8 ++ - libmultipath/structs_vec.c | 3 - + libmultipath/structs_vec.c | 3 multipath/multipath.conf.5 | 14 ++++ multipathd/main.c | 23 +++++-- - 14 files changed, 322 insertions(+), 27 deletions(-) + 14 files changed, 333 insertions(+), 27 deletions(-) Index: multipath-tools-130222/libmultipath/config.c =================================================================== @@ -99,7 +99,16 @@ Index: multipath-tools-130222/libmultipath/devmapper.c =================================================================== --- multipath-tools-130222.orig/libmultipath/devmapper.c +++ multipath-tools-130222/libmultipath/devmapper.c -@@ -103,7 +103,9 @@ dm_lib_prereq (void) +@@ -32,6 +32,8 @@ + #define UUID_PREFIX "mpath-" + #define UUID_PREFIX_LEN 6 + ++static int dm_cancel_remove_partmaps(const char * mapname); ++ + #ifndef LIBDM_API_COOKIE + static inline int dm_task_set_cookie(struct dm_task *dmt, uint32_t *c, int a) + { +@@ -103,7 +105,9 @@ dm_lib_prereq (void) { char version[64]; int v[3]; @@ -110,28 +119,31 @@ Index: multipath-tools-130222/libmultipath/devmapper.c int minv[3] = {1, 2, 82}; #elif defined(LIBDM_API_COOKIE) int minv[3] = {1, 2, 38}; -@@ -202,7 +204,7 @@ dm_prereq (void) +@@ -201,8 +205,10 @@ dm_prereq (void) + return dm_drv_prereq(); } ++#define do_deferred(x) ((x) == DEFERRED_REMOVE_ON || (x) == DEFERRED_REMOVE_IN_PROGRESS) ++ static int -dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t udev_flags) { +dm_simplecmd (int task, const char *name, int no_flush, int need_sync, uint16_t udev_flags, int deferred_remove) { int r = 0; int udev_wait_flag = (need_sync && (task == DM_DEVICE_RESUME || task == DM_DEVICE_REMOVE)); -@@ -220,7 +222,10 @@ dm_simplecmd (int task, const char *name +@@ -220,7 +226,10 @@ dm_simplecmd (int task, const char *name if (no_flush) dm_task_no_flush(dmt); /* for DM_DEVICE_SUSPEND/RESUME */ #endif - +#ifdef LIBDM_API_DEFERRED -+ if (deferred_remove) ++ if (do_deferred(deferred_remove)) + dm_task_deferred_remove(dmt); +#endif if (udev_wait_flag && !dm_task_set_cookie(dmt, &conf->cookie, ((conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0) | udev_flags)) goto out; r = dm_task_run (dmt); -@@ -232,12 +237,18 @@ dm_simplecmd (int task, const char *name +@@ -232,12 +241,18 @@ dm_simplecmd (int task, const char *name extern int dm_simplecmd_flush (int task, const char *name, int needsync, uint16_t udev_flags) { @@ -145,14 +157,14 @@ Index: multipath-tools-130222/libmultipath/devmapper.c + return dm_simplecmd(task, name, 1, 1, udev_flags, 0); +} + -+extern int ++static int +dm_device_remove (const char *name, int needsync, int deferred_remove) { + return dm_simplecmd(DM_DEVICE_REMOVE, name, 0, needsync, 0, + deferred_remove); } extern int -@@ -653,7 +664,7 @@ out: +@@ -653,7 +668,7 @@ out: } extern int @@ -161,7 +173,7 @@ Index: multipath-tools-130222/libmultipath/devmapper.c { int r; -@@ -663,23 +674,46 @@ _dm_flush_map (const char * mapname, int +@@ -663,23 +678,46 @@ _dm_flush_map (const char * mapname, int if (dm_type(mapname, TGT_MPATH) <= 0) return 0; /* nothing to do */ @@ -170,7 +182,7 @@ Index: multipath-tools-130222/libmultipath/devmapper.c return 1; - if (dm_get_opencount(mapname)) { -+ if (!deferred_remove && dm_get_opencount(mapname)) { ++ if (!do_deferred(deferred_remove) && dm_get_opencount(mapname)) { condlog(2, "%s: map in use", mapname); return 1; } @@ -179,7 +191,7 @@ Index: multipath-tools-130222/libmultipath/devmapper.c + r = dm_device_remove(mapname, need_sync, deferred_remove); if (r) { -+ if (deferred_remove && dm_map_present(mapname)) { ++ if (do_deferred(deferred_remove) && dm_map_present(mapname)) { + condlog(4, "multipath map %s remove deferred", + mapname); + return 2; @@ -211,7 +223,7 @@ Index: multipath-tools-130222/libmultipath/devmapper.c extern int dm_suspend_and_flush_map (const char * mapname) { -@@ -1076,6 +1110,7 @@ out: +@@ -1076,6 +1114,7 @@ out: struct remove_data { int need_sync; @@ -219,14 +231,15 @@ Index: multipath-tools-130222/libmultipath/devmapper.c }; static int -@@ -1084,25 +1119,90 @@ remove_partmap(char *name, void *data) +@@ -1084,25 +1123,98 @@ remove_partmap(char *name, void *data) struct remove_data *rd = (struct remove_data *)data; if (dm_get_opencount(name)) { - dm_remove_partmaps(name, rd->need_sync); - if (dm_get_opencount(name)) { + dm_remove_partmaps(name, rd->need_sync, rd->deferred_remove); -+ if (!rd->deferred_remove && dm_get_opencount(name)) { ++ if (!do_deferred(rd->deferred_remove) && ++ dm_get_opencount(name)) { condlog(2, "%s: map in use", name); return 1; } @@ -252,6 +265,8 @@ Index: multipath-tools-130222/libmultipath/devmapper.c +static int +cancel_remove_partmap (char *name, void *unused) +{ ++ if (dm_get_opencount(name)) ++ dm_cancel_remove_partmaps(name); + if (dm_message(name, "@cancel_deferred_remove") != 0) + condlog(0, "%s: can't cancel deferred remove: %s", name, + strerror(errno)); @@ -283,6 +298,11 @@ Index: multipath-tools-130222/libmultipath/devmapper.c + return r; +} + ++static int ++dm_cancel_remove_partmaps(const char * mapname) { ++ return do_foreach_partmaps(mapname, cancel_remove_partmap, NULL); ++} ++ +int +dm_cancel_deferred_remove (struct multipath *mpp) +{ @@ -293,7 +313,7 @@ Index: multipath-tools-130222/libmultipath/devmapper.c + if (mpp->deferred_remove == DEFERRED_REMOVE_IN_PROGRESS) + mpp->deferred_remove = DEFERRED_REMOVE_ON; + -+ do_foreach_partmaps(mpp->alias, cancel_remove_partmap, NULL); ++ dm_cancel_remove_partmaps(mpp->alias); + r = dm_message(mpp->alias, "@cancel_deferred_remove"); + if (r) + condlog(0, "%s: can't cancel deferred remove: %s", mpp->alias, @@ -320,14 +340,7 @@ Index: multipath-tools-130222/libmultipath/devmapper.h =================================================================== --- multipath-tools-130222.orig/libmultipath/devmapper.h +++ multipath-tools-130222/libmultipath/devmapper.h -@@ -17,15 +17,18 @@ int dm_prereq (void); - int dm_drv_version (unsigned int * version, char * str); - int dm_simplecmd_flush (int, const char *, int, uint16_t); - int dm_simplecmd_noflush (int, const char *, uint16_t); -+int dm_device_remove (const char *, int, int); - int dm_addmap_create (struct multipath *mpp, char *params); - int dm_addmap_reload (struct multipath *mpp, char *params); - int dm_map_present (const char *); +@@ -23,9 +23,11 @@ int dm_map_present (const char *); int dm_get_map(const char *, unsigned long long *, char *); int dm_get_status(char *, char *); int dm_type(const char *, char *); @@ -342,7 +355,7 @@ Index: multipath-tools-130222/libmultipath/devmapper.h int dm_suspend_and_flush_map(const char * mapname); int dm_flush_maps (void); int dm_fail_path(char * mapname, char * path); -@@ -40,7 +43,8 @@ int dm_geteventnr (char *name); +@@ -40,7 +42,8 @@ int dm_geteventnr (char *name); int dm_get_major (char *name); int dm_get_minor (char *name); char * dm_mapname(int major, int minor); diff --git a/SOURCES/0106-RHBZ-1169935-no-new-devs.patch b/SOURCES/0106-RHBZ-1169935-no-new-devs.patch new file mode 100644 index 0000000..99ae35a --- /dev/null +++ b/SOURCES/0106-RHBZ-1169935-no-new-devs.patch @@ -0,0 +1,231 @@ +--- + libmultipath/config.c | 4 ++++ + libmultipath/config.h | 1 + + libmultipath/configure.c | 5 ++--- + libmultipath/dict.c | 33 +++++++++++++++++++++++++++++++++ + libmultipath/util.c | 30 ++++++++++++++++++++++++++++++ + libmultipath/util.h | 1 + + libmultipath/wwids.c | 21 ++++++++++++++------- + multipathd/main.c | 3 +-- + 8 files changed, 86 insertions(+), 12 deletions(-) + +Index: multipath-tools-130222/libmultipath/config.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.h ++++ multipath-tools-130222/libmultipath/config.h +@@ -131,6 +131,7 @@ struct config { + int detect_prio; + int force_sync; + int deferred_remove; ++ int ignore_new_boot_devs; + unsigned int version[3]; + + char * dev; +Index: multipath-tools-130222/libmultipath/configure.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/configure.c ++++ multipath-tools-130222/libmultipath/configure.c +@@ -775,9 +775,8 @@ coalesce_paths (struct vectors * vecs, v + if (refwwid && strncmp(pp1->wwid, refwwid, WWID_SIZE)) + continue; + +- /* If find_multipaths was selected check if the path is valid */ +- if (conf->find_multipaths && !refwwid && +- !should_multipath(pp1, pathvec)) { ++ /* check if the path is valid */ ++ if (!refwwid && !should_multipath(pp1, pathvec)) { + orphan_path(pp1); + continue; + } +Index: multipath-tools-130222/libmultipath/wwids.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/wwids.c ++++ multipath-tools-130222/libmultipath/wwids.c +@@ -15,6 +15,7 @@ + #include "wwids.h" + #include "defaults.h" + #include "config.h" ++#include "util.h" + + /* + * Copyright (c) 2010 Benjamin Marzinski, Redhat +@@ -268,15 +269,21 @@ should_multipath(struct path *pp1, vecto + { + int i; + struct path *pp2; ++ int ignore_new_devs = (conf->ignore_new_boot_devs && in_initrd()); ++ ++ if (!conf->find_multipaths && !ignore_new_devs) ++ return 1; + + condlog(4, "checking if %s should be multipathed", pp1->dev); +- vector_foreach_slot(pathvec, pp2, i) { +- if (pp1->dev == pp2->dev) +- continue; +- if (strncmp(pp1->wwid, pp2->wwid, WWID_SIZE) == 0) { +- condlog(3, "found multiple paths with wwid %s, " +- "multipathing %s", pp1->wwid, pp1->dev); +- return 1; ++ if (!ignore_new_devs) { ++ vector_foreach_slot(pathvec, pp2, i) { ++ if (pp1->dev == pp2->dev) ++ continue; ++ if (strncmp(pp1->wwid, pp2->wwid, WWID_SIZE) == 0) { ++ condlog(3, "found multiple paths with wwid %s, " ++ "multipathing %s", pp1->wwid, pp1->dev); ++ return 1; ++ } + } + } + if (check_wwids_file(pp1->wwid, 0) < 0) { +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -503,8 +503,7 @@ rescan: + return 1; + } + +- if (conf->find_multipaths && +- !should_multipath(pp, vecs->pathvec)) { ++ if (!should_multipath(pp, vecs->pathvec)) { + orphan_path(pp); + return 0; + } +Index: multipath-tools-130222/libmultipath/config.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.c ++++ multipath-tools-130222/libmultipath/config.c +@@ -622,6 +622,7 @@ load_config (char * file, struct udev *u + conf->deferred_remove = DEFAULT_DEFERRED_REMOVE; + conf->hw_strmatch = 0; + conf->force_sync = 0; ++ conf->ignore_new_boot_devs = 0; + + /* + * preload default hwtable +@@ -732,6 +733,9 @@ load_config (char * file, struct udev *u + !conf->wwids_file) + goto out; + ++ if (conf->ignore_new_boot_devs) ++ in_initrd(); ++ + return 0; + out: + free_config(conf); +Index: multipath-tools-130222/libmultipath/dict.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/dict.c ++++ multipath-tools-130222/libmultipath/dict.c +@@ -761,6 +761,29 @@ def_deferred_remove_handler(vector strve + return 0; + } + ++static int ++def_ignore_new_boot_devs_handler(vector strvec) ++{ ++ char * buff; ++ ++ buff = set_value(strvec); ++ ++ if (!buff) ++ return 1; ++ ++ if ((strlen(buff) == 2 && !strcmp(buff, "no")) || ++ (strlen(buff) == 1 && !strcmp(buff, "0"))) ++ conf->ignore_new_boot_devs = 0; ++ else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) || ++ (strlen(buff) == 1 && !strcmp(buff, "1"))) ++ conf->ignore_new_boot_devs = 1; ++ else ++ conf->ignore_new_boot_devs = 0; ++ ++ FREE(buff); ++ return 0; ++} ++ + /* + * blacklist block handlers + */ +@@ -3011,6 +3034,15 @@ snprint_def_deferred_remove(char * buff, + } + + static int ++snprint_def_ignore_new_boot_devs(char * buff, int len, void * data) ++{ ++ if (conf->ignore_new_boot_devs == 1) ++ return snprintf(buff, len, "yes"); ++ else ++ return snprintf(buff, len, "no"); ++} ++ ++static int + snprint_ble_simple (char * buff, int len, void * data) + { + struct blentry * ble = (struct blentry *)data; +@@ -3080,6 +3112,7 @@ init_keywords(void) + install_keyword("hw_str_match", &def_hw_strmatch_handler, &snprint_def_hw_strmatch); + install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync); + install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove); ++ install_keyword("ignore_new_boot_devs", &def_ignore_new_boot_devs_handler, &snprint_def_ignore_new_boot_devs); + __deprecated install_keyword("default_selector", &def_selector_handler, NULL); + __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); + __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); +Index: multipath-tools-130222/libmultipath/util.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/util.c ++++ multipath-tools-130222/libmultipath/util.c +@@ -3,6 +3,8 @@ + #include + #include + #include ++#include ++#include + + #include "debug.h" + #include "memory.h" +@@ -267,3 +269,31 @@ dev_t parse_devt(const char *dev_t) + + return makedev(maj, min); + } ++ ++/* This define was taken from systemd. src/shared/macro.h */ ++#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b) ++ ++/* This function was taken from systemd. src/shared/util.c */ ++int in_initrd(void) { ++ static int saved = -1; ++ struct statfs s; ++ ++ if (saved >= 0) ++ return saved; ++ ++ /* We make two checks here: ++ * ++ * 1. the flag file /etc/initrd-release must exist ++ * 2. the root file system must be a memory file system ++ * The second check is extra paranoia, since misdetecting an ++ * initrd can have bad bad consequences due the initrd ++ * emptying when transititioning to the main systemd. ++ */ ++ ++ saved = access("/etc/initrd-release", F_OK) >= 0 && ++ statfs("/", &s) >= 0 && ++ (F_TYPE_EQUAL(s.f_type, TMPFS_MAGIC) || ++ F_TYPE_EQUAL(s.f_type, RAMFS_MAGIC)); ++ ++ return saved; ++} +Index: multipath-tools-130222/libmultipath/util.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/util.h ++++ multipath-tools-130222/libmultipath/util.h +@@ -11,6 +11,7 @@ void remove_trailing_chars(char *path, c + int devt2devname (char *, int, char *); + dev_t parse_devt(const char *dev_t); + char *convert_dev(char *dev, int is_path_device); ++int in_initrd(void); + + #define safe_sprintf(var, format, args...) \ + snprintf(var, sizeof(var), format, ##args) >= sizeof(var) diff --git a/SOURCES/0106-RHBZ-1212590-dont-use-var.patch b/SOURCES/0106-RHBZ-1212590-dont-use-var.patch deleted file mode 100644 index 8009073..0000000 --- a/SOURCES/0106-RHBZ-1212590-dont-use-var.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- - libmultipath/defaults.h | 4 ++-- - multipathd/multipathd.service | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) - -Index: multipath-tools-130222/libmultipath/defaults.h -=================================================================== ---- multipath-tools-130222.orig/libmultipath/defaults.h -+++ multipath-tools-130222/libmultipath/defaults.h -@@ -25,8 +25,8 @@ - #define MAX_CHECKINT(a) (a << 2) - - #define MAX_DEV_LOSS_TMO 0x7FFFFFFF --#define DEFAULT_PIDFILE "/var/run/multipathd/multipathd.pid" --#define DEFAULT_TIMESTAMP_FILE "/var/run/multipathd/timestamp" -+#define DEFAULT_PIDFILE "/run/multipathd/multipathd.pid" -+#define DEFAULT_TIMESTAMP_FILE "/run/multipathd/timestamp" - #define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd" - #define DEFAULT_CONFIGFILE "/etc/multipath.conf" - #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" -Index: multipath-tools-130222/multipathd/multipathd.service -=================================================================== ---- multipath-tools-130222.orig/multipathd/multipathd.service -+++ multipath-tools-130222/multipathd/multipathd.service -@@ -9,7 +9,7 @@ Conflicts=shutdown.target - - [Service] - Type=forking --PIDFile=/var/run/multipathd/multipathd.pid -+PIDFile=/run/multipathd/multipathd.pid - ExecStartPre=/sbin/modprobe dm-multipath - ExecStartPre=-/sbin/multipath -A - ExecStart=/sbin/multipathd diff --git a/SOURCES/0107-RH-adapter-name-wildcard.patch b/SOURCES/0107-RH-adapter-name-wildcard.patch new file mode 100644 index 0000000..3c67de5 --- /dev/null +++ b/SOURCES/0107-RH-adapter-name-wildcard.patch @@ -0,0 +1,33 @@ +--- + libmultipath/print.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +Index: multipath-tools-130222/libmultipath/print.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/print.c ++++ multipath-tools-130222/libmultipath/print.c +@@ -510,6 +510,16 @@ snprint_tgt_wwnn (char * buff, size_t le + } + + static int ++snprint_host_adapter (char * buff, size_t len, struct path * pp) ++{ ++ char adapter[SLOT_NAME_SIZE]; ++ ++ if (sysfs_get_host_adapter_name(pp, adapter)) ++ return snprintf(buff, len, "[undef]"); ++ return snprint_str(buff, len, adapter); ++} ++ ++static int + snprint_path_checker (char * buff, size_t len, struct path * pp) + { + struct checker * c = &pp->checker; +@@ -557,6 +567,7 @@ struct path_data pd[] = { + {'n', "target WWNN", 0, snprint_tgt_wwnn}, + {'R', "host WWPN", 0, snprint_host_wwpn}, + {'r', "target WWPN", 0, snprint_tgt_wwpn}, ++ {'a', "host adapter", 0, snprint_host_adapter}, + {0, NULL, 0 , NULL} + }; + diff --git a/SOURCES/0107-UPBZ-1254292-iscsi-targetname.patch b/SOURCES/0107-UPBZ-1254292-iscsi-targetname.patch deleted file mode 100644 index 26a6831..0000000 --- a/SOURCES/0107-UPBZ-1254292-iscsi-targetname.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- - libmultipath/discovery.c | 2 ++ - 1 file changed, 2 insertions(+) - -Index: multipath-tools-130222/libmultipath/discovery.c -=================================================================== ---- multipath-tools-130222.orig/libmultipath/discovery.c -+++ multipath-tools-130222/libmultipath/discovery.c -@@ -280,6 +280,8 @@ sysfs_get_tgt_nodename (struct path *pp, - const char *value; - - value = udev_device_get_sysattr_value(tgtdev, "tgtname"); -+ if (!value) -+ value = udev_device_get_sysattr_value(tgtdev, "targetname"); - if (value) { - pp->sg_id.proto_id = SCSI_PROTOCOL_ISCSI; - pp->sg_id.transport_id = tgtid; diff --git a/SOURCES/0108-RHBZ-1153832-kpartx-remove-devs.patch b/SOURCES/0108-RHBZ-1153832-kpartx-remove-devs.patch new file mode 100644 index 0000000..f02551a --- /dev/null +++ b/SOURCES/0108-RHBZ-1153832-kpartx-remove-devs.patch @@ -0,0 +1,15 @@ +--- + multipath/multipath.rules | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: multipath-tools-130222/multipath/multipath.rules +=================================================================== +--- multipath-tools-130222.orig/multipath/multipath.rules ++++ multipath-tools-130222/multipath/multipath.rules +@@ -45,5 +45,5 @@ ACTION!="change", GOTO="end_mpath" + ENV{DM_UUID}!="mpath-?*", GOTO="end_mpath" + ENV{DM_SUSPENDED}=="1", GOTO="end_mpath" + ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath" +-ENV{DM_ACTIVATION}=="1", RUN+="$env{MPATH_SBIN_PATH}/kpartx -a $tempnode" ++ENV{DM_ACTIVATION}=="1", RUN+="$env{MPATH_SBIN_PATH}/kpartx -u $tempnode" + LABEL="end_mpath" diff --git a/SOURCES/0109-RH-read-only-bindings.patch b/SOURCES/0109-RH-read-only-bindings.patch new file mode 100644 index 0000000..c08120f --- /dev/null +++ b/SOURCES/0109-RH-read-only-bindings.patch @@ -0,0 +1,27 @@ +--- + multipathd/main.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -1879,7 +1879,7 @@ main (int argc, char *argv[]) + if (!conf) + exit(1); + +- while ((arg = getopt(argc, argv, ":dv:k::")) != EOF ) { ++ while ((arg = getopt(argc, argv, ":dv:k::B")) != EOF ) { + switch(arg) { + case 'd': + logsink = 0; +@@ -1895,6 +1895,9 @@ main (int argc, char *argv[]) + case 'k': + uxclnt(optarg); + exit(0); ++ case 'B': ++ conf->bindings_read_only = 1; ++ break; + default: + ; + } diff --git a/SOURCES/0110-RHBZ-blacklist-vd-devs.patch b/SOURCES/0110-RHBZ-blacklist-vd-devs.patch new file mode 100644 index 0000000..af52d0d --- /dev/null +++ b/SOURCES/0110-RHBZ-blacklist-vd-devs.patch @@ -0,0 +1,17 @@ +--- + libmultipath/blacklist.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: multipath-tools-130222/libmultipath/blacklist.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/blacklist.c ++++ multipath-tools-130222/libmultipath/blacklist.c +@@ -169,7 +169,7 @@ setup_default_blist (struct config * con + if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) + return 1; + +- str = STRDUP("^(td|hd)[a-z]"); ++ str = STRDUP("^(td|hd|vd)[a-z]"); + if (!str) + return 1; + if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT)) diff --git a/SOURCES/0111-RH-dont-show-pg-timeout.patch b/SOURCES/0111-RH-dont-show-pg-timeout.patch new file mode 100644 index 0000000..f545cc5 --- /dev/null +++ b/SOURCES/0111-RH-dont-show-pg-timeout.patch @@ -0,0 +1,147 @@ +--- + libmultipath/dict.c | 97 ---------------------------------------------------- + 1 file changed, 97 deletions(-) + +Index: multipath-tools-130222/libmultipath/dict.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/dict.c ++++ multipath-tools-130222/libmultipath/dict.c +@@ -473,26 +473,6 @@ def_checker_timeout_handler(vector strve + static int + def_pg_timeout_handler(vector strvec) + { +- int pg_timeout; +- char * buff; +- +- buff = set_value(strvec); +- +- if (!buff) +- return 1; +- +- if (strlen(buff) == 4 && !strcmp(buff, "none")) +- conf->pg_timeout = -PGTIMEOUT_NONE; +- else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) { +- if (pg_timeout == 0) +- conf->pg_timeout = -PGTIMEOUT_NONE; +- else +- conf->pg_timeout = pg_timeout; +- } +- else +- conf->pg_timeout = PGTIMEOUT_UNDEF; +- +- FREE(buff); + return 0; + } + +@@ -1358,30 +1338,6 @@ hw_minio_rq_handler(vector strvec) + static int + hw_pg_timeout_handler(vector strvec) + { +- int pg_timeout; +- struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable); +- char *buff; +- +- if (!hwe) +- return 1; +- +- buff = set_value(strvec); +- +- if (!buff) +- return 1; +- +- if (strlen(buff) == 4 && !strcmp(buff, "none")) +- hwe->pg_timeout = -PGTIMEOUT_NONE; +- else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) { +- if (pg_timeout == 0) +- hwe->pg_timeout = -PGTIMEOUT_NONE; +- else +- hwe->pg_timeout = pg_timeout; +- } +- else +- hwe->pg_timeout = PGTIMEOUT_UNDEF; +- +- FREE(buff); + return 0; + } + +@@ -1819,29 +1775,6 @@ mp_minio_rq_handler(vector strvec) + static int + mp_pg_timeout_handler(vector strvec) + { +- int pg_timeout; +- struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable); +- char *buff; +- +- if (!mpe) +- return 1; +- +- buff = set_value(strvec); +- +- if (!buff) +- return 1; +- if (strlen(buff) == 4 && !strcmp(buff, "none")) +- mpe->pg_timeout = -PGTIMEOUT_NONE; +- else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) { +- if (pg_timeout == 0) +- mpe->pg_timeout = -PGTIMEOUT_NONE; +- else +- mpe->pg_timeout = pg_timeout; +- } +- else +- mpe->pg_timeout = PGTIMEOUT_UNDEF; +- +- FREE(buff); + return 0; + } + +@@ -2180,16 +2113,6 @@ snprint_mp_rr_min_io_rq (char * buff, in + static int + snprint_mp_pg_timeout (char * buff, int len, void * data) + { +- struct mpentry * mpe = (struct mpentry *)data; +- +- switch (mpe->pg_timeout) { +- case PGTIMEOUT_UNDEF: +- break; +- case -PGTIMEOUT_NONE: +- return snprintf(buff, len, "\"none\""); +- default: +- return snprintf(buff, len, "%i", mpe->pg_timeout); +- } + return 0; + } + +@@ -2551,19 +2474,6 @@ snprint_hw_rr_min_io_rq (char * buff, in + static int + snprint_hw_pg_timeout (char * buff, int len, void * data) + { +- struct hwentry * hwe = (struct hwentry *)data; +- +- if (!hwe->pg_timeout) +- return 0; +- +- switch (hwe->pg_timeout) { +- case PGTIMEOUT_UNDEF: +- break; +- case -PGTIMEOUT_NONE: +- return snprintf(buff, len, "\"none\""); +- default: +- return snprintf(buff, len, "%i", hwe->pg_timeout); +- } + return 0; + } + +@@ -2895,13 +2805,6 @@ snprint_def_checker_timeout (char *buff, + static int + snprint_def_pg_timeout (char * buff, int len, void * data) + { +- switch (conf->pg_timeout) { +- case PGTIMEOUT_UNDEF: +- case -PGTIMEOUT_NONE: +- return snprintf(buff, len, "\"none\""); +- default: +- return snprintf(buff, len, "%i", conf->pg_timeout); +- } + return 0; + } + diff --git a/SOURCES/0112-RHBZ-1194917-add-config_dir-option.patch b/SOURCES/0112-RHBZ-1194917-add-config_dir-option.patch new file mode 100644 index 0000000..6cc07e7 --- /dev/null +++ b/SOURCES/0112-RHBZ-1194917-add-config_dir-option.patch @@ -0,0 +1,616 @@ +--- + libmultipath/config.c | 56 +++++++++++++++++++++++++++++++- + libmultipath/config.h | 2 + + libmultipath/defaults.h | 1 + libmultipath/dict.c | 69 +++++++++++++++++++++++++++++++++++---- + libmultipath/parser.c | 78 +++++++++++++++++++++++---------------------- + libmultipath/parser.h | 3 - + multipath.conf.annotated | 10 +++++ + multipath.conf.defaults | 1 + multipath/multipath.conf.5 | 7 ++++ + 9 files changed, 179 insertions(+), 48 deletions(-) + +Index: multipath-tools-130222/libmultipath/parser.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/parser.c ++++ multipath-tools-130222/libmultipath/parser.c +@@ -18,6 +18,7 @@ + */ + + #include ++#include + + #include "parser.h" + #include "memory.h" +@@ -453,14 +454,15 @@ set_value(vector strvec) + /* non-recursive configuration stream handler */ + static int kw_level = 0; + +-int warn_on_duplicates(vector uniques, char *str) ++int warn_on_duplicates(vector uniques, char *str, char *file) + { + char *tmp; + int i; + + vector_foreach_slot(uniques, tmp, i) { + if (!strcmp(str, tmp)) { +- condlog(1, "multipath.conf line %d, duplicate keyword: %s", line_nr, str); ++ condlog(1, "%s line %d, duplicate keyword: %s", ++ file, line_nr, str); + return 0; + } + } +@@ -496,65 +498,70 @@ is_sublevel_keyword(char *str) + } + + int +-validate_config_strvec(vector strvec) ++validate_config_strvec(vector strvec, char *file) + { + char *str; + int i; + + str = VECTOR_SLOT(strvec, 0); + if (str == NULL) { +- condlog(0, "can't parse option on line %d of config file", +- line_nr); ++ condlog(0, "can't parse option on line %d of %s", ++ line_nr, file); + return -1; + } + if (*str == '}') { + if (VECTOR_SIZE(strvec) > 1) +- condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 1), line_nr); ++ condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 1), line_nr, file); + return 0; + } + if (*str == '{') { +- condlog(0, "invalid keyword '%s' on line %d of config file", str, line_nr); ++ condlog(0, "invalid keyword '%s' on line %d of %s", ++ str, line_nr, file); + return -1; + } + if (is_sublevel_keyword(str)) { + str = VECTOR_SLOT(strvec, 1); + if (str == NULL) +- condlog(0, "missing '{' on line %d of config file", line_nr); ++ condlog(0, "missing '{' on line %d of %s", ++ line_nr, file); + else if (*str != '{') +- condlog(0, "expecting '{' on line %d of config file. found '%s'", line_nr, str); ++ condlog(0, "expecting '{' on line %d of %s. found '%s'", ++ line_nr, file, str); + else if (VECTOR_SIZE(strvec) > 2) +- condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 2), line_nr); ++ condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 2), line_nr, file); + return 0; + } + str = VECTOR_SLOT(strvec, 1); + if (str == NULL) { +- condlog(0, "missing value for option '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 0), line_nr); ++ condlog(0, "missing value for option '%s' on line %d of %s", ++ (char *)VECTOR_SLOT(strvec, 0), line_nr, file); + return -1; + } + if (*str != '"') { + if (VECTOR_SIZE(strvec) > 2) +- condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, 2), line_nr); ++ condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, 2), line_nr, file); + return 0; + } + for (i = 2; i < VECTOR_SIZE(strvec); i++) { + str = VECTOR_SLOT(strvec, i); + if (str == NULL) { +- condlog(0, "can't parse value on line %d of config file", line_nr); ++ condlog(0, "can't parse value on line %d of %s", ++ line_nr, file); + return -1; + } + if (*str == '"') { + if (VECTOR_SIZE(strvec) > i + 1) +- condlog(0, "ignoring extra data starting with '%s' on line %d of config file", (char *)VECTOR_SLOT(strvec, (i + 1)), line_nr); ++ condlog(0, "ignoring extra data starting with '%s' on line %d of %s", (char *)VECTOR_SLOT(strvec, (i + 1)), line_nr, file); + return 0; + } + } +- condlog(0, "missing closing quotes on line %d of config file", +- line_nr); ++ condlog(0, "missing closing quotes on line %d of %s", ++ line_nr, file); + return 0; + } + +-int +-process_stream(vector keywords) ++static int ++process_stream(vector keywords, char *file) + { + int i; + int r = 0; +@@ -583,7 +590,7 @@ process_stream(vector keywords) + if (!strvec) + continue; + +- if (validate_config_strvec(strvec) != 0) { ++ if (validate_config_strvec(strvec, file) != 0) { + free_strvec(strvec); + continue; + } +@@ -595,8 +602,8 @@ process_stream(vector keywords) + free_strvec(strvec); + break; + } +- condlog(0, "unmatched '%s' at line %d of config file", +- EOB, line_nr); ++ condlog(0, "unmatched '%s' at line %d of %s", ++ EOB, line_nr, file); + } + + for (i = 0; i < VECTOR_SIZE(keywords); i++) { +@@ -604,7 +611,7 @@ process_stream(vector keywords) + + if (!strcmp(keyword->string, str)) { + if (keyword->unique && +- warn_on_duplicates(uniques, str)) { ++ warn_on_duplicates(uniques, str, file)) { + r = 1; + free_strvec(strvec); + goto out; +@@ -614,15 +621,15 @@ process_stream(vector keywords) + + if (keyword->sub) { + kw_level++; +- r += process_stream(keyword->sub); ++ r += process_stream(keyword->sub, file); + kw_level--; + } + break; + } + } + if (i >= VECTOR_SIZE(keywords)) +- condlog(1, "multipath.conf +%d, invalid keyword: %s", +- line_nr, str); ++ condlog(1, "%s line %d, invalid keyword: %s", ++ file, line_nr, str); + + free_strvec(strvec); + } +@@ -646,27 +653,24 @@ int alloc_keywords(void) + + /* Data initialization */ + int +-init_data(char *conf_file, void (*init_keywords) (void)) ++process_file(char *file) + { + int r; + +- stream = fopen(conf_file, "r"); ++ if (!keywords) { ++ condlog(0, "No keywords alocated"); ++ return 1; ++ } ++ stream = fopen(file, "r"); + if (!stream) { +- syslog(LOG_WARNING, "Configuration file open problem"); ++ condlog(0, "couldn't open configuration file '%s': %s", ++ file, strerror(errno)); + return 1; + } + +- /* Init Keywords structure */ +- (*init_keywords) (); +- +-/* Dump configuration * +- vector_dump(keywords); +- dump_keywords(keywords, 0); +-*/ +- + /* Stream handling */ + line_nr = 0; +- r = process_stream(keywords); ++ r = process_stream(keywords, file); + fclose(stream); + //free_keywords(keywords); + +Index: multipath-tools-130222/libmultipath/dict.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/dict.c ++++ multipath-tools-130222/libmultipath/dict.c +@@ -117,6 +117,8 @@ reassign_maps_handler(vector strvec) + static int + multipath_dir_handler(vector strvec) + { ++ if (conf->multipath_dir) ++ FREE(conf->multipath_dir); + conf->multipath_dir = set_value(strvec); + + if (!conf->multipath_dir) +@@ -128,6 +130,8 @@ multipath_dir_handler(vector strvec) + static int + def_selector_handler(vector strvec) + { ++ if (conf->selector) ++ FREE(conf->selector); + conf->selector = set_value(strvec); + + if (!conf->selector) +@@ -155,6 +159,8 @@ def_pgpolicy_handler(vector strvec) + static int + def_uid_attribute_handler(vector strvec) + { ++ if (conf->uid_attribute) ++ FREE(conf->uid_attribute); + conf->uid_attribute = set_value(strvec); + + if (!conf->uid_attribute) +@@ -166,6 +172,8 @@ def_uid_attribute_handler(vector strvec) + static int + def_prio_handler(vector strvec) + { ++ if (conf->prio_name) ++ FREE(conf->prio_name); + conf->prio_name = set_value(strvec); + + if (!conf->prio_name) +@@ -177,6 +185,8 @@ def_prio_handler(vector strvec) + static int + def_alias_prefix_handler(vector strvec) + { ++ if (conf->alias_prefix) ++ FREE(conf->alias_prefix); + conf->alias_prefix = set_value(strvec); + + if (!conf->alias_prefix) +@@ -188,6 +198,8 @@ def_alias_prefix_handler(vector strvec) + static int + def_prio_args_handler(vector strvec) + { ++ if (conf->prio_args) ++ FREE(conf->prio_args); + conf->prio_args = set_value(strvec); + + if (!conf->prio_args) +@@ -199,6 +211,8 @@ def_prio_args_handler(vector strvec) + static int + def_features_handler(vector strvec) + { ++ if (conf->features) ++ FREE(conf->features); + conf->features = set_value(strvec); + + if (!conf->features) +@@ -210,6 +224,8 @@ def_features_handler(vector strvec) + static int + def_path_checker_handler(vector strvec) + { ++ if (conf->checker_name) ++ FREE(conf->checker_name); + conf->checker_name = set_value(strvec); + + if (!conf->checker_name) +@@ -432,6 +448,23 @@ def_no_path_retry_handler(vector strvec) + return 0; + } + ++ ++static int ++def_config_dir_handler(vector strvec) ++{ ++ /* this is only valid in the main config file */ ++ if (conf->processed_main_config) ++ return 0; ++ if (conf->config_dir) ++ FREE(conf->config_dir); ++ conf->config_dir = set_value(strvec); ++ ++ if (!conf->config_dir) ++ return 1; ++ ++ return 0; ++} ++ + static int + def_queue_without_daemon(vector strvec) + { +@@ -611,6 +644,8 @@ def_names_handler(vector strvec) + static int + bindings_file_handler(vector strvec) + { ++ if (conf->bindings_file) ++ FREE(conf->bindings_file); + conf->bindings_file = set_value(strvec); + + if (!conf->bindings_file) +@@ -622,6 +657,8 @@ bindings_file_handler(vector strvec) + static int + wwids_file_handler(vector strvec) + { ++ if (conf->wwids_file) ++ FREE(conf->wwids_file); + conf->wwids_file = set_value(strvec); + + if (!conf->wwids_file) +@@ -770,9 +807,12 @@ def_ignore_new_boot_devs_handler(vector + static int + blacklist_handler(vector strvec) + { +- conf->blist_devnode = vector_alloc(); +- conf->blist_wwid = vector_alloc(); +- conf->blist_device = vector_alloc(); ++ if (!conf->blist_devnode) ++ conf->blist_devnode = vector_alloc(); ++ if (!conf->blist_wwid) ++ conf->blist_wwid = vector_alloc(); ++ if (!conf->blist_device) ++ conf->blist_device = vector_alloc(); + + if (!conf->blist_devnode || !conf->blist_wwid || !conf->blist_device) + return 1; +@@ -783,9 +823,12 @@ blacklist_handler(vector strvec) + static int + blacklist_exceptions_handler(vector strvec) + { +- conf->elist_devnode = vector_alloc(); +- conf->elist_wwid = vector_alloc(); +- conf->elist_device = vector_alloc(); ++ if (!conf->elist_devnode) ++ conf->elist_devnode = vector_alloc(); ++ if (!conf->elist_wwid) ++ conf->elist_wwid = vector_alloc(); ++ if (!conf->elist_device) ++ conf->elist_device = vector_alloc(); + + if (!conf->elist_devnode || !conf->elist_wwid || !conf->elist_device) + return 1; +@@ -1480,7 +1523,8 @@ hw_deferred_remove_handler(vector strvec + static int + multipaths_handler(vector strvec) + { +- conf->mptable = vector_alloc(); ++ if (!conf->mptable) ++ conf->mptable = vector_alloc(); + + if (!conf->mptable) + return 1; +@@ -2945,6 +2989,16 @@ snprint_def_ignore_new_boot_devs(char * + return snprintf(buff, len, "no"); + } + ++ ++static int ++snprint_def_config_dir (char * buff, int len, void * data) ++{ ++ if (!conf->config_dir) ++ return 0; ++ ++ return snprintf(buff, len, "\"%s\"", conf->config_dir); ++} ++ + static int + snprint_ble_simple (char * buff, int len, void * data) + { +@@ -3016,6 +3070,7 @@ init_keywords(void) + install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync); + install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove); + install_keyword("ignore_new_boot_devs", &def_ignore_new_boot_devs_handler, &snprint_def_ignore_new_boot_devs); ++ install_keyword("config_dir", &def_config_dir_handler, &snprint_def_config_dir); + __deprecated install_keyword("default_selector", &def_selector_handler, NULL); + __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); + __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); +Index: multipath-tools-130222/libmultipath/parser.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/parser.h ++++ multipath-tools-130222/libmultipath/parser.h +@@ -76,9 +76,8 @@ extern int read_line(char *buf, int size + extern vector read_value_block(void); + extern int alloc_value_block(vector strvec, void (*alloc_func) (vector)); + extern void *set_value(vector strvec); +-extern int process_stream(vector keywords); + extern int alloc_keywords(void); +-extern int init_data(char *conf_file, void (*init_keywords) (void)); ++extern int process_file(char *conf_file); + extern struct keyword * find_keyword(vector v, char * name); + void set_current_keywords (vector *k); + int snprint_keyword(char *buff, int len, char *fmt, struct keyword *kw, +Index: multipath-tools-130222/libmultipath/config.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.c ++++ multipath-tools-130222/libmultipath/config.c +@@ -6,6 +6,9 @@ + #include + #include + #include ++#include ++#include ++#include + + #include "checkers.h" + #include "memory.h" +@@ -556,6 +559,7 @@ free_config (struct config * conf) + + if (conf->wwids_file) + FREE(conf->wwids_file); ++ + if (conf->prio_name) + FREE(conf->prio_name); + +@@ -567,6 +571,10 @@ free_config (struct config * conf) + + if (conf->checker_name) + FREE(conf->checker_name); ++ ++ if (conf->config_dir) ++ FREE(conf->config_dir); ++ + if (conf->reservation_key) + FREE(conf->reservation_key); + +@@ -584,6 +592,43 @@ free_config (struct config * conf) + FREE(conf); + } + ++/* if multipath fails to process the config directory, it should continue, ++ * with just a warning message */ ++static void ++process_config_dir(vector keywords, char *dir) ++{ ++ struct dirent **namelist; ++ int i, n; ++ char path[LINE_MAX]; ++ int old_hwtable_size; ++ ++ if (dir[0] != '/') { ++ condlog(1, "config_dir '%s' must be a fully qualified path", ++ dir); ++ return; ++ } ++ n = scandir(dir, &namelist, NULL, alphasort); ++ if (n < 0) { ++ if (errno == ENOENT) ++ condlog(3, "No configuration dir '%s'", dir); ++ else ++ condlog(0, "couldn't open configuration dir '%s': %s", ++ dir, strerror(errno)); ++ return; ++ } ++ for (i = 0; i < n; i++) { ++ if (!strstr(namelist[i]->d_name, ".conf")) ++ continue; ++ old_hwtable_size = VECTOR_SIZE(conf->hwtable); ++ snprintf(path, LINE_MAX, "%s/%s", dir, namelist[i]->d_name); ++ path[LINE_MAX-1] = '\0'; ++ process_file(path); ++ if (VECTOR_SIZE(conf->hwtable) > old_hwtable_size) ++ factorize_hwtable(conf->hwtable, old_hwtable_size); ++ ++ } ++} ++ + int + load_config (char * file, struct udev *udev) + { +@@ -623,6 +668,7 @@ load_config (char * file, struct udev *u + conf->hw_strmatch = 0; + conf->force_sync = 0; + conf->ignore_new_boot_devs = 0; ++ conf->processed_main_config = 0; + + /* + * preload default hwtable +@@ -641,11 +687,12 @@ load_config (char * file, struct udev *u + */ + set_current_keywords(&conf->keywords); + alloc_keywords(); ++ init_keywords(); + if (filepresent(file)) { + int builtin_hwtable_size; + + builtin_hwtable_size = VECTOR_SIZE(conf->hwtable); +- if (init_data(file, init_keywords)) { ++ if (process_file(file)) { + condlog(0, "error parsing config file"); + goto out; + } +@@ -658,7 +705,6 @@ load_config (char * file, struct udev *u + } + + } else { +- init_keywords(); + condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); + condlog(0, "A default multipath.conf file is located at"); + condlog(0, "/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf", MULTIPATH_VERSION(VERSION_CODE)); +@@ -677,6 +723,12 @@ load_config (char * file, struct udev *u + } + } + ++ conf->processed_main_config = 1; ++ if (conf->config_dir == NULL) ++ conf->config_dir = set_default(DEFAULT_CONFIG_DIR); ++ if (conf->config_dir && conf->config_dir[0] != '\0') ++ process_config_dir(conf->keywords, conf->config_dir); ++ + /* + * fill the voids left in the config file + */ +Index: multipath-tools-130222/libmultipath/config.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.h ++++ multipath-tools-130222/libmultipath/config.h +@@ -132,6 +132,7 @@ struct config { + int force_sync; + int deferred_remove; + int ignore_new_boot_devs; ++ int processed_main_config; + unsigned int version[3]; + + char * dev; +@@ -147,6 +148,7 @@ struct config { + char * prio_args; + char * checker_name; + char * alias_prefix; ++ char * config_dir; + unsigned char * reservation_key; + + vector keywords; +Index: multipath-tools-130222/libmultipath/defaults.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/defaults.h ++++ multipath-tools-130222/libmultipath/defaults.h +@@ -31,5 +31,6 @@ + #define DEFAULT_CONFIGFILE "/etc/multipath.conf" + #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" + #define DEFAULT_WWIDS_FILE "/etc/multipath/wwids" ++#define DEFAULT_CONFIG_DIR "/etc/multipath/conf.d" + + char * set_default (char * str); +Index: multipath-tools-130222/multipath.conf.annotated +=================================================================== +--- multipath-tools-130222.orig/multipath.conf.annotated ++++ multipath-tools-130222/multipath.conf.annotated +@@ -232,6 +232,16 @@ + # # values : yes|no + # # default : no + # force_sync yes ++# ++# # ++# # name : config_dir ++# # scope : multipath & multipathd ++# # desc : If not set to an empty string, multipath will search ++# # this directory alphabetically for files ending in ".conf" ++# # and it will read configuration information from these ++# # files, just as if it was in /etc/multipath.conf ++# # values : "" or a fully qualified pathname ++# # default : "/etc/multipath/conf.d" + #} + # + ## +Index: multipath-tools-130222/multipath.conf.defaults +=================================================================== +--- multipath-tools-130222.orig/multipath.conf.defaults ++++ multipath-tools-130222/multipath.conf.defaults +@@ -26,6 +26,7 @@ + # log_checker_err always + # retain_attached_hw_handler no + # detect_prio no ++# config_dir "/etc/multipath/conf.d" + #} + #blacklist { + # devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*" +Index: multipath-tools-130222/multipath/multipath.conf.5 +=================================================================== +--- multipath-tools-130222.orig/multipath/multipath.conf.5 ++++ multipath-tools-130222/multipath/multipath.conf.5 +@@ -452,6 +452,13 @@ still in use, it will be freed when the + to the multipath device before the last user closes it, the deferred remove + will be canceled. Default is + .I no ++.TP ++.B config_dir ++If set to anything other than "", multipath will search this directory ++alphabetically for file ending in ".conf" and it will read configuration ++information from them, just as if it was in /etc/multipath.conf. config_dir ++must either be "" or a fully qualified directory name. Default is ++.I "/etc/multipath/conf.d" + . + .SH "blacklist section" + The diff --git a/SOURCES/0113-RHBZ-1194917-cleanup.patch b/SOURCES/0113-RHBZ-1194917-cleanup.patch new file mode 100644 index 0000000..cf95c98 --- /dev/null +++ b/SOURCES/0113-RHBZ-1194917-cleanup.patch @@ -0,0 +1,185 @@ +--- + libmultipath/parser.c | 103 +++----------------------------------------------- + libmultipath/parser.h | 6 -- + 2 files changed, 8 insertions(+), 101 deletions(-) + +Index: multipath-tools-130222/libmultipath/parser.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/parser.c ++++ multipath-tools-130222/libmultipath/parser.c +@@ -280,8 +280,8 @@ out: + return NULL; + } + +-int +-read_line(char *buf, int size) ++static int ++read_line(FILE *stream, char *buf, int size) + { + int ch; + int count = 0; +@@ -297,95 +297,6 @@ read_line(char *buf, int size) + return (ch == EOF) ? 0 : 1; + } + +-vector +-read_value_block(void) +-{ +- char *buf; +- int i; +- char *str = NULL; +- char *dup; +- vector vec = NULL; +- vector elements = vector_alloc(); +- +- if (!elements) +- return NULL; +- +- buf = (char *) MALLOC(MAXBUF); +- +- if (!buf) { +- vector_free(elements); +- return NULL; +- } +- +- while (read_line(buf, MAXBUF)) { +- vec = alloc_strvec(buf); +- if (vec) { +- str = VECTOR_SLOT(vec, 0); +- if (!strcmp(str, EOB)) { +- free_strvec(vec); +- break; +- } +- +- for (i = 0; i < VECTOR_SIZE(vec); i++) { +- str = VECTOR_SLOT(vec, i); +- dup = (char *) MALLOC(strlen(str) + 1); +- if (!dup) +- goto out; +- memcpy(dup, str, strlen(str)); +- +- if (!vector_alloc_slot(elements)) { +- free_strvec(vec); +- goto out1; +- } +- +- vector_set_slot(elements, dup); +- } +- free_strvec(vec); +- } +- memset(buf, 0, MAXBUF); +- } +- FREE(buf); +- return elements; +-out1: +- FREE(dup); +-out: +- FREE(buf); +- vector_free(elements); +- return NULL; +-} +- +-int +-alloc_value_block(vector strvec, void (*alloc_func) (vector)) +-{ +- char *buf; +- char *str = NULL; +- vector vec = NULL; +- +- buf = (char *) MALLOC(MAXBUF); +- +- if (!buf) +- return 1; +- +- while (read_line(buf, MAXBUF)) { +- vec = alloc_strvec(buf); +- if (vec) { +- str = VECTOR_SLOT(vec, 0); +- if (!strcmp(str, EOB)) { +- free_strvec(vec); +- break; +- } +- +- if (VECTOR_SIZE(vec)) +- (*alloc_func) (vec); +- +- free_strvec(vec); +- } +- memset(buf, 0, MAXBUF); +- } +- FREE(buf); +- return 0; +-} +- + void * + set_value(vector strvec) + { +@@ -561,7 +472,7 @@ validate_config_strvec(vector strvec, ch + } + + static int +-process_stream(vector keywords, char *file) ++process_stream(FILE *stream, vector keywords, char *file) + { + int i; + int r = 0; +@@ -582,7 +493,7 @@ process_stream(vector keywords, char *fi + return 1; + } + +- while (read_line(buf, MAXBUF)) { ++ while (read_line(stream, buf, MAXBUF)) { + line_nr++; + strvec = alloc_strvec(buf); + memset(buf,0, MAXBUF); +@@ -621,7 +532,8 @@ process_stream(vector keywords, char *fi + + if (keyword->sub) { + kw_level++; +- r += process_stream(keyword->sub, file); ++ r += process_stream(stream, ++ keyword->sub, file); + kw_level--; + } + break; +@@ -656,6 +568,7 @@ int + process_file(char *file) + { + int r; ++ FILE *stream; + + if (!keywords) { + condlog(0, "No keywords alocated"); +@@ -670,7 +583,7 @@ process_file(char *file) + + /* Stream handling */ + line_nr = 0; +- r = process_stream(keywords, file); ++ r = process_stream(stream, keywords, file); + fclose(stream); + //free_keywords(keywords); + +Index: multipath-tools-130222/libmultipath/parser.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/parser.h ++++ multipath-tools-130222/libmultipath/parser.h +@@ -47,9 +47,6 @@ struct keyword { + int unique; + }; + +-/* global var exported */ +-FILE *stream; +- + /* Reloading helpers */ + #define SET_RELOAD (reload = 1) + #define UNSET_RELOAD (reload = 0) +@@ -72,9 +69,6 @@ extern int _install_keyword(char *string + extern void dump_keywords(vector keydump, int level); + extern void free_keywords(vector keywords); + extern vector alloc_strvec(char *string); +-extern int read_line(char *buf, int size); +-extern vector read_value_block(void); +-extern int alloc_value_block(vector strvec, void (*alloc_func) (vector)); + extern void *set_value(vector strvec); + extern int alloc_keywords(void); + extern int process_file(char *conf_file); diff --git a/SOURCES/0114-RHBZ-1196394-delayed-reintegration.patch b/SOURCES/0114-RHBZ-1196394-delayed-reintegration.patch new file mode 100644 index 0000000..b0647a5 --- /dev/null +++ b/SOURCES/0114-RHBZ-1196394-delayed-reintegration.patch @@ -0,0 +1,744 @@ +--- + libmultipath/checkers.c | 3 + libmultipath/checkers.h | 9 + + libmultipath/config.c | 4 + libmultipath/config.h | 6 + + libmultipath/configure.c | 2 + libmultipath/defaults.h | 1 + libmultipath/dict.c | 204 ++++++++++++++++++++++++++++++++++++++++++++- + libmultipath/print.c | 2 + libmultipath/propsel.c | 52 +++++++++++ + libmultipath/propsel.h | 2 + libmultipath/structs.h | 9 + + multipath.conf.annotated | 40 ++++++++ + multipath.conf.defaults | 2 + multipath/multipath.conf.5 | 27 +++++ + multipathd/main.c | 34 ++++++- + 15 files changed, 388 insertions(+), 9 deletions(-) + +Index: multipath-tools-130222/libmultipath/config.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.h ++++ multipath-tools-130222/libmultipath/config.h +@@ -62,6 +62,8 @@ struct hwentry { + int retain_hwhandler; + int detect_prio; + int deferred_remove; ++ int delay_watch_checks; ++ int delay_wait_checks; + char * bl_product; + }; + +@@ -86,6 +88,8 @@ struct mpentry { + int attribute_flags; + int user_friendly_names; + int deferred_remove; ++ int delay_watch_checks; ++ int delay_wait_checks; + uid_t uid; + gid_t gid; + mode_t mode; +@@ -133,6 +137,8 @@ struct config { + int deferred_remove; + int ignore_new_boot_devs; + int processed_main_config; ++ int delay_watch_checks; ++ int delay_wait_checks; + unsigned int version[3]; + + char * dev; +Index: multipath-tools-130222/libmultipath/structs.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/structs.h ++++ multipath-tools-130222/libmultipath/structs.h +@@ -134,6 +134,11 @@ enum scsi_protocol { + SCSI_PROTOCOL_UNSPEC = 0xf, /* No specific protocol */ + }; + ++enum delay_checks_states { ++ DELAY_CHECKS_OFF = -1, ++ DELAY_CHECKS_UNDEF = 0, ++}; ++ + struct sg_id { + int host_no; + int channel; +@@ -180,6 +185,8 @@ struct path { + int priority; + int pgindex; + int detect_prio; ++ int watch_checks; ++ int wait_checks; + char * uid_attribute; + struct prio prio; + char * prio_args; +@@ -215,6 +222,8 @@ struct multipath { + int fast_io_fail; + int retain_hwhandler; + int deferred_remove; ++ int delay_watch_checks; ++ int delay_wait_checks; + unsigned int dev_loss; + uid_t uid; + gid_t gid; +Index: multipath-tools-130222/libmultipath/checkers.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/checkers.h ++++ multipath-tools-130222/libmultipath/checkers.h +@@ -46,6 +46,14 @@ + * PATH_PENDING: + * - Use: All async checkers + * - Description: Indicates a check IO is in flight. ++ * ++ * PATH_DELAYED: ++ * - Use: None of the checkers (returned if the path is being delayed before ++ * reintegration. ++ * - Description: If a path fails after being up for less than ++ * delay_watch_checks checks, when it comes back up again, it will not ++ * be marked as up until it has been up for delay_wait_checks checks. ++ * During this time, it is marked as "delayed" + */ + enum path_check_state { + PATH_WILD, +@@ -55,6 +63,7 @@ enum path_check_state { + PATH_SHAKY, + PATH_GHOST, + PATH_PENDING, ++ PATH_DELAYED, + PATH_MAX_STATE + }; + +Index: multipath-tools-130222/libmultipath/configure.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/configure.c ++++ multipath-tools-130222/libmultipath/configure.c +@@ -291,6 +291,8 @@ setup_map (struct multipath * mpp, char + select_reservation_key(mpp); + select_retain_hwhandler(mpp); + select_deferred_remove(mpp); ++ select_delay_watch_checks(mpp); ++ select_delay_wait_checks(mpp); + + sysfs_set_scsi_tmo(mpp); + /* +Index: multipath-tools-130222/libmultipath/defaults.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/defaults.h ++++ multipath-tools-130222/libmultipath/defaults.h +@@ -20,6 +20,7 @@ + #define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_OFF + #define DEFAULT_DETECT_PRIO DETECT_PRIO_OFF + #define DEFAULT_DEFERRED_REMOVE DEFERRED_REMOVE_OFF ++#define DEFAULT_DELAY_CHECKS DELAY_CHECKS_OFF + + #define DEFAULT_CHECKINT 5 + #define MAX_CHECKINT(a) (a << 2) +Index: multipath-tools-130222/libmultipath/dict.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/dict.c ++++ multipath-tools-130222/libmultipath/dict.c +@@ -801,6 +801,44 @@ def_ignore_new_boot_devs_handler(vector + return 0; + } + ++static int ++def_delay_watch_checks_handler(vector strvec) ++{ ++ char * buff; ++ ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ ++ if ((strlen(buff) == 2 && !strcmp(buff, "no")) || ++ (strlen(buff) == 1 && !strcmp(buff, "0"))) ++ conf->delay_watch_checks = DELAY_CHECKS_OFF; ++ else if ((conf->delay_watch_checks = atoi(buff)) < 1) ++ conf->delay_watch_checks = DELAY_CHECKS_OFF; ++ ++ FREE(buff); ++ return 0; ++} ++ ++static int ++def_delay_wait_checks_handler(vector strvec) ++{ ++ char * buff; ++ ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ ++ if ((strlen(buff) == 2 && !strcmp(buff, "no")) || ++ (strlen(buff) == 1 && !strcmp(buff, "0"))) ++ conf->delay_wait_checks = DELAY_CHECKS_OFF; ++ else if ((conf->delay_wait_checks = atoi(buff)) < 1) ++ conf->delay_wait_checks = DELAY_CHECKS_OFF; ++ ++ FREE(buff); ++ return 0; ++} ++ + /* + * blacklist block handlers + */ +@@ -1517,6 +1555,52 @@ hw_deferred_remove_handler(vector strvec + return 0; + } + ++static int ++hw_delay_watch_checks_handler(vector strvec) ++{ ++ struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable); ++ char * buff; ++ ++ 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->delay_watch_checks = DELAY_CHECKS_OFF; ++ else if ((hwe->delay_watch_checks = atoi(buff)) < 1) ++ hwe->delay_watch_checks = DELAY_CHECKS_OFF; ++ ++ FREE(buff); ++ return 0; ++} ++ ++static int ++hw_delay_wait_checks_handler(vector strvec) ++{ ++ struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable); ++ char * buff; ++ ++ 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->delay_wait_checks = DELAY_CHECKS_OFF; ++ else if ((hwe->delay_wait_checks = atoi(buff)) < 1) ++ hwe->delay_wait_checks = DELAY_CHECKS_OFF; ++ ++ FREE(buff); ++ return 0; ++} ++ + /* + * multipaths block handlers + */ +@@ -1996,6 +2080,52 @@ mp_deferred_remove_handler(vector strvec + return 0; + } + ++static int ++mp_delay_watch_checks_handler(vector strvec) ++{ ++ struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable); ++ char * buff; ++ ++ if (!mpe) ++ return 1; ++ ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ ++ if ((strlen(buff) == 2 && !strcmp(buff, "no")) || ++ (strlen(buff) == 1 && !strcmp(buff, "0"))) ++ mpe->delay_watch_checks = DELAY_CHECKS_OFF; ++ else if ((mpe->delay_watch_checks = atoi(buff)) < 1) ++ mpe->delay_watch_checks = DELAY_CHECKS_OFF; ++ ++ FREE(buff); ++ return 0; ++} ++ ++static int ++mp_delay_wait_checks_handler(vector strvec) ++{ ++ struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable); ++ char * buff; ++ ++ if (!mpe) ++ return 1; ++ ++ buff = set_value(strvec); ++ if (!buff) ++ return 1; ++ ++ if ((strlen(buff) == 2 && !strcmp(buff, "no")) || ++ (strlen(buff) == 1 && !strcmp(buff, "0"))) ++ mpe->delay_wait_checks = DELAY_CHECKS_OFF; ++ else if ((mpe->delay_wait_checks = atoi(buff)) < 1) ++ mpe->delay_wait_checks = DELAY_CHECKS_OFF; ++ ++ FREE(buff); ++ return 0; ++} ++ + /* + * config file keywords printing + */ +@@ -2258,6 +2388,30 @@ snprint_mp_deferred_remove (char * buff, + } + + static int ++snprint_mp_delay_watch_checks(char * buff, int len, void * data) ++{ ++ struct mpentry * mpe = (struct mpentry *)data; ++ ++ if (mpe->delay_watch_checks == DELAY_CHECKS_UNDEF) ++ return 0; ++ if (mpe->delay_watch_checks == DELAY_CHECKS_OFF) ++ return snprintf(buff, len, "no"); ++ return snprintf(buff, len, "%d", mpe->delay_watch_checks); ++} ++ ++static int ++snprint_mp_delay_wait_checks(char * buff, int len, void * data) ++{ ++ struct mpentry * mpe = (struct mpentry *)data; ++ ++ if (mpe->delay_wait_checks == DELAY_CHECKS_UNDEF) ++ return 0; ++ if (mpe->delay_wait_checks == DELAY_CHECKS_OFF) ++ return snprintf(buff, len, "no"); ++ return snprintf(buff, len, "%d", mpe->delay_wait_checks); ++} ++ ++static int + snprint_hw_fast_io_fail(char * buff, int len, void * data) + { + struct hwentry * hwe = (struct hwentry *)data; +@@ -2586,6 +2740,30 @@ snprint_hw_deferred_remove(char * buff, + } + + static int ++snprint_hw_delay_watch_checks(char * buff, int len, void * data) ++{ ++ struct hwentry * hwe = (struct hwentry *)data; ++ ++ if (hwe->delay_watch_checks == DELAY_CHECKS_UNDEF) ++ return 0; ++ if (hwe->delay_watch_checks == DELAY_CHECKS_OFF) ++ return snprintf(buff, len, "no"); ++ return snprintf(buff, len, "%d", hwe->delay_watch_checks); ++} ++ ++static int ++snprint_hw_delay_wait_checks(char * buff, int len, void * data) ++{ ++ struct hwentry * hwe = (struct hwentry *)data; ++ ++ if (hwe->delay_wait_checks == DELAY_CHECKS_UNDEF) ++ return 0; ++ if (hwe->delay_wait_checks == DELAY_CHECKS_OFF) ++ return snprintf(buff, len, "no"); ++ return snprintf(buff, len, "%d", hwe->delay_wait_checks); ++} ++ ++static int + snprint_detect_prio(char * buff, int len, void * data) + { + struct hwentry * hwe = (struct hwentry *)data; +@@ -2883,7 +3061,6 @@ snprint_def_find_multipaths (char * buff + return snprintf(buff, len, "yes"); + } + +- + static int + snprint_def_user_friendly_names (char * buff, int len, void * data) + { +@@ -2989,7 +3166,6 @@ snprint_def_ignore_new_boot_devs(char * + return snprintf(buff, len, "no"); + } + +- + static int + snprint_def_config_dir (char * buff, int len, void * data) + { +@@ -3000,6 +3176,24 @@ snprint_def_config_dir (char * buff, int + } + + static int ++snprint_def_delay_watch_checks(char * buff, int len, void * data) ++{ ++ if (conf->delay_watch_checks == DELAY_CHECKS_UNDEF || ++ conf->delay_watch_checks == DELAY_CHECKS_OFF) ++ return snprintf(buff, len, "no"); ++ return snprintf(buff, len, "%d", conf->delay_watch_checks); ++} ++ ++static int ++snprint_def_delay_wait_checks(char * buff, int len, void * data) ++{ ++ if (conf->delay_wait_checks == DELAY_CHECKS_UNDEF || ++ conf->delay_wait_checks == DELAY_CHECKS_OFF) ++ return snprintf(buff, len, "no"); ++ return snprintf(buff, len, "%d", conf->delay_wait_checks); ++} ++ ++static int + snprint_ble_simple (char * buff, int len, void * data) + { + struct blentry * ble = (struct blentry *)data; +@@ -3071,6 +3265,8 @@ init_keywords(void) + install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove); + install_keyword("ignore_new_boot_devs", &def_ignore_new_boot_devs_handler, &snprint_def_ignore_new_boot_devs); + install_keyword("config_dir", &def_config_dir_handler, &snprint_def_config_dir); ++ install_keyword("delay_watch_checks", &def_delay_watch_checks_handler, &snprint_def_delay_watch_checks); ++ install_keyword("delay_wait_checks", &def_delay_wait_checks_handler, &snprint_def_delay_wait_checks); + __deprecated install_keyword("default_selector", &def_selector_handler, NULL); + __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); + __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); +@@ -3136,6 +3332,8 @@ init_keywords(void) + install_keyword("retain_attached_hw_handler", &hw_retain_hwhandler_handler, &snprint_hw_retain_hwhandler_handler); + install_keyword("detect_prio", &hw_detect_prio_handler, &snprint_detect_prio); + install_keyword("deferred_remove", &hw_deferred_remove_handler, &snprint_hw_deferred_remove); ++ install_keyword("delay_watch_checks", &hw_delay_watch_checks_handler, &snprint_hw_delay_watch_checks); ++ install_keyword("delay_wait_checks", &hw_delay_wait_checks_handler, &snprint_hw_delay_wait_checks); + install_sublevel_end(); + + install_keyword_root("multipaths", &multipaths_handler); +@@ -3161,5 +3359,7 @@ init_keywords(void) + install_keyword("reservation_key", &mp_reservation_key_handler, &snprint_mp_reservation_key); + install_keyword("user_friendly_names", &mp_names_handler, &snprint_mp_user_friendly_names); + install_keyword("deferred_remove", &mp_deferred_remove_handler, &snprint_mp_deferred_remove); ++ install_keyword("delay_watch_checks", &mp_delay_watch_checks_handler, &snprint_mp_delay_watch_checks); ++ install_keyword("delay_wait_checks", &mp_delay_wait_checks_handler, &snprint_mp_delay_wait_checks); + install_sublevel_end(); + } +Index: multipath-tools-130222/libmultipath/print.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/print.c ++++ multipath-tools-130222/libmultipath/print.c +@@ -336,6 +336,8 @@ snprint_chk_state (char * buff, size_t l + return snprintf(buff, len, "shaky"); + case PATH_GHOST: + return snprintf(buff, len, "ghost"); ++ case PATH_DELAYED: ++ return snprintf(buff, len, "delayed"); + default: + return snprintf(buff, len, "undef"); + } +Index: multipath-tools-130222/libmultipath/propsel.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/propsel.c ++++ multipath-tools-130222/libmultipath/propsel.c +@@ -788,3 +788,55 @@ select_detect_prio (struct path * pp) + condlog(3, "%s: detect_prio = %d (compiled in default)", pp->dev, pp->detect_prio); + return 0; + } ++ ++extern int ++select_delay_watch_checks (struct multipath * mp) ++{ ++ if (mp->mpe && mp->mpe->delay_watch_checks != DELAY_CHECKS_UNDEF) { ++ mp->delay_watch_checks = mp->mpe->delay_watch_checks; ++ condlog(3, "delay_watch_checks = %i (multipath setting)", ++ mp->delay_watch_checks); ++ return 0; ++ } ++ if (mp->hwe && mp->hwe->delay_watch_checks != DELAY_CHECKS_UNDEF) { ++ mp->delay_watch_checks = mp->hwe->delay_watch_checks; ++ condlog(3, "delay_watch_checks = %i (controler setting)", ++ mp->delay_watch_checks); ++ return 0; ++ } ++ if (conf->delay_watch_checks != DELAY_CHECKS_UNDEF) { ++ mp->delay_watch_checks = conf->delay_watch_checks; ++ condlog(3, "delay_watch_checks = %i (config file default)", ++ mp->delay_watch_checks); ++ return 0; ++ } ++ mp->delay_watch_checks = DEFAULT_DELAY_CHECKS; ++ condlog(3, "delay_watch_checks = DISABLED (internal default)"); ++ return 0; ++} ++ ++extern int ++select_delay_wait_checks (struct multipath * mp) ++{ ++ if (mp->mpe && mp->mpe->delay_wait_checks != DELAY_CHECKS_UNDEF) { ++ mp->delay_wait_checks = mp->mpe->delay_wait_checks; ++ condlog(3, "delay_wait_checks = %i (multipath setting)", ++ mp->delay_wait_checks); ++ return 0; ++ } ++ if (mp->hwe && mp->hwe->delay_wait_checks != DELAY_CHECKS_UNDEF) { ++ mp->delay_wait_checks = mp->hwe->delay_wait_checks; ++ condlog(3, "delay_wait_checks = %i (controler setting)", ++ mp->delay_wait_checks); ++ return 0; ++ } ++ if (conf->delay_wait_checks != DELAY_CHECKS_UNDEF) { ++ mp->delay_wait_checks = conf->delay_wait_checks; ++ condlog(3, "delay_wait_checks = %i (config file default)", ++ mp->delay_wait_checks); ++ return 0; ++ } ++ mp->delay_wait_checks = DEFAULT_DELAY_CHECKS; ++ condlog(3, "delay_wait_checks = DISABLED (internal default)"); ++ return 0; ++} +Index: multipath-tools-130222/libmultipath/propsel.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/propsel.h ++++ multipath-tools-130222/libmultipath/propsel.h +@@ -21,3 +21,5 @@ int select_reservation_key(struct multip + int select_retain_hwhandler (struct multipath * mp); + int select_detect_prio(struct path * pp); + int select_deferred_remove(struct multipath *mp); ++int select_delay_watch_checks (struct multipath * mp); ++int select_delay_wait_checks (struct multipath * mp); +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -188,7 +188,8 @@ sync_map_state(struct multipath *mpp) + vector_foreach_slot (mpp->pg, pgp, i){ + vector_foreach_slot (pgp->paths, pp, j){ + if (pp->state == PATH_UNCHECKED || +- pp->state == PATH_WILD) ++ pp->state == PATH_WILD || ++ pp->state == PATH_DELAYED) + continue; + if ((pp->dmstate == PSTATE_FAILED || + pp->dmstate == PSTATE_UNDEF) && +@@ -1165,6 +1166,16 @@ check_path (struct vectors * vecs, struc + if (!pp->mpp) + return; + ++ if ((newstate == PATH_UP || newstate == PATH_GHOST) && ++ pp->wait_checks > 0) { ++ if (pp->mpp && pp->mpp->nr_active > 0) { ++ pp->state = PATH_DELAYED; ++ pp->wait_checks--; ++ return; ++ } else ++ pp->wait_checks = 0; ++ } ++ + pp->chkrstate = newstate; + if (newstate != pp->state) { + int oldstate = pp->state; +@@ -1182,9 +1193,14 @@ check_path (struct vectors * vecs, struc + * proactively fail path in the DM + */ + if (oldstate == PATH_UP || +- oldstate == PATH_GHOST) ++ oldstate == PATH_GHOST) { + fail_path(pp, 1); +- else ++ if (pp->mpp->delay_wait_checks > 0 && ++ pp->watch_checks > 0) { ++ pp->wait_checks = pp->mpp->delay_wait_checks; ++ pp->watch_checks = 0; ++ } ++ }else + fail_path(pp, 0); + + /* +@@ -1211,11 +1227,15 @@ check_path (struct vectors * vecs, struc + * reinstate this path + */ + if (oldstate != PATH_UP && +- oldstate != PATH_GHOST) ++ oldstate != PATH_GHOST) { ++ if (pp->mpp->delay_watch_checks > 0) ++ pp->watch_checks = pp->mpp->delay_watch_checks; + reinstate_path(pp, 1); +- else ++ } else { ++ if (pp->watch_checks > 0) ++ pp->watch_checks--; + reinstate_path(pp, 0); +- ++ } + new_path_up = 1; + + if (oldchkrstate != PATH_UP && oldchkrstate != PATH_GHOST) +@@ -1245,6 +1265,8 @@ check_path (struct vectors * vecs, struc + else + pp->checkint = conf->max_checkint; + } ++ if (pp->watch_checks > 0) ++ pp->watch_checks--; + pp->tick = pp->checkint; + condlog(4, "%s: delay next check %is", + pp->dev_t, pp->tick); +Index: multipath-tools-130222/multipath.conf.annotated +=================================================================== +--- multipath-tools-130222.orig/multipath.conf.annotated ++++ multipath-tools-130222/multipath.conf.annotated +@@ -242,6 +242,30 @@ + # # files, just as if it was in /etc/multipath.conf + # # values : "" or a fully qualified pathname + # # default : "/etc/multipath/conf.d" ++# ++# # ++# # name : delay_watch_checks ++# # scope : multipathd ++# # desc : If set to a value greater than 0, multipathd will watch ++# # paths that have recently become valid for this many ++# # checks. If they fail again while they are being watched, ++# # when they next become valid, they will not be used until ++# # they have stayed up for delay_wait_checks checks. ++# # values : no| > 0 ++# # default : no ++# delay_watch_checks 12 ++# ++# # ++# # name : delay_wait_checks ++# # scope : multipathd ++# # desc : If set to a value greater than 0, when a device that has ++# # recently come back online fails again within ++# # delay_watch_checks checks, the next time it comes back ++# # online, it will marked and delayed, and not used until ++# # it has passed delay_wait_checks checks. ++# # values : no| > 0 ++# # default : no ++# delay_wait_checks 12 + #} + # + ## +@@ -383,6 +407,13 @@ + # # + # flush_on_last_del yes + # ++# # ++# # name : delay_watch_checks ++# # See defualts section for information. ++# ++# # ++# # name : delay_wait_checks ++# # See defualts section for information. + # } + # multipath { + # wwid 1DEC_____321816758474 +@@ -566,6 +597,15 @@ + # # before removing it from the system. + # # values : n > 0 + # dev_loss_tmo 600 ++# ++# # ++# # name : delay_watch_checks ++# # See defaults section for information. ++# ++# # ++# # name : delay_wait_checks ++# # See defaults section for information. ++# + # } + # device { + # vendor "COMPAQ " +Index: multipath-tools-130222/multipath.conf.defaults +=================================================================== +--- multipath-tools-130222.orig/multipath.conf.defaults ++++ multipath-tools-130222/multipath.conf.defaults +@@ -27,6 +27,8 @@ + # retain_attached_hw_handler no + # detect_prio no + # config_dir "/etc/multipath/conf.d" ++# delay_watch_checks no ++# delay_wait_checks no + #} + #blacklist { + # devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*" +Index: multipath-tools-130222/multipath/multipath.conf.5 +=================================================================== +--- multipath-tools-130222.orig/multipath/multipath.conf.5 ++++ multipath-tools-130222/multipath/multipath.conf.5 +@@ -459,6 +459,25 @@ alphabetically for file ending in ".conf + information from them, just as if it was in /etc/multipath.conf. config_dir + must either be "" or a fully qualified directory name. Default is + .I "/etc/multipath/conf.d" ++.TP ++.B delay_watch_checks ++If set to a value greater than 0, multipathd will watch paths that have ++recently become valid for this many checks. If they fail again while they are ++being watched, when they next become valid, they will not be used until they ++have stayed up for ++.I delay_wait_checks ++checks. Default is ++.I no ++.TP ++.B delay_wait_checks ++If set to a value greater than 0, when a device that has recently come back ++online fails again within ++.I delay_watch_checks ++checks, the next time it comes back online, it will marked and delayed, and not ++used until it has passed ++.I delay_wait_checks ++checks. Default is ++.I no + . + .SH "blacklist section" + The +@@ -562,6 +581,10 @@ section: + .B reservation_key + .TP + .B deferred_remove ++.TP ++.B delay_watch_checks ++.TP ++.B delay_wait_checks + .RE + .PD + .LP +@@ -654,6 +677,10 @@ section: + .B detect_prio + .TP + .B deferred_remove ++.TP ++.B delay_watch_checks ++.TP ++.B delay_wait_checks + .RE + .PD + .LP +Index: multipath-tools-130222/libmultipath/checkers.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/checkers.c ++++ multipath-tools-130222/libmultipath/checkers.c +@@ -16,7 +16,8 @@ char *checker_state_names[] = { + "up", + "shaky", + "ghost", +- "pending" ++ "pending", ++ "delayed" + }; + + static LIST_HEAD(checkers); +Index: multipath-tools-130222/libmultipath/config.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.c ++++ multipath-tools-130222/libmultipath/config.c +@@ -341,6 +341,8 @@ merge_hwe (struct hwentry * dst, struct + merge_num(retain_hwhandler); + merge_num(detect_prio); + merge_num(deferred_remove); ++ merge_num(delay_watch_checks); ++ merge_num(delay_wait_checks); + + /* + * Make sure features is consistent with +@@ -399,6 +401,8 @@ overwrite_hwe (struct hwentry * dst, str + overwrite_num(retain_hwhandler); + overwrite_num(detect_prio); + overwrite_num(deferred_remove); ++ overwrite_num(delay_watch_checks); ++ overwrite_num(delay_wait_checks); + + /* + * Make sure features is consistent with diff --git a/SOURCES/0115-RHBZ-1198418-fix-double-free.patch b/SOURCES/0115-RHBZ-1198418-fix-double-free.patch new file mode 100644 index 0000000..a403760 --- /dev/null +++ b/SOURCES/0115-RHBZ-1198418-fix-double-free.patch @@ -0,0 +1,28 @@ +--- + multipathd/main.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -310,10 +310,15 @@ ev_add_map (char * dev, char * alias, st + /* + * now we can register the map + */ +- if (map_present && (mpp = add_map_without_path(vecs, alias))) { +- sync_map_state(mpp); +- condlog(2, "%s: devmap %s registered", alias, dev); +- return 0; ++ if (map_present) { ++ if ((mpp = add_map_without_path(vecs, alias))) { ++ sync_map_state(mpp); ++ condlog(2, "%s: devmap %s registered", alias, dev); ++ return 0; ++ } else { ++ condlog(2, "%s: uev_add_map failed", dev); ++ return 1; ++ } + } + r = get_refwwid(dev, DEV_DEVMAP, vecs->pathvec, &refwwid); + diff --git a/SOURCES/0116-UPBZ-1188179-dell-36xxi.patch b/SOURCES/0116-UPBZ-1188179-dell-36xxi.patch new file mode 100644 index 0000000..e32118b --- /dev/null +++ b/SOURCES/0116-UPBZ-1188179-dell-36xxi.patch @@ -0,0 +1,83 @@ +--- + libmultipath/hwtable.c | 30 ++++++++++++++++++++++++++++++ + multipath.conf.defaults | 26 ++++++++++++++++++++++++++ + 2 files changed, 56 insertions(+) + +Index: multipath-tools-130222/libmultipath/hwtable.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/hwtable.c ++++ multipath-tools-130222/libmultipath/hwtable.c +@@ -772,6 +772,36 @@ static struct hwentry default_hw[] = { + .prio_name = PRIO_RDAC, + .prio_args = NULL, + }, ++ { ++ /* DELL MD36xxi */ ++ .vendor = "DELL", ++ .product = "MD36xxi", ++ .bl_product = "Universal Xport", ++ .features = "2 pg_init_retries 50", ++ .hwhandler = "1 rdac", ++ .pgpolicy = GROUP_BY_PRIO, ++ .pgfailback = -FAILBACK_IMMEDIATE, ++ .rr_weight = RR_WEIGHT_NONE, ++ .no_path_retry = 15, ++ .checker_name = RDAC, ++ .prio_name = PRIO_RDAC, ++ .prio_args = NULL, ++ }, ++ { ++ /* DELL MD36xxf */ ++ .vendor = "DELL", ++ .product = "MD36xxf", ++ .bl_product = "Universal Xport", ++ .features = "2 pg_init_retries 50", ++ .hwhandler = "1 rdac", ++ .pgpolicy = GROUP_BY_PRIO, ++ .pgfailback = -FAILBACK_IMMEDIATE, ++ .rr_weight = RR_WEIGHT_NONE, ++ .no_path_retry = 15, ++ .checker_name = RDAC, ++ .prio_name = PRIO_RDAC, ++ .prio_args = NULL, ++ }, + /* + * NETAPP controller family + * +Index: multipath-tools-130222/multipath.conf.defaults +=================================================================== +--- multipath-tools-130222.orig/multipath.conf.defaults ++++ multipath-tools-130222/multipath.conf.defaults +@@ -655,6 +655,32 @@ + # no_path_retry 15 + # } + # device { ++# vendor "DELL" ++# product "MD36xxi" ++# product_blacklist "Universal Xport" ++# path_grouping_policy "group_by_prio" ++# path_checker "rdac" ++# features "2 pg_init_retries 50" ++# hardware_handler "1 rdac" ++# prio "rdac" ++# failback "immediate" ++# rr_weight "uniform" ++# no_path_retry 15 ++# } ++# device { ++# vendor "DELL" ++# product "MD36xxf" ++# product_blacklist "Universal Xport" ++# path_grouping_policy "group_by_prio" ++# path_checker "rdac" ++# features "2 pg_init_retries 50" ++# hardware_handler "1 rdac" ++# prio "rdac" ++# failback "immediate" ++# rr_weight "uniform" ++# no_path_retry 15 ++# } ++# device { + # vendor "NETAPP" + # product "LUN.*" + # path_grouping_policy "group_by_prio" diff --git a/SOURCES/0117-RHBZ-1198424-autodetect-clariion-alua.patch b/SOURCES/0117-RHBZ-1198424-autodetect-clariion-alua.patch new file mode 100644 index 0000000..64a302d --- /dev/null +++ b/SOURCES/0117-RHBZ-1198424-autodetect-clariion-alua.patch @@ -0,0 +1,31 @@ +--- + libmultipath/hwtable.c | 2 ++ + multipath.conf.defaults | 2 ++ + 2 files changed, 4 insertions(+) + +Index: multipath-tools-130222/libmultipath/hwtable.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/hwtable.c ++++ multipath-tools-130222/libmultipath/hwtable.c +@@ -272,6 +272,8 @@ static struct hwentry default_hw[] = { + .checker_name = EMC_CLARIION, + .prio_name = PRIO_EMC, + .prio_args = NULL, ++ .retain_hwhandler = RETAIN_HWHANDLER_ON, ++ .detect_prio = DETECT_PRIO_ON, + }, + { + .vendor = "EMC", +Index: multipath-tools-130222/multipath.conf.defaults +=================================================================== +--- multipath-tools-130222.orig/multipath.conf.defaults ++++ multipath-tools-130222/multipath.conf.defaults +@@ -261,6 +261,8 @@ + # failback immediate + # rr_weight "uniform" + # no_path_retry 60 ++# retain_attached_hw_handler yes ++# detect_prio yes + # } + # device { + # vendor "EMC" diff --git a/SOURCES/0118-UPBZ-1200738-update-eternus-config.patch b/SOURCES/0118-UPBZ-1200738-update-eternus-config.patch new file mode 100644 index 0000000..10e96e3 --- /dev/null +++ b/SOURCES/0118-UPBZ-1200738-update-eternus-config.patch @@ -0,0 +1,31 @@ +--- + libmultipath/hwtable.c | 2 +- + multipath.conf.defaults | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +Index: multipath-tools-130222/libmultipath/hwtable.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/hwtable.c ++++ multipath-tools-130222/libmultipath/hwtable.c +@@ -310,7 +310,7 @@ static struct hwentry default_hw[] = { + }, + { + .vendor = "FUJITSU", +- .product = "ETERNUS_DX(L|400|8000)", ++ .product = "ETERNUS_DX(H|L|M|400|8000)", + .features = "1 queue_if_no_path", + .hwhandler = DEFAULT_HWHANDLER, + .pgpolicy = GROUP_BY_PRIO, +Index: multipath-tools-130222/multipath.conf.defaults +=================================================================== +--- multipath-tools-130222.orig/multipath.conf.defaults ++++ multipath-tools-130222/multipath.conf.defaults +@@ -288,7 +288,7 @@ + # } + # device { + # vendor "FUJITSU" +-# product "ETERNUS_DX(L|400|8000)" ++# product "ETERNUS_DX(H|L|M|400|8000)" + # path_grouping_policy "group_by_prio" + # path_checker "tur" + # features "1 queue_if_no_path" diff --git a/SOURCES/0119-RHBZ-1081397-save-alua-info.patch b/SOURCES/0119-RHBZ-1081397-save-alua-info.patch new file mode 100644 index 0000000..c9913f3 --- /dev/null +++ b/SOURCES/0119-RHBZ-1081397-save-alua-info.patch @@ -0,0 +1,565 @@ +--- + libmultipath/prio.c | 34 ++++++++++++++++- + libmultipath/prio.h | 7 +++ + libmultipath/prioritizers/alua.c | 62 +++++++++++++++++++++++-------- + libmultipath/prioritizers/alua_rtpg.c | 22 +++++++++-- + libmultipath/prioritizers/alua_rtpg.h | 4 +- + libmultipath/prioritizers/const.c | 4 ++ + libmultipath/prioritizers/datacore.c | 3 + + libmultipath/prioritizers/def_func.h | 11 +++++ + libmultipath/prioritizers/emc.c | 4 ++ + libmultipath/prioritizers/hds.c | 4 ++ + libmultipath/prioritizers/hp_sw.c | 4 ++ + libmultipath/prioritizers/iet.c | 4 ++ + libmultipath/prioritizers/ontap.c | 4 ++ + libmultipath/prioritizers/random.c | 4 ++ + libmultipath/prioritizers/rdac.c | 4 ++ + libmultipath/prioritizers/weightedpath.c | 3 + + libmultipath/propsel.c | 4 +- + multipathd/main.c | 24 ++++++++---- + 18 files changed, 174 insertions(+), 32 deletions(-) + +Index: multipath-tools-130222/libmultipath/prio.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prio.c ++++ multipath-tools-130222/libmultipath/prio.c +@@ -112,9 +112,24 @@ struct prio * add_prio (char * name) + p->getprio = (int (*)(struct path *, char *)) dlsym(p->handle, "getprio"); + errstr = dlerror(); + if (errstr != NULL) +- condlog(0, "A dynamic linking error occurred: (%s)", errstr); ++ condlog(0, "A dynamic linking error occurred with getprio: (%s)", errstr); + if (!p->getprio) + goto out; ++ ++ p->initprio = (int (*)(struct prio *)) dlsym(p->handle, "initprio"); ++ errstr = dlerror(); ++ if (errstr != NULL) ++ condlog(0, "A dynamic linking error occurred with initprio: (%s)", errstr); ++ if (!p->initprio) ++ goto out; ++ ++ p->freeprio = (int (*)(struct prio *)) dlsym(p->handle, "freeprio"); ++ errstr = dlerror(); ++ if (errstr != NULL) ++ condlog(0, "A dynamic linking error occurred with freeprio: (%s)", errstr); ++ if (!p->freeprio) ++ goto out; ++ + list_add(&p->node, &prioritizers); + return p; + out: +@@ -122,6 +137,13 @@ out: + return NULL; + } + ++int prio_init (struct prio * p) ++{ ++ if (!p || !p->initprio) ++ return 1; ++ return p->initprio(p); ++} ++ + int prio_getprio (struct prio * p, struct path * pp) + { + return p->getprio(pp, p->args); +@@ -156,8 +178,16 @@ void prio_get (struct prio * dst, char * + strncpy(dst->name, src->name, PRIO_NAME_LEN); + if (args) + strncpy(dst->args, args, PRIO_ARGS_LEN); ++ dst->initprio = src->initprio; + dst->getprio = src->getprio; ++ dst->freeprio = src->freeprio; + dst->handle = NULL; ++ dst->context = NULL; ++ ++ if (dst->initprio(dst) != 0){ ++ memset(dst, 0x0, sizeof(struct prio)); ++ return; ++ } + + src->refcount++; + } +@@ -173,6 +203,8 @@ void prio_put (struct prio * dst) + src = NULL; + else + src = prio_lookup(dst->name); ++ if (dst->freeprio) ++ dst->freeprio(dst); + memset(dst, 0x0, sizeof(struct prio)); + free_prio(src); + } +Index: multipath-tools-130222/libmultipath/prio.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prio.h ++++ multipath-tools-130222/libmultipath/prio.h +@@ -46,9 +46,15 @@ struct prio { + void *handle; + int refcount; + struct list_head node; ++ void * context; + char name[PRIO_NAME_LEN]; + char args[PRIO_ARGS_LEN]; ++ int (*initprio)(struct prio * p); ++ /* You are allowed to call initprio multiple times without calling ++ * freeprio. Doing so will reinitialize it (possibly skipping ++ * allocations) */ + int (*getprio)(struct path *, char *); ++ int (*freeprio)(struct prio * p); + }; + + unsigned int get_prio_timeout(unsigned int default_timeout); +@@ -57,6 +63,7 @@ void cleanup_prio (void); + struct prio * add_prio (char *); + struct prio * prio_lookup (char *); + int prio_getprio (struct prio *, struct path *); ++int prio_init (struct prio *); + void prio_get (struct prio *, char *, char *); + void prio_put (struct prio *); + int prio_selected (struct prio *); +Index: multipath-tools-130222/libmultipath/prioritizers/alua.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/alua.c ++++ multipath-tools-130222/libmultipath/prioritizers/alua.c +@@ -37,6 +37,12 @@ static const char * aas_string[] = { + [AAS_TRANSITIONING] = "transitioning between states", + }; + ++struct alua_context { ++ int tpg_support; ++ int tpg; ++ int buflen; ++}; ++ + static const char *aas_print_string(int rc) + { + rc &= 0x7f; +@@ -51,25 +57,26 @@ static const char *aas_print_string(int + } + + int +-get_alua_info(int fd) ++get_alua_info(int fd, struct alua_context *ct) + { + int rc; +- int tpg; + int aas; + +- rc = get_target_port_group_support(fd); +- if (rc < 0) +- return -ALUA_PRIO_TPGS_FAILED; +- +- if (rc == TPGS_NONE) +- return -ALUA_PRIO_NOT_SUPPORTED; +- +- tpg = get_target_port_group(fd); +- if (tpg < 0) +- return -ALUA_PRIO_RTPG_FAILED; ++ if (ct->tpg_support <= 0 || ct->tpg < 0) { ++ ct->tpg_support = get_target_port_group_support(fd); ++ if (ct->tpg_support < 0) ++ return -ALUA_PRIO_TPGS_FAILED; ++ ++ if (ct->tpg_support == TPGS_NONE) ++ return -ALUA_PRIO_NOT_SUPPORTED; ++ ++ ct->tpg = get_target_port_group(fd, &ct->buflen); ++ if (ct->tpg < 0) ++ return -ALUA_PRIO_RTPG_FAILED; ++ } + +- condlog(3, "reported target port group is %i", tpg); +- rc = get_asymmetric_access_state(fd, tpg); ++ condlog(3, "reported target port group is %i", ct->tpg); ++ rc = get_asymmetric_access_state(fd, ct->tpg, &ct->buflen); + if (rc < 0) + return -ALUA_PRIO_GETAAS_FAILED; + aas = (rc & 0x0f); +@@ -88,7 +95,7 @@ int getprio (struct path * pp, char * ar + if (pp->fd < 0) + return -ALUA_PRIO_NO_INFORMATION; + +- rc = get_alua_info(pp->fd); ++ rc = get_alua_info(pp->fd, pp->prio.context); + if (rc >= 0) { + aas = (rc & 0x0f); + priopath = (rc & 0x80); +@@ -128,3 +135,28 @@ int getprio (struct path * pp, char * ar + } + return rc; + } ++ ++int initprio(struct prio *p) ++{ ++ if (!p->context) { ++ struct alua_context *ct; ++ ++ ct = malloc(sizeof(struct alua_context)); ++ if (!ct) ++ return 1; ++ p->context = ct; ++ } ++ memset(p->context, 0, sizeof(struct alua_context)); ++ return 0; ++} ++ ++ ++int freeprio(struct prio *p) ++{ ++ if (p->context) { ++ free(p->context); ++ p->context = NULL; ++ } ++ return 0; ++} ++ +Index: multipath-tools-130222/libmultipath/prioritizers/alua_rtpg.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/alua_rtpg.c ++++ multipath-tools-130222/libmultipath/prioritizers/alua_rtpg.c +@@ -171,7 +171,7 @@ get_target_port_group_support(int fd) + } + + int +-get_target_port_group(int fd) ++get_target_port_group(int fd, int *buflen_ptr) + { + unsigned char *buf; + struct vpd83_data * vpd83; +@@ -179,7 +179,12 @@ get_target_port_group(int fd) + int rc; + int buflen, scsi_buflen; + +- buflen = 128; /* Lets start from 128 */ ++ if (!buflen_ptr || *buflen_ptr == 0) { ++ buflen = 128; /* Lets start from 128 */ ++ if (buflen_ptr) ++ *buflen_ptr = 128; ++ } else ++ buflen = *buflen_ptr; + buf = (unsigned char *)malloc(buflen); + if (!buf) { + PRINT_DEBUG("malloc failed: could not allocate" +@@ -202,6 +207,8 @@ get_target_port_group(int fd) + return -RTPG_RTPG_FAILED; + } + buflen = scsi_buflen; ++ if (buflen_ptr) ++ *buflen_ptr = buflen; + memset(buf, 0, buflen); + rc = do_inquiry(fd, 1, 0x83, buf, buflen); + if (rc < 0) +@@ -269,7 +276,7 @@ do_rtpg(int fd, void* resp, long resplen + } + + int +-get_asymmetric_access_state(int fd, unsigned int tpg) ++get_asymmetric_access_state(int fd, unsigned int tpg, int *buflen_ptr) + { + unsigned char *buf; + struct rtpg_data * tpgd; +@@ -278,7 +285,12 @@ get_asymmetric_access_state(int fd, unsi + int buflen; + uint32_t scsi_buflen; + +- buflen = 128; /* Initial value from old code */ ++ if (!buflen_ptr || *buflen_ptr == 0) { ++ buflen = 128; /* Initial value from old code */ ++ if (buflen_ptr) ++ *buflen_ptr = 128; ++ } else ++ buflen = *buflen_ptr; + buf = (unsigned char *)malloc(buflen); + if (!buf) { + PRINT_DEBUG ("malloc failed: could not allocate" +@@ -299,6 +311,8 @@ get_asymmetric_access_state(int fd, unsi + return -RTPG_RTPG_FAILED; + } + buflen = scsi_buflen; ++ if (buflen_ptr) ++ *buflen_ptr = buflen; + memset(buf, 0, buflen); + rc = do_rtpg(fd, buf, buflen); + if (rc < 0) +Index: multipath-tools-130222/libmultipath/prioritizers/alua_rtpg.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/alua_rtpg.h ++++ multipath-tools-130222/libmultipath/prioritizers/alua_rtpg.h +@@ -23,8 +23,8 @@ + #define RTPG_TPG_NOT_FOUND 4 + + int get_target_port_group_support(int fd); +-int get_target_port_group(int fd); +-int get_asymmetric_access_state(int fd, unsigned int tpg); ++int get_target_port_group(int fd, int *buflen_ptr); ++int get_asymmetric_access_state(int fd, unsigned int tpg, int *buflen_ptr); + + #endif /* __RTPG_H__ */ + +Index: multipath-tools-130222/libmultipath/prioritizers/const.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/const.c ++++ multipath-tools-130222/libmultipath/prioritizers/const.c +@@ -1,8 +1,12 @@ + #include + + #include ++#include "def_func.h" + + int getprio (struct path * pp, char * args) + { + return 1; + } ++ ++declare_nop_prio(initprio) ++declare_nop_prio(freeprio) +Index: multipath-tools-130222/libmultipath/prioritizers/datacore.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/datacore.c ++++ multipath-tools-130222/libmultipath/prioritizers/datacore.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include "def_func.h" + + #define INQ_REPLY_LEN 255 + #define INQ_CMD_CODE 0x12 +@@ -111,3 +112,5 @@ int getprio (struct path * pp, char * ar + return datacore_prio(pp->dev, pp->fd, args); + } + ++declare_nop_prio(initprio) ++declare_nop_prio(freeprio) +Index: multipath-tools-130222/libmultipath/prioritizers/def_func.h +=================================================================== +--- /dev/null ++++ multipath-tools-130222/libmultipath/prioritizers/def_func.h +@@ -0,0 +1,11 @@ ++#ifndef _DEF_FUNC_H ++#define _DEF_FUNC_H ++ ++#include "prio.h" ++ ++#define declare_nop_prio(name) \ ++int name (struct prio *p) \ ++{ \ ++ return 0; \ ++} ++#endif /* _DEF_FUNC_H */ +Index: multipath-tools-130222/libmultipath/prioritizers/emc.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/emc.c ++++ multipath-tools-130222/libmultipath/prioritizers/emc.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include "def_func.h" + + #define INQUIRY_CMD 0x12 + #define INQUIRY_CMDLEN 6 +@@ -85,3 +86,6 @@ int getprio (struct path * pp, char * ar + { + return emc_clariion_prio(pp->dev, pp->fd); + } ++ ++declare_nop_prio(initprio) ++declare_nop_prio(freeprio) +Index: multipath-tools-130222/libmultipath/prioritizers/hds.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/hds.c ++++ multipath-tools-130222/libmultipath/prioritizers/hds.c +@@ -76,6 +76,7 @@ + #include + #include + #include ++#include "def_func.h" + + #define INQ_REPLY_LEN 255 + #define INQ_CMD_CODE 0x12 +@@ -170,3 +171,6 @@ int getprio (struct path * pp, char * ar + { + return hds_modular_prio(pp->dev, pp->fd); + } ++ ++declare_nop_prio(initprio) ++declare_nop_prio(freeprio) +Index: multipath-tools-130222/libmultipath/prioritizers/hp_sw.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/hp_sw.c ++++ multipath-tools-130222/libmultipath/prioritizers/hp_sw.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include "def_func.h" + + #define TUR_CMD_LEN 6 + #define SCSI_CHECK_CONDITION 0x2 +@@ -99,3 +100,6 @@ int getprio (struct path * pp, char * ar + { + return hp_sw_prio(pp->dev, pp->fd); + } ++ ++declare_nop_prio(initprio) ++declare_nop_prio(freeprio) +Index: multipath-tools-130222/libmultipath/prioritizers/iet.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/iet.c ++++ multipath-tools-130222/libmultipath/prioritizers/iet.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include "def_func.h" + + // + // This prioritizer suits iSCSI needs, makes it possible to prefer one path. +@@ -141,3 +142,6 @@ int getprio(struct path * pp, char * arg + { + return iet_prio(pp->dev, args); + } ++ ++declare_nop_prio(initprio) ++declare_nop_prio(freeprio) +Index: multipath-tools-130222/libmultipath/prioritizers/ontap.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/ontap.c ++++ multipath-tools-130222/libmultipath/prioritizers/ontap.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include "def_func.h" + + #define INQUIRY_CMD 0x12 + #define INQUIRY_CMDLEN 6 +@@ -245,3 +246,6 @@ int getprio (struct path * pp, char * ar + { + return ontap_prio(pp->dev, pp->fd); + } ++ ++declare_nop_prio(initprio) ++declare_nop_prio(freeprio) +Index: multipath-tools-130222/libmultipath/prioritizers/random.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/random.c ++++ multipath-tools-130222/libmultipath/prioritizers/random.c +@@ -4,6 +4,7 @@ + #include + + #include ++#include "def_func.h" + + int getprio (struct path * pp, char * args) + { +@@ -13,3 +14,6 @@ int getprio (struct path * pp, char * ar + srand((unsigned int)tv.tv_usec); + return 1+(int) (10.0*rand()/(RAND_MAX+1.0)); + } ++ ++declare_nop_prio(initprio) ++declare_nop_prio(freeprio) +Index: multipath-tools-130222/libmultipath/prioritizers/rdac.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/rdac.c ++++ multipath-tools-130222/libmultipath/prioritizers/rdac.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include "def_func.h" + + #define INQUIRY_CMD 0x12 + #define INQUIRY_CMDLEN 6 +@@ -95,3 +96,6 @@ int getprio (struct path * pp, char * ar + { + return rdac_prio(pp->dev, pp->fd); + } ++ ++declare_nop_prio(initprio) ++declare_nop_prio(freeprio) +Index: multipath-tools-130222/libmultipath/prioritizers/weightedpath.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/prioritizers/weightedpath.c ++++ multipath-tools-130222/libmultipath/prioritizers/weightedpath.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include "def_func.h" + + char *get_next_string(char **temp, char *split_char) + { +@@ -104,3 +105,5 @@ int getprio(struct path *pp, char *args) + return prio_path_weight(pp, args); + } + ++declare_nop_prio(initprio) ++declare_nop_prio(freeprio) +Index: multipath-tools-130222/libmultipath/propsel.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/propsel.c ++++ multipath-tools-130222/libmultipath/propsel.c +@@ -401,10 +401,10 @@ detect_prio(struct path * pp) + + if (get_target_port_group_support(pp->fd) <= 0) + return; +- ret = get_target_port_group(pp->fd); ++ ret = get_target_port_group(pp->fd, NULL); + if (ret < 0) + return; +- if (get_asymmetric_access_state(pp->fd, ret) < 0) ++ if (get_asymmetric_access_state(pp->fd, ret, NULL) < 0) + return; + prio_get(p, PRIO_ALUA, DEFAULT_PRIO_ARGS); + } +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -700,20 +700,23 @@ static int + uev_update_path (struct uevent *uev, struct vectors * vecs) + { + int ro, retval = 0; ++ struct path * pp; ++ ++ pp = find_path_by_dev(vecs->pathvec, uev->kernel); ++ if (!pp) { ++ condlog(0, "%s: spurious uevent, path not found", ++ uev->kernel); ++ return 1; ++ } ++ /* reinit the prio values on change event, in case something is ++ * different */ ++ prio_init(&pp->prio); + + ro = uevent_get_disk_ro(uev); + + if (ro >= 0) { +- struct path * pp; +- + condlog(2, "%s: update path write_protect to '%d' (uevent)", + uev->kernel, ro); +- pp = find_path_by_dev(vecs->pathvec, uev->kernel); +- if (!pp) { +- condlog(0, "%s: spurious uevent, path not found", +- uev->kernel); +- return 1; +- } + if (pp->mpp) { + retval = reload_map(vecs, pp->mpp, 0); + +@@ -1218,6 +1221,11 @@ check_path (struct vectors * vecs, struc + } + + if(newstate == PATH_UP || newstate == PATH_GHOST){ ++ /* ++ * Reinitialize the prioritizer, in case something ++ * changed. ++ */ ++ prio_init(&pp->prio); + if ( pp->mpp && pp->mpp->prflag ){ + /* + * Check Persistent Reservation. diff --git a/SOURCES/0120-RHBZ-1043093-realloc-fix.patch b/SOURCES/0120-RHBZ-1043093-realloc-fix.patch new file mode 100644 index 0000000..96b812a --- /dev/null +++ b/SOURCES/0120-RHBZ-1043093-realloc-fix.patch @@ -0,0 +1,195 @@ +--- + libmultipath/dmparser.c | 6 ++++-- + libmultipath/regex.c | 9 ++++++++- + multipath/main.c | 9 ++++++--- + multipathd/cli_handlers.c | 41 ++++++++++++----------------------------- + multipathd/uxlsnr.c | 13 ++++++++++++- + 5 files changed, 42 insertions(+), 36 deletions(-) + +Index: multipath-tools-130222/libmultipath/dmparser.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/dmparser.c ++++ multipath-tools-130222/libmultipath/dmparser.c +@@ -20,14 +20,16 @@ + static int + merge_words (char ** dst, char * word, int space) + { +- char * p; ++ char * p = *dst; + int len; + + len = strlen(*dst) + strlen(word) + space; + *dst = REALLOC(*dst, len + 1); + +- if (!*dst) ++ if (!*dst) { ++ free(p); + return 1; ++ } + + p = *dst; + +Index: multipath-tools-130222/libmultipath/regex.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/regex.c ++++ multipath-tools-130222/libmultipath/regex.c +@@ -123,7 +123,14 @@ static void init_syntax_once(void) + + /* (Re)Allocate N items of type T using malloc, or fail. */ + #define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t))) +-#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t))) ++#define RETALLOC(addr, n, t) \ ++do { \ ++ t *tmp = (t *) realloc (addr, (n) * sizeof (t)); \ ++ if (!tmp) \ ++ free(addr); \ ++ (addr) = tmp; \ ++} while(0) ++ + #define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t))) + + #define BYTEWIDTH 8 /* In bits. */ +Index: multipath-tools-130222/multipath/main.c +=================================================================== +--- multipath-tools-130222.orig/multipath/main.c ++++ multipath-tools-130222/multipath/main.c +@@ -394,7 +394,7 @@ out: + static int + dump_config (void) + { +- char * c; ++ char * c, * tmp = NULL; + char * reply; + unsigned int maxlen = 256; + int again = 1; +@@ -402,9 +402,12 @@ dump_config (void) + reply = MALLOC(maxlen); + + while (again) { +- if (!reply) ++ if (!reply) { ++ if (tmp) ++ free(tmp); + return 1; +- c = reply; ++ } ++ c = tmp = reply; + c += snprint_defaults(c, reply + maxlen - c); + again = ((c - reply) == maxlen); + if (again) { +Index: multipath-tools-130222/multipathd/cli_handlers.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/cli_handlers.c ++++ multipath-tools-130222/multipathd/cli_handlers.c +@@ -26,11 +26,14 @@ + #define REALLOC_REPLY(r, a, m) \ + do { \ + if ((a)) { \ ++ char *tmp = (r); \ + (r) = REALLOC((r), (m) * 2); \ + if ((r)) { \ + memset((r) + (m), 0, (m)); \ + (m) *= 2; \ + } \ ++ else \ ++ free(tmp); \ + } \ + } while (0) + +@@ -144,7 +147,7 @@ show_config (char ** r, int * len) + unsigned int maxlen = INITIAL_REPLY_LEN; + int again = 1; + +- reply = MALLOC(maxlen); ++ c = reply = MALLOC(maxlen); + + while (again) { + if (!reply) +@@ -152,44 +155,24 @@ show_config (char ** r, int * len) + c = reply; + c += snprint_defaults(c, reply + maxlen - c); + again = ((c - reply) == maxlen); +- if (again) { +- reply = REALLOC(reply, maxlen * 2); +- if (!reply) +- return 1; +- memset(reply + maxlen, 0, maxlen); +- maxlen *= 2; ++ REALLOC_REPLY(reply, again, maxlen); ++ if (again) + continue; +- } + c += snprint_blacklist(c, reply + maxlen - c); + again = ((c - reply) == maxlen); +- if (again) { +- reply = REALLOC(reply, maxlen * 2); +- if (!reply) +- return 1; +- memset(reply + maxlen, 0, maxlen); +- maxlen *= 2; ++ REALLOC_REPLY(reply, again, maxlen); ++ if (again) + continue; +- } + c += snprint_blacklist_except(c, reply + maxlen - c); + again = ((c - reply) == maxlen); +- if (again) { +- reply = REALLOC(reply, maxlen * 2); +- if (!reply) +- return 1; +- memset(reply + maxlen, 0, maxlen); +- maxlen *= 2; ++ REALLOC_REPLY(reply, again, maxlen); ++ if (again) + continue; +- } + c += snprint_hwtable(c, reply + maxlen - c, conf->hwtable); + again = ((c - reply) == maxlen); +- if (again) { +- reply = REALLOC(reply, maxlen * 2); +- if (!reply) +- return 1; +- memset(reply + maxlen, 0, maxlen); +- maxlen *= 2; ++ REALLOC_REPLY(reply, again, maxlen); ++ if (again) + continue; +- } + c += snprint_mptable(c, reply + maxlen - c, conf->mptable); + again = ((c - reply) == maxlen); + REALLOC_REPLY(reply, again, maxlen); +Index: multipath-tools-130222/multipathd/uxlsnr.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/uxlsnr.c ++++ multipath-tools-130222/multipathd/uxlsnr.c +@@ -64,6 +64,10 @@ static void new_client(int ux_sock) + + /* put it in our linked list */ + c = (struct client *)MALLOC(sizeof(*c)); ++ if (!c) { ++ close(fd); ++ return; ++ } + memset(c, 0, sizeof(*c)); + c->fd = fd; + c->next = clients; +@@ -124,11 +128,18 @@ void * uxsock_listen(int (*uxsock_trigge + sigdelset(&mask, SIGHUP); + sigdelset(&mask, SIGUSR1); + while (1) { ++ struct pollfd *tmp; + struct client *c; + int i, poll_count; + + /* setup for a poll */ +- polls = REALLOC(polls, (1+num_clients) * sizeof(*polls)); ++ tmp = REALLOC(polls, (1+num_clients) * sizeof(*polls)); ++ /* If we can't allocate poliing space for the new client, ++ * close it */ ++ if (!tmp) ++ dead_client(clients); ++ else ++ polls = tmp; + polls[0].fd = ux_sock; + polls[0].events = POLLIN; + diff --git a/SOURCES/0121-RHBZ-1197234-rules-fix.patch b/SOURCES/0121-RHBZ-1197234-rules-fix.patch new file mode 100644 index 0000000..41d672b --- /dev/null +++ b/SOURCES/0121-RHBZ-1197234-rules-fix.patch @@ -0,0 +1,28 @@ +--- + multipath/multipath.rules | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +Index: multipath-tools-130222/multipath/multipath.rules +=================================================================== +--- multipath-tools-130222.orig/multipath/multipath.rules ++++ multipath-tools-130222/multipath/multipath.rules +@@ -21,6 +21,7 @@ ACTION!="change", GOTO="update_timestamp + IMPORT{db}="DM_MULTIPATH_TIMESTAMP" + IMPORT{db}="DM_MULTIPATH_DEVICE_PATH" + IMPORT{db}="DM_MULTIPATH_WIPE_PARTS" ++IMPORT{db}="DM_MULTIPATH_NEED_KPARTX" + # Check if the device is part of a multipath device. the -T option just keeps + # the old result if the timestamp hasn't changed. + PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -T $env{DM_MULTIPATH_TIMESTAMP}:$env{DM_MULTIPATH_DEVICE_PATH} -c $env{DEVNAME}", \ +@@ -43,7 +44,10 @@ KERNEL!="dm-*", GOTO="end_mpath" + ENV{DM_UUID}=="mpath-?*|part[0-9]*-mpath-?*", OPTIONS+="link_priority=10" + ACTION!="change", GOTO="end_mpath" + ENV{DM_UUID}!="mpath-?*", GOTO="end_mpath" ++ENV{DM_ACTIVATION}=="1", ENV{DM_MULTIPATH_NEED_KPARTX}="1" + ENV{DM_SUSPENDED}=="1", GOTO="end_mpath" + ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath" +-ENV{DM_ACTIVATION}=="1", RUN+="$env{MPATH_SBIN_PATH}/kpartx -u $tempnode" ++ENV{DM_ACTIVATION}!="1", ENV{DM_MULTIPATH_NEED_KPARTX}!="1", GOTO="end_mpath" ++RUN+="$env{MPATH_SBIN_PATH}/kpartx -a $tempnode", \ ++ ENV{DM_MULTIPATH_NEED_KPARTX}="" + LABEL="end_mpath" diff --git a/SOURCES/0122-RHBZ-1212590-dont-use-var.patch b/SOURCES/0122-RHBZ-1212590-dont-use-var.patch new file mode 100644 index 0000000..52d743a --- /dev/null +++ b/SOURCES/0122-RHBZ-1212590-dont-use-var.patch @@ -0,0 +1,33 @@ +--- + libmultipath/defaults.h | 4 ++-- + multipathd/multipathd.service | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +Index: multipath-tools-130222/libmultipath/defaults.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/defaults.h ++++ multipath-tools-130222/libmultipath/defaults.h +@@ -26,8 +26,8 @@ + #define MAX_CHECKINT(a) (a << 2) + + #define MAX_DEV_LOSS_TMO 0x7FFFFFFF +-#define DEFAULT_PIDFILE "/var/run/multipathd/multipathd.pid" +-#define DEFAULT_TIMESTAMP_FILE "/var/run/multipathd/timestamp" ++#define DEFAULT_PIDFILE "/run/multipathd/multipathd.pid" ++#define DEFAULT_TIMESTAMP_FILE "/run/multipathd/timestamp" + #define DEFAULT_SOCKET "/org/kernel/linux/storage/multipathd" + #define DEFAULT_CONFIGFILE "/etc/multipath.conf" + #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" +Index: multipath-tools-130222/multipathd/multipathd.service +=================================================================== +--- multipath-tools-130222.orig/multipathd/multipathd.service ++++ multipath-tools-130222/multipathd/multipathd.service +@@ -9,7 +9,7 @@ Conflicts=shutdown.target + + [Service] + Type=forking +-PIDFile=/var/run/multipathd/multipathd.pid ++PIDFile=/run/multipathd/multipathd.pid + ExecStartPre=/sbin/modprobe dm-multipath + ExecStartPre=-/sbin/multipath -A + ExecStart=/sbin/multipathd diff --git a/SOURCES/0123-UPBZ-1166072-fix-path-offline.patch b/SOURCES/0123-UPBZ-1166072-fix-path-offline.patch new file mode 100644 index 0000000..0f1a912 --- /dev/null +++ b/SOURCES/0123-UPBZ-1166072-fix-path-offline.patch @@ -0,0 +1,19 @@ +--- + libmultipath/discovery.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +Index: multipath-tools-130222/libmultipath/discovery.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/discovery.c ++++ multipath-tools-130222/libmultipath/discovery.c +@@ -946,9 +946,7 @@ path_offline (struct path * pp) + + condlog(3, "%s: path state = %s", pp->dev, buff); + +- if (!strncmp(buff, "offline", 7) || +- !strncmp(buff, "quiesce", 7) || +- !strncmp(buff, "transport-offline", 17)) { ++ if (!strncmp(buff, "offline", 7)) { + pp->offline = 1; + return PATH_DOWN; + } diff --git a/SOURCES/0124-RHBZ-1209275-retrigger-uevents.patch b/SOURCES/0124-RHBZ-1209275-retrigger-uevents.patch new file mode 100644 index 0000000..e0b1886 --- /dev/null +++ b/SOURCES/0124-RHBZ-1209275-retrigger-uevents.patch @@ -0,0 +1,214 @@ +--- + libmultipath/config.c | 2 ++ + libmultipath/config.h | 2 ++ + libmultipath/defaults.h | 2 ++ + libmultipath/dict.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ + libmultipath/discovery.c | 8 +++++--- + libmultipath/structs.h | 8 ++++++++ + multipathd/main.c | 15 ++++++++++++++- + 7 files changed, 79 insertions(+), 4 deletions(-) + +Index: multipath-tools-130222/libmultipath/config.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.c ++++ multipath-tools-130222/libmultipath/config.c +@@ -673,6 +673,8 @@ load_config (char * file, struct udev *u + conf->force_sync = 0; + conf->ignore_new_boot_devs = 0; + conf->processed_main_config = 0; ++ conf->retrigger_tries = DEFAULT_RETRIGGER_TRIES; ++ conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY; + + /* + * preload default hwtable +Index: multipath-tools-130222/libmultipath/config.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.h ++++ multipath-tools-130222/libmultipath/config.h +@@ -139,6 +139,8 @@ struct config { + int processed_main_config; + int delay_watch_checks; + int delay_wait_checks; ++ int retrigger_tries; ++ int retrigger_delay; + unsigned int version[3]; + + char * dev; +Index: multipath-tools-130222/libmultipath/defaults.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/defaults.h ++++ multipath-tools-130222/libmultipath/defaults.h +@@ -21,6 +21,8 @@ + #define DEFAULT_DETECT_PRIO DETECT_PRIO_OFF + #define DEFAULT_DEFERRED_REMOVE DEFERRED_REMOVE_OFF + #define DEFAULT_DELAY_CHECKS DELAY_CHECKS_OFF ++#define DEFAULT_RETRIGGER_DELAY 10 ++#define DEFAULT_RETRIGGER_TRIES 3 + + #define DEFAULT_CHECKINT 5 + #define MAX_CHECKINT(a) (a << 2) +Index: multipath-tools-130222/libmultipath/dict.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/dict.c ++++ multipath-tools-130222/libmultipath/dict.c +@@ -839,6 +839,38 @@ def_delay_wait_checks_handler(vector str + return 0; + } + ++static int ++def_retrigger_tries_handler(vector strvec) ++{ ++ char * buff; ++ ++ buff = set_value(strvec); ++ ++ if (!buff) ++ return 1; ++ ++ conf->retrigger_tries = atoi(buff); ++ FREE(buff); ++ ++ return 0; ++} ++ ++static int ++def_retrigger_delay_handler(vector strvec) ++{ ++ char * buff; ++ ++ buff = set_value(strvec); ++ ++ if (!buff) ++ return 1; ++ ++ conf->retrigger_delay = atoi(buff); ++ FREE(buff); ++ ++ return 0; ++} ++ + /* + * blacklist block handlers + */ +@@ -3194,6 +3226,18 @@ snprint_def_delay_wait_checks(char * buf + } + + static int ++snprint_def_retrigger_tries (char * buff, int len, void * data) ++{ ++ return snprintf(buff, len, "%i", conf->retrigger_tries); ++} ++ ++static int ++snprint_def_retrigger_delay (char * buff, int len, void * data) ++{ ++ return snprintf(buff, len, "%i", conf->retrigger_delay); ++} ++ ++static int + snprint_ble_simple (char * buff, int len, void * data) + { + struct blentry * ble = (struct blentry *)data; +@@ -3267,6 +3311,8 @@ init_keywords(void) + install_keyword("config_dir", &def_config_dir_handler, &snprint_def_config_dir); + install_keyword("delay_watch_checks", &def_delay_watch_checks_handler, &snprint_def_delay_watch_checks); + install_keyword("delay_wait_checks", &def_delay_wait_checks_handler, &snprint_def_delay_wait_checks); ++ install_keyword("retrigger_tries", &def_retrigger_tries_handler, &snprint_def_retrigger_tries); ++ install_keyword("retrigger_delay", &def_retrigger_delay_handler, &snprint_def_retrigger_delay); + __deprecated install_keyword("default_selector", &def_selector_handler, NULL); + __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); + __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); +Index: multipath-tools-130222/libmultipath/discovery.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/discovery.c ++++ multipath-tools-130222/libmultipath/discovery.c +@@ -1111,9 +1111,13 @@ get_uid (struct path * pp) + len = strlen(value); + } + strncpy(pp->wwid, value, len); ++ pp->missing_udev_info = INFO_OK; ++ pp->tick = 0; + } else { + condlog(3, "%s: no %s attribute", pp->dev, + pp->uid_attribute); ++ pp->missing_udev_info = INFO_MISSING; ++ pp->tick = conf->retrigger_delay; + } + + /* Strip any trailing blanks */ +@@ -1201,10 +1205,8 @@ pathinfo (struct path *pp, vector hwtabl + * Retrieve path priority, even for PATH_DOWN paths if it has never + * been successfully obtained before. + */ +- if ((mask & DI_PRIO) && path_state == PATH_UP) { ++ if ((mask & DI_PRIO) && path_state == PATH_UP && strlen(pp->wwid)) { + if (pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF) { +- if (!strlen(pp->wwid)) +- get_uid(pp); + get_prio(pp); + } + } +Index: multipath-tools-130222/libmultipath/structs.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/structs.h ++++ multipath-tools-130222/libmultipath/structs.h +@@ -139,6 +139,12 @@ enum delay_checks_states { + DELAY_CHECKS_UNDEF = 0, + }; + ++enum missing_udev_info_states { ++ INFO_OK, ++ INFO_MISSING, ++ INFO_REQUESTED, ++}; ++ + struct sg_id { + int host_no; + int channel; +@@ -193,6 +199,8 @@ struct path { + struct checker checker; + struct multipath * mpp; + int fd; ++ int missing_udev_info; ++ int retriggers; + + /* configlet pointers */ + struct hwentry * hwe; +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -708,6 +708,10 @@ uev_update_path (struct uevent *uev, str + uev->kernel); + return 1; + } ++ ++ if (pp->missing_udev_info == INFO_REQUESTED) ++ return uev_add_path(uev, vecs); ++ + /* reinit the prio values on change event, in case something is + * different */ + prio_init(&pp->prio); +@@ -1133,12 +1137,21 @@ check_path (struct vectors * vecs, struc + int chkr_new_path_up = 0; + int oldchkrstate = pp->chkrstate; + +- if (!pp->mpp) ++ if (!pp->mpp && (pp->missing_udev_info != INFO_MISSING || ++ pp->retriggers >= conf->retrigger_tries)) + return; + + if (pp->tick && --pp->tick) + return; /* don't check this path yet */ + ++ if (!pp->mpp) { ++ pp->missing_udev_info = INFO_REQUESTED; ++ pp->retriggers++; ++ sysfs_attr_set_value(pp->udev, "uevent", "change", ++ strlen("change")); ++ return; ++ } ++ + /* + * provision a next check soonest, + * in case we exit abnormaly from here diff --git a/SOURCES/0125-RHBZ-1153832-kpartx-delete.patch b/SOURCES/0125-RHBZ-1153832-kpartx-delete.patch new file mode 100644 index 0000000..329bc44 --- /dev/null +++ b/SOURCES/0125-RHBZ-1153832-kpartx-delete.patch @@ -0,0 +1,26 @@ +--- + kpartx/kpartx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: multipath-tools-130222/kpartx/kpartx.c +=================================================================== +--- multipath-tools-130222.orig/kpartx/kpartx.c ++++ multipath-tools-130222/kpartx/kpartx.c +@@ -409,7 +409,7 @@ main(int argc, char **argv){ + break; + + case DELETE: +- for (j = n-1; j >= 0; j--) { ++ for (j = MAXSLICES-1; j >= 0; j--) { + if (safe_sprintf(partname, "%s%s%d", + mapname, delim, j+1)) { + fprintf(stderr, "partname too small\n"); +@@ -417,7 +417,7 @@ main(int argc, char **argv){ + } + strip_slash(partname); + +- if (!slices[j].size || !dm_map_present(partname)) ++ if (!dm_map_present(partname)) + continue; + + if (!dm_simplecmd(DM_DEVICE_REMOVE, partname, diff --git a/SOURCES/0126-RHBZ-1211383-alias-collision.patch b/SOURCES/0126-RHBZ-1211383-alias-collision.patch new file mode 100644 index 0000000..965bf53 --- /dev/null +++ b/SOURCES/0126-RHBZ-1211383-alias-collision.patch @@ -0,0 +1,113 @@ +--- + libmultipath/config.c | 4 ++++ + libmultipath/config.h | 1 + + libmultipath/configure.c | 3 +++ + libmultipath/dict.c | 33 +++++++++++++++++++++++++++++++++ + 4 files changed, 41 insertions(+) + +Index: multipath-tools-130222/libmultipath/configure.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/configure.c ++++ multipath-tools-130222/libmultipath/configure.c +@@ -422,6 +422,9 @@ select_action (struct multipath * mpp, v + condlog(2, "%s: unable to rename %s to %s (%s is used by %s)", + mpp->wwid, cmpp->alias, mpp->alias, + mpp->alias, cmpp_by_name->wwid); ++ /* reset alias to existing alias */ ++ FREE(mpp->alias); ++ mpp->alias = STRDUP(cmpp->alias); + mpp->action = ACT_NOTHING; + return; + } +Index: multipath-tools-130222/libmultipath/config.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.c ++++ multipath-tools-130222/libmultipath/config.c +@@ -675,6 +675,7 @@ load_config (char * file, struct udev *u + conf->processed_main_config = 0; + conf->retrigger_tries = DEFAULT_RETRIGGER_TRIES; + conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY; ++ conf->new_bindings_in_boot = 0; + + /* + * preload default hwtable +@@ -794,6 +795,9 @@ load_config (char * file, struct udev *u + if (conf->ignore_new_boot_devs) + in_initrd(); + ++ if (conf->new_bindings_in_boot == 0 && in_initrd()) ++ conf->bindings_read_only = 1; ++ + return 0; + out: + free_config(conf); +Index: multipath-tools-130222/libmultipath/config.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.h ++++ multipath-tools-130222/libmultipath/config.h +@@ -141,6 +141,7 @@ struct config { + int delay_wait_checks; + int retrigger_tries; + int retrigger_delay; ++ int new_bindings_in_boot; + unsigned int version[3]; + + char * dev; +Index: multipath-tools-130222/libmultipath/dict.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/dict.c ++++ multipath-tools-130222/libmultipath/dict.c +@@ -871,6 +871,29 @@ def_retrigger_delay_handler(vector strve + return 0; + } + ++static int ++def_new_bindings_in_boot_handler(vector strvec) ++{ ++ char * buff; ++ ++ buff = set_value(strvec); ++ ++ if (!buff) ++ return 1; ++ ++ if ((strlen(buff) == 2 && !strcmp(buff, "no")) || ++ (strlen(buff) == 1 && !strcmp(buff, "0"))) ++ conf->new_bindings_in_boot = 0; ++ else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) || ++ (strlen(buff) == 1 && !strcmp(buff, "1"))) ++ conf->new_bindings_in_boot = 1; ++ else ++ conf->new_bindings_in_boot = 0; ++ ++ FREE(buff); ++ return 0; ++} ++ + /* + * blacklist block handlers + */ +@@ -3238,6 +3261,15 @@ snprint_def_retrigger_delay (char * buff + } + + static int ++snprint_def_new_bindings_in_boot(char * buff, int len, void * data) ++{ ++ if (conf->new_bindings_in_boot == 1) ++ return snprintf(buff, len, "yes"); ++ else ++ return snprintf(buff, len, "no"); ++} ++ ++static int + snprint_ble_simple (char * buff, int len, void * data) + { + struct blentry * ble = (struct blentry *)data; +@@ -3313,6 +3345,7 @@ init_keywords(void) + install_keyword("delay_wait_checks", &def_delay_wait_checks_handler, &snprint_def_delay_wait_checks); + install_keyword("retrigger_tries", &def_retrigger_tries_handler, &snprint_def_retrigger_tries); + install_keyword("retrigger_delay", &def_retrigger_delay_handler, &snprint_def_retrigger_delay); ++ install_keyword("new_bindings_in_boot", &def_new_bindings_in_boot_handler, &snprint_def_new_bindings_in_boot); + __deprecated install_keyword("default_selector", &def_selector_handler, NULL); + __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); + __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL); diff --git a/SOURCES/0127-RHBZ-1201030-use-blk-availability.patch b/SOURCES/0127-RHBZ-1201030-use-blk-availability.patch new file mode 100644 index 0000000..b2cd7cf --- /dev/null +++ b/SOURCES/0127-RHBZ-1201030-use-blk-availability.patch @@ -0,0 +1,15 @@ +--- + multipathd/multipathd.service | 1 + + 1 file changed, 1 insertion(+) + +Index: multipath-tools-130222/multipathd/multipathd.service +=================================================================== +--- multipath-tools-130222.orig/multipathd/multipathd.service ++++ multipath-tools-130222/multipathd/multipathd.service +@@ -1,5 +1,6 @@ + [Unit] + Description=Device-Mapper Multipath Device Controller ++Requires=blk-availability.service + Before=iscsi.service iscsid.service lvm2-activation-early.service + After=syslog.target + ConditionPathExists=/etc/multipath.conf diff --git a/SOURCES/0128-RHBZ-1222123-mpathconf-allow.patch b/SOURCES/0128-RHBZ-1222123-mpathconf-allow.patch new file mode 100644 index 0000000..a48d8ae --- /dev/null +++ b/SOURCES/0128-RHBZ-1222123-mpathconf-allow.patch @@ -0,0 +1,240 @@ +--- + multipath/mpathconf | 135 +++++++++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 124 insertions(+), 11 deletions(-) + +Index: multipath-tools-130222/multipath/mpathconf +=================================================================== +--- multipath-tools-130222.orig/multipath/mpathconf ++++ multipath-tools-130222/multipath/mpathconf +@@ -1,4 +1,4 @@ +-#!/bin/sh ++#!/bin/bash + # + # Copyright (C) 2010 Red Hat, Inc. All rights reserved. + # +@@ -17,12 +17,14 @@ + # This program was largely ripped off from lvmconf + # + +-unset ENABLE FIND FRIENDLY MODULE MULTIPATHD HAVE_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_DEFAULTS HAVE_FRIENDLY HAVE_MULTIPATHD HAVE_MODULE SHOW_STATUS CHANGED_CONFIG ++unset ENABLE FIND FRIENDLY MODULE MULTIPATHD HAVE_DISABLE HAVE_WWID_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_EXCEPTIONS HAVE_DEFAULTS HAVE_FRIENDLY HAVE_MULTIPATHD HAVE_MODULE HAVE_OUTFILE SHOW_STATUS CHANGED_CONFIG WWID_LIST + + DEFAULT_CONFIGFILE="/usr/share/doc/device-mapper-multipath-0.4.9/multipath.conf" + CONFIGFILE="/etc/multipath.conf" ++OUTPUTFILE="/etc/multipath.conf" + MULTIPATHDIR="/etc/multipath" + TMPFILE=/etc/multipath/.multipath.conf.tmp ++WWIDS=0 + + function usage + { +@@ -31,13 +33,60 @@ function usage + echo "Commands:" + echo "Enable: --enable " + echo "Disable: --disable" ++ echo "Only allow certain wwids (instead of enable): --allow " + echo "Set user_friendly_names (Default y): --user_friendly_names " + echo "Set find_multipaths (Default y): --find_multipaths " + echo "Load the dm-multipath modules on enable (Default y): --with_module " + echo "start/stop/reload multipathd (Default n): --with_multipathd " ++ echo "select output file (Default /etc/multipath.conf): --outfile " + echo "" + } + ++function get_dm_deps ++{ ++ shift 3 ++ while [ -n "$1" -a -n "$2" ]; do ++ MAJOR=$(echo $1 | tr -d '(,') ++ MINOR=$(echo $2 | tr -d ')') ++ UUID=`dmsetup info -c --noheadings -o uuid -j $MAJOR -m $MINOR 2> /dev/null` ++ if [ -n "$UUID" ] ; then ++ set_dm_wwid $UUID ++ fi ++ shift 2 ++ done ++} ++ ++function set_dm_wwid ++{ ++ if [[ "$1" =~ ^part[[:digit:]]+-mpath- ]] ; then ++ WWID_LIST[$WWIDS]="${1##part*-mpath-}" ++ ((WWIDS++)) ++ elif [[ "$1" =~ ^mpath- ]] ; then ++ WWID_LIST[$WWIDS]="${1##mpath-}" ++ ((WWIDS++)) ++ else ++ get_dm_deps `dmsetup deps -u $1` ++ fi ++} ++ ++function set_wwid ++{ ++ UUID="" ++ if [[ "$1" =~ ^[[:digit:]]+:[[:digit:]]+$ ]] ; then ++ MAJOR=${1%%:*} ++ MINOR=${1##*:} ++ UUID=`dmsetup info -c --noheadings -o uuid -j $MAJOR -m $MINOR 2> /dev/null` ++ else ++ UUID=`dmsetup info -c --noheadings -o uuid $1 2> /dev/null` ++ fi ++ if [ -n "$UUID" ] ; then ++ set_dm_wwid $UUID ++ else ++ WWID_LIST[$WWIDS]="$1" ++ ((WWIDS++)) ++ fi ++} ++ + function parse_args + { + while [ -n "$1" ]; do +@@ -50,6 +99,16 @@ function parse_args + ENABLE=0 + shift + ;; ++ --allow) ++ ENABLE=2 ++ if [ -n "$2" ]; then ++ set_wwid $2 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; + --user_friendly_names) + if [ -n "$2" ]; then + FRIENDLY=$2 +@@ -86,6 +145,16 @@ function parse_args + exit 1 + fi + ;; ++ --outfile) ++ if [ -n "$2" ]; then ++ OUTPUTFILE=$2 ++ HAVE_OUTFILE=1 ++ shift 2 ++ else ++ usage ++ exit 1 ++ fi ++ ;; + *) + usage + exit +@@ -120,6 +189,22 @@ function validate_args + echo "--with_multipathd must be either 'y' or 'n'" + exit 1 + fi ++ if [ "$ENABLE" = 2 -a -z "$HAVE_OUTFILE" ]; then ++ echo "Because --allow makes changes that cannot be automatically reversed," ++ echo "you must set --outfile when you set --allow" ++ exit 1 ++ fi ++} ++ ++function add_blacklist_exceptions ++{ ++ echo "blacklist_exceptions {" >> $TMPFILE ++ INDEX=0 ++ while [ "$INDEX" -lt "$WWIDS" ] ; do ++ echo " wwid \"${WWID_LIST[$INDEX]}\"" >> $TMPFILE ++ ((INDEX++)) ++ done ++ echo "}" >> $TMPFILE + } + + umask 0077 +@@ -146,6 +231,10 @@ if grep -q "^blacklist[[:space:]]*{" $TM + HAVE_BLACKLIST=1 + fi + ++if grep -q "^blacklist_exceptions[[:space:]]*{" $TMPFILE ; then ++ HAVE_EXCEPTIONS=1 ++fi ++ + if grep -q "^defaults[[:space:]]*{" $TMPFILE ; then + HAVE_DEFAULTS=1 + fi +@@ -169,11 +258,19 @@ fi + if [ "$HAVE_BLACKLIST" = "1" ]; then + if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode \"\.\?\*\"" ; then + HAVE_DISABLE=1 +- elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[#[:space:]]*devnode \"\.\?\*\"" ; then ++ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"" ; then + HAVE_DISABLE=0 + fi + fi + ++if [ "$HAVE_BLACKLIST" = "1" ]; then ++ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*wwid \"\.\?\*\"" ; then ++ HAVE_WWID_DISABLE=1 ++ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"" ; then ++ HAVE_WWID_DISABLE=0 ++ fi ++fi ++ + if [ "$HAVE_DEFAULTS" = "1" ]; then + if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)" ; then + HAVE_FIND=1 +@@ -241,17 +338,33 @@ defaults { + _EOF_ + fi + +-if [ "$ENABLE" = 1 ]; then ++if [ "$ENABLE" = 2 ]; then ++ if [ "$HAVE_DISABLE" = 1 ]; then ++ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE ++ fi ++ if [ -z "$HAVE_WWID_DISABLE" ]; then ++ sed -i '/^blacklist[[:space:]]*{/ a\ ++ wwid ".*" ++' $TMPFILE ++ elif [ "$HAVE_WWID_DISABLE" = 0 ]; then ++ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*wwid \"\.\?\*\"/ wwid ".*"/' $TMPFILE ++ fi ++ if [ "$HAVE_EXCEPTIONS" = 1 ]; then ++ sed -i '/^blacklist_exceptions[[:space:]]*{/,/^}/d' $TMPFILE ++ fi ++ echo $HAVE_WWID_DISABLE ++ add_blacklist_exceptions ++elif [ "$ENABLE" = 1 ]; then + if [ "$HAVE_DISABLE" = 1 ]; then + sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE + fi + elif [ "$ENABLE" = 0 ]; then + if [ -z "$HAVE_DISABLE" ]; then + sed -i '/^blacklist[[:space:]]*{/ a\ +- devnode "*" ++ devnode ".*" + ' $TMPFILE + elif [ "$HAVE_DISABLE" = 0 ]; then +- sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[#[:space:]]*devnode \"\.\?\*\"/ devnode ".*"/' $TMPFILE ++ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[[:space:]]*devnode \"\.\?\*\"/ devnode ".*"/' $TMPFILE + fi + fi + +@@ -289,17 +402,17 @@ elif [ "$FRIENDLY" = "y" ]; then + fi + fi + +-if [ -f "$CONFIGFILE" ]; then +- cp $CONFIGFILE $CONFIGFILE.old ++if [ -f "$OUTPUTFILE" ]; then ++ cp $OUTPUTFILE $OUTPUTFILE.old + if [ $? != 0 ]; then +- echo "failed to backup old config file, $CONFIGFILE not updated" ++ echo "failed to backup old config file, $OUTPUTFILE not updated" + exit 1 + fi + fi + +-cp $TMPFILE $CONFIGFILE ++cp $TMPFILE $OUTPUTFILE + if [ $? != 0 ]; then +- echo "failed to copy new config file into place, check $CONFIGFILE is still OK" ++ echo "failed to copy new config file into place, check $OUTPUTFILE is still OK" + exit 1 + fi + diff --git a/SOURCES/0129-UPBZ-1254292-iscsi-targetname.patch b/SOURCES/0129-UPBZ-1254292-iscsi-targetname.patch new file mode 100644 index 0000000..26a6831 --- /dev/null +++ b/SOURCES/0129-UPBZ-1254292-iscsi-targetname.patch @@ -0,0 +1,17 @@ +--- + libmultipath/discovery.c | 2 ++ + 1 file changed, 2 insertions(+) + +Index: multipath-tools-130222/libmultipath/discovery.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/discovery.c ++++ multipath-tools-130222/libmultipath/discovery.c +@@ -280,6 +280,8 @@ sysfs_get_tgt_nodename (struct path *pp, + const char *value; + + value = udev_device_get_sysattr_value(tgtdev, "tgtname"); ++ if (!value) ++ value = udev_device_get_sysattr_value(tgtdev, "targetname"); + if (value) { + pp->sg_id.proto_id = SCSI_PROTOCOL_ISCSI; + pp->sg_id.transport_id = tgtid; diff --git a/SOURCES/0130-RHBZ-1259523-host_name_len.patch b/SOURCES/0130-RHBZ-1259523-host_name_len.patch new file mode 100644 index 0000000..1460550 --- /dev/null +++ b/SOURCES/0130-RHBZ-1259523-host_name_len.patch @@ -0,0 +1,17 @@ +--- + libmultipath/structs.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: multipath-tools-130222/libmultipath/structs.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/structs.h ++++ multipath-tools-130222/libmultipath/structs.h +@@ -15,7 +15,7 @@ + #define BLK_DEV_SIZE 33 + #define PATH_SIZE 512 + #define NAME_SIZE 512 +-#define HOST_NAME_LEN 8 ++#define HOST_NAME_LEN 16 + #define SLOT_NAME_SIZE 40 + + #define SCSI_VENDOR_SIZE 9 diff --git a/SOURCES/0131-UPBZ-1259831-lock-retry.patch b/SOURCES/0131-UPBZ-1259831-lock-retry.patch new file mode 100644 index 0000000..3f5bd4d --- /dev/null +++ b/SOURCES/0131-UPBZ-1259831-lock-retry.patch @@ -0,0 +1,33 @@ +--- + multipathd/main.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -462,6 +462,7 @@ ev_add_path (struct path * pp, struct ve + char params[PARAMS_SIZE] = {0}; + int retries = 3; + int start_waiter = 0; ++ int ret; + + /* + * need path UID to go any further +@@ -540,7 +541,15 @@ rescan: + /* + * reload the map for the multipath mapped device + */ +- if (domap(mpp, params) <= 0) { ++retry: ++ ret = domap(mpp, params); ++ if (ret <= 0) { ++ if (ret < 0 && retries-- > 0) { ++ condlog(0, "%s: retry domap for addition of new " ++ "path %s", mpp->alias, pp->dev); ++ sleep(1); ++ goto retry; ++ } + condlog(0, "%s: failed in domap for addition of new " + "path %s", mpp->alias, pp->dev); + /* diff --git a/SOURCES/multipath.conf b/SOURCES/multipath.conf index 22872ae..32589c3 100644 --- a/SOURCES/multipath.conf +++ b/SOURCES/multipath.conf @@ -29,9 +29,8 @@ defaults { ## # #defaults { -# udev_dir /dev # polling_interval 10 -# selector "round-robin 0" +# path_selector "round-robin 0" # path_grouping_policy multibus # uid_attribute ID_SERIAL # prio alua @@ -63,7 +62,6 @@ defaults { # wwid 3600508b4000156d700012000000b0000 # alias yellow # path_grouping_policy multibus -# path_checker readsector0 # path_selector "round-robin 0" # failback manual # rr_weight priorities diff --git a/SPECS/device-mapper-multipath.spec b/SPECS/device-mapper-multipath.spec index 937c5c6..2b5cb3e 100644 --- a/SPECS/device-mapper-multipath.spec +++ b/SPECS/device-mapper-multipath.spec @@ -1,7 +1,7 @@ Summary: Tools to manage multipath devices using device-mapper Name: device-mapper-multipath Version: 0.4.9 -Release: 77%{?dist}.2 +Release: 85%{?dist} License: GPL+ Group: System Environment/Base URL: http://christophe.varoqui.free.fr/ @@ -113,13 +113,37 @@ Patch0102: 0102-RHBZ-631009-deferred-remove.patch Patch0103: 0103-RHBZ-1148979-fix-partition-mapping-creation-race-with-kpartx.patch Patch0104: 0104-RHBZ-1159337-fix-double-free.patch Patch0105: 0105-RHBZ-1180032-find-multipaths-man.patch -Patch0106: 0106-RHBZ-1212590-dont-use-var.patch -Patch0107: 0107-UPBZ-1254292-iscsi-targetname.patch +Patch0106: 0106-RHBZ-1169935-no-new-devs.patch +Patch0107: 0107-RH-adapter-name-wildcard.patch +Patch0108: 0108-RHBZ-1153832-kpartx-remove-devs.patch +Patch0109: 0109-RH-read-only-bindings.patch +Patch0110: 0110-RHBZ-blacklist-vd-devs.patch +Patch0111: 0111-RH-dont-show-pg-timeout.patch +Patch0112: 0112-RHBZ-1194917-add-config_dir-option.patch +Patch0113: 0113-RHBZ-1194917-cleanup.patch +Patch0114: 0114-RHBZ-1196394-delayed-reintegration.patch +Patch0115: 0115-RHBZ-1198418-fix-double-free.patch +Patch0116: 0116-UPBZ-1188179-dell-36xxi.patch +Patch0117: 0117-RHBZ-1198424-autodetect-clariion-alua.patch +Patch0118: 0118-UPBZ-1200738-update-eternus-config.patch +Patch0119: 0119-RHBZ-1081397-save-alua-info.patch +Patch0120: 0120-RHBZ-1043093-realloc-fix.patch +Patch0121: 0121-RHBZ-1197234-rules-fix.patch +Patch0122: 0122-RHBZ-1212590-dont-use-var.patch +Patch0123: 0123-UPBZ-1166072-fix-path-offline.patch +Patch0124: 0124-RHBZ-1209275-retrigger-uevents.patch +Patch0125: 0125-RHBZ-1153832-kpartx-delete.patch +Patch0126: 0126-RHBZ-1211383-alias-collision.patch +Patch0127: 0127-RHBZ-1201030-use-blk-availability.patch +Patch0128: 0128-RHBZ-1222123-mpathconf-allow.patch +Patch0129: 0129-UPBZ-1254292-iscsi-targetname.patch +Patch0130: 0130-RHBZ-1259523-host_name_len.patch +Patch0131: 0131-UPBZ-1259831-lock-retry.patch # runtime Requires: %{name}-libs = %{version}-%{release} Requires: kpartx = %{version}-%{release} -Requires: device-mapper >= 1.02.89 +Requires: device-mapper >= 7:1.02.96 Requires: initscripts Requires(post): systemd-units systemd-sysv chkconfig Requires(preun): systemd-units @@ -274,6 +298,30 @@ kpartx manages partition creation and removal for device-mapper devices. %patch0105 -p1 %patch0106 -p1 %patch0107 -p1 +%patch0108 -p1 +%patch0109 -p1 +%patch0110 -p1 +%patch0111 -p1 +%patch0112 -p1 +%patch0113 -p1 +%patch0114 -p1 +%patch0115 -p1 +%patch0116 -p1 +%patch0117 -p1 +%patch0118 -p1 +%patch0119 -p1 +%patch0120 -p1 +%patch0121 -p1 +%patch0122 -p1 +%patch0123 -p1 +%patch0124 -p1 +%patch0125 -p1 +%patch0126 -p1 +%patch0127 -p1 +%patch0128 -p1 +%patch0129 -p1 +%patch0130 -p1 +%patch0131 -p1 cp %{SOURCE1} . %build @@ -368,15 +416,96 @@ bin/systemctl --no-reload enable multipathd.service >/dev/null 2>&1 ||: %{_mandir}/man8/kpartx.8.gz %changelog -* Wed Sep 30 2015 Benjamin Marzinski 0.4.9-77.2 -- Add 0107-UPBZ-1254292-iscsi-targetname.patch +* Thu Sep 17 2015 Benjamin Marzinski 0.4.9-85 +- Fix device-mapper Requires line in spec file +- Resolves: bz# 1260728 + +* Mon Sep 14 2015 Benjamin Marzinski 0.4.9-84 +- 0131-UPBZ-1259831-lock-retry.patch + * retry locking when creating multipath devices +- Resolves: bz# 1259831 + +* Tue Sep 8 2015 Benjmain Marzinski 0.4.9-83 +- Add 0130-RHBZ-1259523-host_name_len.patch + * increase size of host string +- Resolves: bz# 1259523 + +* Wed Aug 19 2015 Benjmain Marzinski 0.4.9-82 +- Add 0129-UPBZ-1254292-iscsi-targetname.patch * check for targetname iscsi sysfs value -- Resolves: bz #1267131 - -* Thu Jul 30 2015 Benjamin Marzinski 0.4.9-77.1 -- Add 0106-RHBZ-1212590-dont-use-var.patch +- Resolves: bz #1254292 + +* Wed Jul 8 2015 Benjamin Marzinski 0.4.9-81 +- Modify 0128-RHBZ-1222123-mpathconf-allow.patch + * Fix up covscan complaints. +- Related: bz #1222123 + +* Tue Jul 7 2015 Benjamin Marzinski 0.4.9-80 +- Add 0127-RHBZ-1201030-use-blk-availability.patch + * Make multipath use blk-availability.service +- Add 0128-RHBZ-1222123-mpathconf-allow.patch + * Add mpathconf --allow for creating specialized config files. +- Resolves: bz #1201030, #1222123 + +* Fri Jun 5 2015 Benjamin Marzinski 0.4.9-79 +- Add 0124-RHBZ-1209275-retrigger-uevents.patch + * Make multipathd retrigger uevents when paths haven't successfully had + their udev_attribute environment variable set by udev and add + "retrigger_ties" and "retrigger_delay" to control this +- Add 0125-RHBZ-1153832-kpartx-delete.patch + * Delete all partition devices with -d (not just the ones in the partition + table) +- Add 0126-RHBZ-1211383-alias-collision.patch + * make multipathd use the old alias, if rename failed and add + "new_bindings_in_boot" to determine if new bindings can be added to + the bindings file in the initramfs +- Resolves: bz #1153832, #1209275, #1211383 + +* Thu May 7 2015 Benjamin Marzinski 0.4.9-78 +- Modify 0102-RHBZ-631009-deferred-remove.patch + * Code refactor and minor fix. +- Add 0106-RHBZ-1169935-no-new-devs.patch + * add new configuration option "ignore_new_boot_devs" +- Add 0107-RH-adapter-name-wildcard.patch + * add new paths wildcard to show the host adapter +- Add 0108-RHBZ-1153832-kpartx-remove-devs.patch + * switch to kpartx -u in 62-multipath.rules to delete removed partitions +- Add 0109-RH-read-only-bindings.patch + * add -B support to multipathd +- Add 0110-RHBZ-blacklist-vd-devs.patch + * virtio-blk devices don't report a WWID so multipath can't use them +- Add 0111-RH-dont-show-pg-timeout.patch + * remove pg_timeout setting and displaying code +- Add 0112-RHBZ-1194917-add-config_dir-option.patch + * add new configuration option "config_dir" +- Add 0113-RHBZ-1194917-cleanup.patch + * code refactoring +- Add 0114-RHBZ-1196394-delayed-reintegration.patch + * add new configuration options "delay_watch_checks" and + "delay_wait_checks" +- Add 0115-RHBZ-1198418-fix-double-free.patch + * fix crash when multipath fails adding a multipath device +- Add 0116-UPBZ-1188179-dell-36xxi.patch + * New builtin config +- Add 0117-RHBZ-1198424-autodetect-clariion-alua.patch + * update default config +- Add 0118-UPBZ-1200738-update-eternus-config.patch + * update default config +- Add 0119-RHBZ-1081397-save-alua-info.patch + * make prioritizers save information between calls to speed them up. +- Add 0120-RHBZ-1043093-realloc-fix.patch + * free old memory if realloc fails. +- Add 0121-RHBZ-1197234-rules-fix.patch + * make sure kpartx runs after an DM_ACTIVATION event occurs. +- Add 0122-RHBZ-1212590-dont-use-var.patch * use /run instead of /var/run -- Resolves: bz #1248386 +- Add 0123-UPBZ-1166072-fix-path-offline.patch + * Don't mark quiesce and transport-offline paths as offline +- Modify mulfipth.conf default config file (bz #1194794) +- Related: bz #1153832 +- Resolves: bz #631009, #1043093, #1081397, #1166072, #1169935, #1188179 +- Resolves: bz #1194794, #1194917, #1196394, #1197234, #1198418, #1198424 +- Resolves: bz #1200738, #1212590 * Fri Jan 9 2015 Benjamin Marzinski 0.4.9-77 - Add 0105-RHBZ-1180032-find-multipaths-man.patch