From 906e1e11285fc41097fd89893227664addb00848 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 22 Jul 2016 15:20:02 -0500 Subject: [PATCH] device-mapper-multipath-0.4.9-83 Modify 0135-RHBZ-1299600-path-dev-uevents.patch * trigger uevents when adding wwids for existing devices during startup Refresh 0136-RHBZ-1304687-wait-for-map-add.patch Refresh 0150-RHBZ-1253913-fix-startup-msg.patch Modify 0159-UPBZ-1255885-udev-waits.patch * fix bug in failure path Add 0160-RH-udev-flags.patch Add 0161-RHBZ-1311659-no-kpartx.patch * skip_kpartx option disables kpartx running on multipath devices Add 0162-RHBZ-1333331-huawei-config.patch * Add default config for Huawei XSG1 array Add 0163-UPBZ-1333492-resize-map.patch * restore old size if resize fails Add 0164-RHBZ-1311463-dos-part-rollover.patch * fix incorrect partition size due to 4k device size rollover Add 0165-UPBZ-1341748-MSA-2040-conf.patch * Add default config for MSA 2040 array Add 0166-RHBZ-1323429-dont-allow-new-wwid.patch * don't allow path wwid to change while it is in use Add 0167-RHBZ-1335176-fix-show-cmds.patch * and new show multipath format wildcard, 'f' to sho number of failures. This will hopefully be useful for tracking what happens to multipath devices for bz #1335176 Add 0168-RHBZ-1347769-shared-lock.patch * make multipath lock the path devices with a shared lock Add 0169-UPBZ-1353357-json-output.patch * add mulitpathd json output command Add 0170-UPBZ-1352925-fix-typo.patch Add 0171-UPBZ-1356651-allow-zero-size.patch * Allow zero-sized paths to be added to a multipath device Add 0172-RHBZ-1350931-no-active-add.patch * Allow paths to be added to a new map if no active paths exist. Also fixes 1351430 --- 0135-RHBZ-1299600-path-dev-uevents.patch | 29 +- 0136-RHBZ-1304687-wait-for-map-add.patch | 4 +- 0150-RHBZ-1253913-fix-startup-msg.patch | 14 +- 0159-UPBZ-1255885-udev-waits.patch | 188 +----- 0160-RH-udev-flags.patch | 20 + 0161-RHBZ-1311659-no-kpartx.patch | 618 ++++++++++++++++++++ 0162-RHBZ-1333331-huawei-config.patch | 24 + 0163-UPBZ-1333492-resize-map.patch | 24 + 0164-RHBZ-1311463-dos-part-rollover.patch | 17 + 0165-UPBZ-1341748-MSA-2040-conf.patch | 30 + 0166-RHBZ-1323429-dont-allow-new-wwid.patch | 24 + 0167-RHBZ-1335176-fix-show-cmds.patch | 138 +++++ 0168-RHBZ-1347769-shared-lock.patch | 17 + 0169-UPBZ-1353357-json-output.patch | 549 +++++++++++++++++ 0170-UPBZ-1352925-fix-typo.patch | 26 + 0171-UPBZ-1356651-allow-zero-size.patch | 79 +++ 0172-RHBZ-1350931-no-active-add.patch | 37 ++ device-mapper-multipath.spec | 64 +- 18 files changed, 1727 insertions(+), 175 deletions(-) create mode 100644 0160-RH-udev-flags.patch create mode 100644 0161-RHBZ-1311659-no-kpartx.patch create mode 100644 0162-RHBZ-1333331-huawei-config.patch create mode 100644 0163-UPBZ-1333492-resize-map.patch create mode 100644 0164-RHBZ-1311463-dos-part-rollover.patch create mode 100644 0165-UPBZ-1341748-MSA-2040-conf.patch create mode 100644 0166-RHBZ-1323429-dont-allow-new-wwid.patch create mode 100644 0167-RHBZ-1335176-fix-show-cmds.patch create mode 100644 0168-RHBZ-1347769-shared-lock.patch create mode 100644 0169-UPBZ-1353357-json-output.patch create mode 100644 0170-UPBZ-1352925-fix-typo.patch create mode 100644 0171-UPBZ-1356651-allow-zero-size.patch create mode 100644 0172-RHBZ-1350931-no-active-add.patch diff --git a/0135-RHBZ-1299600-path-dev-uevents.patch b/0135-RHBZ-1299600-path-dev-uevents.patch index fddbe19..2de58a4 100644 --- a/0135-RHBZ-1299600-path-dev-uevents.patch +++ b/0135-RHBZ-1299600-path-dev-uevents.patch @@ -1,8 +1,10 @@ --- libmultipath/configure.c | 30 ++++++++++++++++++++++++++++-- + libmultipath/configure.h | 1 + libmultipath/wwids.c | 4 ++-- multipath/main.c | 2 +- - 3 files changed, 31 insertions(+), 5 deletions(-) + multipathd/main.c | 3 ++- + 5 files changed, 34 insertions(+), 6 deletions(-) Index: multipath-tools-130222/libmultipath/configure.c =================================================================== @@ -20,7 +22,7 @@ Index: multipath-tools-130222/libmultipath/configure.c return 1; } -+static void ++void +trigger_uevents (struct multipath *mpp) +{ + struct pathgroup * pgp; @@ -94,3 +96,26 @@ Index: multipath-tools-130222/multipath/main.c printf("wwid '%s' added\n", refwwid); else printf("failed adding '%s' to wwids file\n", +Index: multipath-tools-130222/libmultipath/configure.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/configure.h ++++ multipath-tools-130222/libmultipath/configure.h +@@ -31,3 +31,4 @@ int coalesce_paths (struct vectors *vecs + int get_refwwid (char * dev, enum devtypes dev_type, vector pathvec, char **wwid); + int reload_map(struct vectors *vecs, struct multipath *mpp, int refresh); + int sysfs_get_host_adapter_name(struct path *pp, char *adapter_name); ++void trigger_uevents (struct multipath *mpp); +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -1435,7 +1435,8 @@ configure (struct vectors * vecs, int st + + sync_maps_state(mpvec); + vector_foreach_slot(mpvec, mpp, i){ +- remember_wwid(mpp->wwid); ++ if (remember_wwid(mpp->wwid) > 0) ++ trigger_uevents(mpp); + update_map_pr(mpp); + } + diff --git a/0136-RHBZ-1304687-wait-for-map-add.patch b/0136-RHBZ-1304687-wait-for-map-add.patch index 03deb1a..cd9cdee 100644 --- a/0136-RHBZ-1304687-wait-for-map-add.patch +++ b/0136-RHBZ-1304687-wait-for-map-add.patch @@ -332,7 +332,7 @@ Index: multipath-tools-130222/multipathd/main.c } if (count) count--; -@@ -1464,6 +1555,22 @@ configure (struct vectors * vecs, int st +@@ -1465,6 +1556,22 @@ configure (struct vectors * vecs, int st } int @@ -355,7 +355,7 @@ Index: multipath-tools-130222/multipathd/main.c reconfigure (struct vectors * vecs) { struct config * old = conf; -@@ -1543,12 +1650,18 @@ void +@@ -1544,12 +1651,18 @@ void handle_signals(void) { if (reconfig_sig && running_state == DAEMON_RUNNING) { diff --git a/0150-RHBZ-1253913-fix-startup-msg.patch b/0150-RHBZ-1253913-fix-startup-msg.patch index ca661e8..7dc5125 100644 --- a/0150-RHBZ-1253913-fix-startup-msg.patch +++ b/0150-RHBZ-1253913-fix-startup-msg.patch @@ -14,7 +14,7 @@ Index: multipath-tools-130222/multipathd/main.c static sem_t exit_sem; /* -@@ -1704,6 +1705,12 @@ sigusr2 (int sig) +@@ -1705,6 +1706,12 @@ sigusr2 (int sig) } static void @@ -27,7 +27,7 @@ Index: multipath-tools-130222/multipathd/main.c signal_init(void) { sigset_t set; -@@ -1806,6 +1813,9 @@ child (void * param) +@@ -1807,6 +1814,9 @@ child (void * param) } running_state = DAEMON_START; @@ -37,7 +37,7 @@ Index: multipath-tools-130222/multipathd/main.c condlog(2, "--------start up--------"); condlog(2, "read " DEFAULT_CONFIGFILE); -@@ -1897,8 +1907,6 @@ child (void * param) +@@ -1898,8 +1908,6 @@ child (void * param) } pthread_attr_destroy(&misc_attr); @@ -46,7 +46,7 @@ Index: multipath-tools-130222/multipathd/main.c update_timestamp(1); /* Ignore errors, we can live without */ -@@ -1978,7 +1986,10 @@ daemonize(void) +@@ -1979,7 +1987,10 @@ daemonize(void) { int pid; int dev_null_fd; @@ -57,7 +57,7 @@ Index: multipath-tools-130222/multipathd/main.c if( (pid = fork()) < 0){ fprintf(stderr, "Failed first fork : %s\n", strerror(errno)); return -1; -@@ -1986,10 +1997,13 @@ daemonize(void) +@@ -1987,10 +1998,13 @@ daemonize(void) else if (pid != 0) return pid; @@ -72,7 +72,7 @@ Index: multipath-tools-130222/multipathd/main.c else if (pid != 0) _exit(0); -@@ -2000,30 +2014,34 @@ daemonize(void) +@@ -2001,30 +2015,34 @@ daemonize(void) if (dev_null_fd < 0){ fprintf(stderr, "cannot open /dev/null for input & output : %s\n", strerror(errno)); @@ -111,7 +111,7 @@ Index: multipath-tools-130222/multipathd/main.c } int -@@ -2102,10 +2120,12 @@ main (int argc, char *argv[]) +@@ -2103,10 +2121,12 @@ main (int argc, char *argv[]) if (err < 0) /* error */ exit(1); diff --git a/0159-UPBZ-1255885-udev-waits.patch b/0159-UPBZ-1255885-udev-waits.patch index 9af0981..9e0921b 100644 --- a/0159-UPBZ-1255885-udev-waits.patch +++ b/0159-UPBZ-1255885-udev-waits.patch @@ -1,14 +1,11 @@ --- - kpartx/devmapper.c | 53 ++++++++++++++++++++++++++++++++++------------ - kpartx/devmapper.h | 4 +-- - kpartx/kpartx.c | 16 ++++++------- - libmultipath/config.h | 1 - libmultipath/configure.c | 5 ++-- - libmultipath/devmapper.c | 48 +++++++++++++++++++++++++++++++---------- - libmultipath/devmapper.h | 2 - - multipath/main.c | 2 - - multipathd/cli_handlers.c | 4 +-- - 9 files changed, 92 insertions(+), 43 deletions(-) + kpartx/devmapper.c | 41 ++++++++++++++++++++++++++++------------- + kpartx/devmapper.h | 4 ++-- + kpartx/kpartx.c | 16 ++++++++-------- + libmultipath/config.h | 1 - + libmultipath/devmapper.c | 19 +++++++++++++------ + multipath/main.c | 2 -- + 6 files changed, 51 insertions(+), 32 deletions(-) Index: multipath-tools-130222/kpartx/devmapper.c =================================================================== @@ -43,7 +40,7 @@ Index: multipath-tools-130222/kpartx/devmapper.c struct dm_task *dmt; if (!(dmt = dm_task_create(task))) -@@ -78,10 +74,23 @@ dm_simplecmd (int task, const char *name +@@ -78,10 +74,17 @@ dm_simplecmd (int task, const char *name if (no_flush) dm_task_no_flush(dmt); @@ -51,25 +48,19 @@ Index: multipath-tools-130222/kpartx/devmapper.c +#ifdef LIBDM_API_COOKIE + if (!udev_sync) + udev_flags |= DM_UDEV_DISABLE_LIBRARY_FALLBACK; -+ if (udev_wait_flag && !dm_task_set_cookie(dmt, &cookie, udev_flags)) { -+ dm_udev_complete(cookie); ++ if (udev_wait_flag && !dm_task_set_cookie(dmt, &cookie, udev_flags)) goto out; -+ } +#endif r = dm_task_run(dmt); - +#ifdef LIBDM_API_COOKIE -+ if (udev_wait_flag) { -+ if (!r) -+ dm_udev_complete(cookie); -+ else -+ dm_udev_wait(cookie); -+ } ++ if (udev_wait_flag) ++ dm_udev_wait(cookie); +#endif out: dm_task_destroy(dmt); return r; -@@ -90,10 +99,14 @@ dm_simplecmd (int task, const char *name +@@ -90,10 +93,14 @@ dm_simplecmd (int task, const char *name extern int dm_addmap (int task, const char *name, const char *target, const char *params, uint64_t size, int ro, const char *uuid, int part, @@ -85,7 +76,7 @@ Index: multipath-tools-130222/kpartx/devmapper.c if (!(dmt = dm_task_create (task))) return 0; -@@ -128,10 +141,24 @@ dm_addmap (int task, const char *name, c +@@ -128,10 +135,18 @@ dm_addmap (int task, const char *name, c dm_task_no_open_count(dmt); @@ -94,20 +85,14 @@ Index: multipath-tools-130222/kpartx/devmapper.c + if (!udev_sync) + udev_flags = DM_UDEV_DISABLE_LIBRARY_FALLBACK; + if (task == DM_DEVICE_CREATE && -+ !dm_task_set_cookie(dmt, &cookie, udev_flags)) { -+ dm_udev_complete(cookie); ++ !dm_task_set_cookie(dmt, &cookie, udev_flags)) goto addout; -+ } +#endif r = dm_task_run (dmt); - +#ifdef LIBDM_API_COOKIE -+ if (task == DM_DEVICE_CREATE) { -+ if (!r) -+ dm_udev_complete(cookie); -+ else ++ if (task == DM_DEVICE_CREATE) + dm_udev_wait(cookie); -+ } +#endif addout: dm_task_destroy (dmt); @@ -214,29 +199,6 @@ Index: multipath-tools-130222/libmultipath/config.h int reassign_maps; int retain_hwhandler; int detect_prio; -Index: multipath-tools-130222/libmultipath/configure.c -=================================================================== ---- multipath-tools-130222.orig/libmultipath/configure.c -+++ multipath-tools-130222/libmultipath/configure.c -@@ -654,7 +654,8 @@ domap (struct multipath * mpp, char * pa - case ACT_RELOAD: - r = dm_addmap_reload(mpp, params); - if (r) -- r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, (mpp->force_udev_reload)? 0 : MPATH_UDEV_RELOAD_FLAG); -+ r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, -+ 0, (mpp->force_udev_reload)? 0 : MPATH_UDEV_RELOAD_FLAG); - break; - - case ACT_RESIZE: -@@ -672,7 +673,7 @@ domap (struct multipath * mpp, char * pa - if (r) { - r = dm_addmap_reload(mpp, params); - if (r) -- r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, (mpp->force_udev_reload)? 0 : MPATH_UDEV_RELOAD_FLAG); -+ r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, 0, (mpp->force_udev_reload)? 0 : MPATH_UDEV_RELOAD_FLAG); - } - break; - Index: multipath-tools-130222/libmultipath/devmapper.c =================================================================== --- multipath-tools-130222.orig/libmultipath/devmapper.c @@ -249,38 +211,21 @@ Index: multipath-tools-130222/libmultipath/devmapper.c struct dm_task *dmt; if (!(dmt = dm_task_create (task))) -@@ -233,10 +234,18 @@ dm_simplecmd (int task, const char *name +@@ -233,10 +234,12 @@ dm_simplecmd (int task, const char *name 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)) -+ if (udev_wait_flag && !dm_task_set_cookie(dmt, &cookie, ((conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0) | udev_flags)) { -+ dm_udev_complete(cookie); ++ if (udev_wait_flag && !dm_task_set_cookie(dmt, &cookie, ((conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0) | udev_flags)) goto out; -+ } r = dm_task_run (dmt); -+ if (udev_wait_flag) { -+ if (!r) -+ dm_udev_complete(cookie); -+ else ++ if (udev_wait_flag) + udev_wait(cookie); -+ } out: dm_task_destroy (dmt); return r; -@@ -248,8 +257,8 @@ dm_simplecmd_flush (int task, const char - } - - extern int --dm_simplecmd_noflush (int task, const char *name, uint16_t udev_flags) { -- return dm_simplecmd(task, name, 1, 1, udev_flags, 0); -+dm_simplecmd_noflush (int task, const char *name, int needsync, uint16_t udev_flags) { -+ return dm_simplecmd(task, name, 1, needsync, udev_flags, 0); - } - - static int -@@ -264,6 +273,7 @@ dm_addmap (int task, const char *target, +@@ -264,6 +267,7 @@ dm_addmap (int task, const char *target, int r = 0; struct dm_task *dmt; char *prefixed_uuid = NULL; @@ -288,54 +233,21 @@ Index: multipath-tools-130222/libmultipath/devmapper.c if (!(dmt = dm_task_create (task))) return 0; -@@ -304,10 +314,18 @@ dm_addmap (int task, const char *target, +@@ -304,10 +308,12 @@ dm_addmap (int task, const char *target, dm_task_no_open_count(dmt); if (task == DM_DEVICE_CREATE && - !dm_task_set_cookie(dmt, &conf->cookie, (conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0)) -+ !dm_task_set_cookie(dmt, &cookie, (conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0)) { -+ dm_udev_complete(cookie); ++ !dm_task_set_cookie(dmt, &cookie, (conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0)) goto freeout; -+ } r = dm_task_run (dmt); -+ if (task == DM_DEVICE_CREATE) { -+ if (!r) -+ dm_udev_complete(cookie); -+ else ++ if (task == DM_DEVICE_CREATE) + udev_wait(cookie); -+ } freeout: if (prefixed_uuid) FREE(prefixed_uuid); -@@ -325,7 +343,8 @@ dm_addmap_create (struct multipath *mpp, - for (ro = 0; ro <= 1; ro++) { - int err; - -- if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, 1, ro)) -+ if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, -+ mpp, params, 1, ro)) - return 1; - /* - * DM_DEVICE_CREATE is actually DM_DEV_CREATE + DM_TABLE_LOAD. -@@ -806,14 +825,14 @@ dm_suspend_and_flush_map (const char * m - if (s) - queue_if_no_path = 0; - else -- s = dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 0, 0); -+ s = dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 1, 0); - - if (!dm_flush_map(mapname)) { - condlog(4, "multipath map %s removed", mapname); - return 0; - } - condlog(2, "failed to remove multipath map %s", mapname); -- dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname, 0); -+ dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname, 1, 0); - if (queue_if_no_path) - s = dm_queue_if_no_path((char *)mapname, 1); - return 1; -@@ -1366,6 +1385,7 @@ dm_rename (const char * old, char * new) +@@ -1366,6 +1372,7 @@ dm_rename (const char * old, char * new) { int r = 0; struct dm_task *dmt; @@ -343,7 +255,7 @@ Index: multipath-tools-130222/libmultipath/devmapper.c if (dm_rename_partmaps(old, new)) return r; -@@ -1381,14 +1401,18 @@ dm_rename (const char * old, char * new) +@@ -1381,12 +1388,12 @@ dm_rename (const char * old, char * new) dm_task_no_open_count(dmt); @@ -354,40 +266,12 @@ Index: multipath-tools-130222/libmultipath/devmapper.c goto out; + r = dm_task_run(dmt); + -+ if (!r) -+ dm_udev_complete(cookie); -+ else -+ udev_wait(cookie); ++ udev_wait(cookie); - r = 1; out: dm_task_destroy(dmt); -+ return r; - } - -@@ -1453,7 +1477,7 @@ int dm_reassign_table(const char *name, - condlog(3, "%s: failed to reassign targets", name); - goto out_reload; - } -- dm_simplecmd_noflush(DM_DEVICE_RESUME, name, MPATH_UDEV_RELOAD_FLAG); -+ dm_simplecmd_noflush(DM_DEVICE_RESUME, name, 1, MPATH_UDEV_RELOAD_FLAG); - } - r = 1; - -Index: multipath-tools-130222/libmultipath/devmapper.h -=================================================================== ---- multipath-tools-130222.orig/libmultipath/devmapper.h -+++ multipath-tools-130222/libmultipath/devmapper.h -@@ -16,7 +16,7 @@ void dm_init(void); - 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_simplecmd_noflush (int, const char *, int, uint16_t); - int dm_addmap_create (struct multipath *mpp, char *params); - int dm_addmap_reload (struct multipath *mpp, char *params); - int dm_map_present (const char *); Index: multipath-tools-130222/multipath/main.c =================================================================== --- multipath-tools-130222.orig/multipath/main.c @@ -401,25 +285,3 @@ Index: multipath-tools-130222/multipath/main.c dm_lib_release(); dm_lib_exit(); -Index: multipath-tools-130222/multipathd/cli_handlers.c -=================================================================== ---- multipath-tools-130222.orig/multipathd/cli_handlers.c -+++ multipath-tools-130222/multipathd/cli_handlers.c -@@ -807,7 +807,7 @@ cli_suspend(void * v, char ** reply, int - return 1; - } - -- r = dm_simplecmd_noflush(DM_DEVICE_SUSPEND, param, 0); -+ r = dm_simplecmd_noflush(DM_DEVICE_SUSPEND, param, 0, 0); - - condlog(2, "%s: suspend (operator)", param); - -@@ -837,7 +837,7 @@ cli_resume(void * v, char ** reply, int - return 1; - } - -- r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param, 0); -+ r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param, 0, 0); - - condlog(2, "%s: resume (operator)", param); - diff --git a/0160-RH-udev-flags.patch b/0160-RH-udev-flags.patch new file mode 100644 index 0000000..29a2c9c --- /dev/null +++ b/0160-RH-udev-flags.patch @@ -0,0 +1,20 @@ +--- + libmultipath/devmapper.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +Index: multipath-tools-130222/libmultipath/devmapper.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/devmapper.c ++++ multipath-tools-130222/libmultipath/devmapper.c +@@ -213,8 +213,9 @@ dm_prereq (void) + static int + 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)); ++ int udev_wait_flag = ((need_sync && (task == DM_DEVICE_RESUME || ++ task == DM_DEVICE_REMOVE)) || ++ udev_flags); + uint32_t cookie = 0; + struct dm_task *dmt; + diff --git a/0161-RHBZ-1311659-no-kpartx.patch b/0161-RHBZ-1311659-no-kpartx.patch new file mode 100644 index 0000000..0bce7f6 --- /dev/null +++ b/0161-RHBZ-1311659-no-kpartx.patch @@ -0,0 +1,618 @@ +--- + libmultipath/config.c | 3 + + libmultipath/config.h | 3 + + libmultipath/configure.c | 15 +++-- + libmultipath/defaults.h | 1 + libmultipath/devmapper.c | 35 +++++++++---- + libmultipath/devmapper.h | 8 ++- + libmultipath/dict.c | 114 +++++++++++++++++++++++++++++++++++++++++++++ + libmultipath/propsel.c | 26 ++++++++++ + libmultipath/propsel.h | 1 + libmultipath/structs.h | 7 ++ + multipath/multipath.conf.5 | 10 +++ + multipath/multipath.rules | 1 + multipathd/cli_handlers.c | 4 + + 13 files changed, 211 insertions(+), 17 deletions(-) + +Index: multipath-tools-130222/libmultipath/config.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.c ++++ multipath-tools-130222/libmultipath/config.c +@@ -343,6 +343,7 @@ merge_hwe (struct hwentry * dst, struct + merge_num(deferred_remove); + merge_num(delay_watch_checks); + merge_num(delay_wait_checks); ++ merge_num(skip_kpartx); + + /* + * Make sure features is consistent with +@@ -403,6 +404,7 @@ overwrite_hwe (struct hwentry * dst, str + overwrite_num(deferred_remove); + overwrite_num(delay_watch_checks); + overwrite_num(delay_wait_checks); ++ overwrite_num(skip_kpartx); + + /* + * Make sure features is consistent with +@@ -677,6 +679,7 @@ load_config (char * file, struct udev *u + conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY; + conf->new_bindings_in_boot = 0; + conf->uev_msg_delay = DEFAULT_UEV_MSG_DELAY; ++ conf->skip_kpartx = DEFAULT_SKIP_KPARTX; + + /* + * preload default hwtable +Index: multipath-tools-130222/libmultipath/config.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/config.h ++++ multipath-tools-130222/libmultipath/config.h +@@ -64,6 +64,7 @@ struct hwentry { + int deferred_remove; + int delay_watch_checks; + int delay_wait_checks; ++ int skip_kpartx; + char * bl_product; + }; + +@@ -90,6 +91,7 @@ struct mpentry { + int deferred_remove; + int delay_watch_checks; + int delay_wait_checks; ++ int skip_kpartx; + uid_t uid; + gid_t gid; + mode_t mode; +@@ -143,6 +145,7 @@ struct config { + int new_bindings_in_boot; + int delayed_reconfig; + int uev_msg_delay; ++ int skip_kpartx; + 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 +@@ -294,6 +294,7 @@ setup_map (struct multipath * mpp, char + select_deferred_remove(mpp); + select_delay_watch_checks(mpp); + select_delay_wait_checks(mpp); ++ select_skip_kpartx(mpp); + + sysfs_set_scsi_tmo(mpp); + /* +@@ -446,6 +447,7 @@ select_action (struct multipath * mpp, v + } + mpp->force_udev_reload = !pathcount(mpp, PATH_WILD); + if (cmpp->size != mpp->size) { ++ mpp->force_udev_reload = 1; + mpp->action = ACT_RESIZE; + condlog(3, "%s: set ACT_RESIZE (size change)", + mpp->alias); +@@ -609,6 +611,7 @@ extern int + domap (struct multipath * mpp, char * params) + { + int r = 0; ++ uint16_t udev_flags = ((mpp->force_udev_reload)? 0 : MPATH_UDEV_RELOAD_FLAG) | ((mpp->skip_kpartx == SKIP_KPARTX_ON)? MPATH_UDEV_NO_KPARTX_FLAG : 0); + + /* + * last chance to quit before touching the devmaps +@@ -654,25 +657,27 @@ domap (struct multipath * mpp, char * pa + case ACT_RELOAD: + r = dm_addmap_reload(mpp, params); + if (r) +- r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, (mpp->force_udev_reload)? 0 : MPATH_UDEV_RELOAD_FLAG); ++ r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, ++ udev_flags); + break; + + case ACT_RESIZE: + r = dm_addmap_reload(mpp, params); + if (r) +- r = dm_simplecmd_flush(DM_DEVICE_RESUME, mpp->alias, 1, 0); ++ r = dm_simplecmd_flush(DM_DEVICE_RESUME, mpp->alias, 1, ++ udev_flags); + break; + + case ACT_RENAME: +- r = dm_rename(mpp->alias_old, mpp->alias); ++ r = dm_rename(mpp->alias_old, mpp->alias, mpp->skip_kpartx); + break; + + case ACT_RENAME2: +- r = dm_rename(mpp->alias_old, mpp->alias); ++ r = dm_rename(mpp->alias_old, mpp->alias, mpp->skip_kpartx); + if (r) { + r = dm_addmap_reload(mpp, params); + if (r) +- r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, (mpp->force_udev_reload)? 0 : MPATH_UDEV_RELOAD_FLAG); ++ r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, udev_flags); + } + break; + +Index: multipath-tools-130222/libmultipath/defaults.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/defaults.h ++++ multipath-tools-130222/libmultipath/defaults.h +@@ -24,6 +24,7 @@ + #define DEFAULT_RETRIGGER_DELAY 10 + #define DEFAULT_RETRIGGER_TRIES 3 + #define DEFAULT_UEV_MSG_DELAY 30 ++#define DEFAULT_SKIP_KPARTX SKIP_KPARTX_OFF + + #define DEFAULT_CHECKINT 5 + #define MAX_CHECKINT(a) (a << 2) +Index: multipath-tools-130222/libmultipath/devmapper.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/devmapper.c ++++ multipath-tools-130222/libmultipath/devmapper.c +@@ -262,13 +262,14 @@ dm_device_remove (const char *name, int + deferred_remove); + } + +-extern int ++static int + dm_addmap (int task, const char *target, struct multipath *mpp, char * params, +- int use_uuid, int ro) { ++ int use_uuid, int ro, int skip_kpartx) { + int r = 0; + struct dm_task *dmt; + char *prefixed_uuid = NULL; + uint32_t cookie = 0; ++ uint16_t udev_flags = ((conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0) | ((skip_kpartx == SKIP_KPARTX_ON)? MPATH_UDEV_NO_KPARTX_FLAG : 0); + + if (!(dmt = dm_task_create (task))) + return 0; +@@ -309,7 +310,7 @@ dm_addmap (int task, const char *target, + dm_task_no_open_count(dmt); + + if (task == DM_DEVICE_CREATE && +- !dm_task_set_cookie(dmt, &cookie, (conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0)) ++ !dm_task_set_cookie(dmt, &cookie, udev_flags)) + goto freeout; + r = dm_task_run (dmt); + +@@ -332,7 +333,8 @@ dm_addmap_create (struct multipath *mpp, + for (ro = 0; ro <= 1; ro++) { + int err; + +- if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, 1, ro)) ++ if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, ++ mpp, params, 1, ro, mpp->skip_kpartx)) + return 1; + /* + * DM_DEVICE_CREATE is actually DM_DEV_CREATE + DM_TABLE_LOAD. +@@ -354,11 +356,11 @@ dm_addmap_create (struct multipath *mpp, + + extern int + dm_addmap_reload (struct multipath *mpp, char *params) { +- if (dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RW)) ++ if (dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RW, SKIP_KPARTX_OFF)) + return 1; + if (errno != EROFS) + return 0; +- return dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RO); ++ return dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RO, SKIP_KPARTX_OFF); + } + + extern int +@@ -720,6 +722,12 @@ out: + } + + static int ++has_partmap(const char *name, void *data) ++{ ++ return 1; ++} ++ ++static int + partmap_in_use(const char *name, void *data) + { + int part_count, *ret_count = (int *)data; +@@ -798,10 +806,16 @@ dm_suspend_and_flush_map (const char * m + int s = 0, queue_if_no_path = 0; + unsigned long long mapsize; + char params[PARAMS_SIZE] = {0}; ++ int udev_flags = 0; + + if (!dm_is_mpath(mapname)) + return 0; /* nothing to do */ + ++ /* if the device currently has no partitions, do not ++ run kpartx on it if you fail to delete it */ ++ if (do_foreach_partmaps(mapname, has_partmap, NULL) == 0) ++ udev_flags |= MPATH_UDEV_NO_KPARTX_FLAG; ++ + if (!dm_get_map(mapname, &mapsize, params)) { + if (strstr(params, "queue_if_no_path")) + queue_if_no_path = 1; +@@ -820,7 +834,7 @@ dm_suspend_and_flush_map (const char * m + return 0; + } + condlog(2, "failed to remove multipath map %s", mapname); +- dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname, 0); ++ dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname, udev_flags); + if (queue_if_no_path) + s = dm_queue_if_no_path((char *)mapname, 1); + return 1; +@@ -1349,7 +1363,7 @@ rename_partmap (const char *name, void * + for (offset = strlen(rd->old); name[offset] && !(isdigit(name[offset])); offset++); /* do nothing */ + snprintf(buff, PARAMS_SIZE, "%s%s%s", rd->new, rd->delim, + name + offset); +- dm_rename(name, buff); ++ dm_rename(name, buff, SKIP_KPARTX_OFF); + condlog(4, "partition map %s renamed", name); + return 0; + } +@@ -1369,11 +1383,12 @@ dm_rename_partmaps (const char * old, ch + } + + int +-dm_rename (const char * old, char * new) ++dm_rename (const char * old, char * new, int skip_kpartx) + { + int r = 0; + struct dm_task *dmt; + uint32_t cookie; ++ uint16_t udev_flags = ((conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0) | ((skip_kpartx == SKIP_KPARTX_ON)? MPATH_UDEV_NO_KPARTX_FLAG : 0); + + if (dm_rename_partmaps(old, new)) + return r; +@@ -1389,7 +1404,7 @@ dm_rename (const char * old, char * new) + + dm_task_no_open_count(dmt); + +- if (!dm_task_set_cookie(dmt, &cookie, (conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0)) ++ if (!dm_task_set_cookie(dmt, &cookie, udev_flags)) + goto out; + r = dm_task_run(dmt); + +Index: multipath-tools-130222/libmultipath/devmapper.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/devmapper.h ++++ multipath-tools-130222/libmultipath/devmapper.h +@@ -12,6 +12,12 @@ + #define MPATH_UDEV_RELOAD_FLAG 0 + #endif + ++#ifdef DM_SUBSYSTEM_UDEV_FLAG1 ++#define MPATH_UDEV_NO_KPARTX_FLAG DM_SUBSYSTEM_UDEV_FLAG1 ++#else ++#define MPATH_UDEV_NO_KPARTX_FLAG 0 ++#endif ++ + void dm_init(void); + int dm_prereq (void); + int dm_drv_version (unsigned int * version, char * str); +@@ -47,7 +53,7 @@ int dm_remove_partmaps (const char * map + int deferred_remove); + int dm_get_uuid(char *name, char *uuid); + int dm_get_info (char * mapname, struct dm_info ** dmi); +-int dm_rename (const char * old, char * new); ++int dm_rename (const char * old, char * new, int skip_kpartx); + int dm_reassign(const char * mapname); + int dm_reassign_table(const char *name, char *old, char *new); + int dm_setgeometry(struct multipath *mpp); +Index: multipath-tools-130222/libmultipath/dict.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/dict.c ++++ multipath-tools-130222/libmultipath/dict.c +@@ -779,6 +779,29 @@ def_deferred_remove_handler(vector strve + } + + static int ++def_skip_kpartx_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->skip_kpartx = SKIP_KPARTX_OFF; ++ else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) || ++ (strlen(buff) == 1 && !strcmp(buff, "1"))) ++ conf->skip_kpartx = SKIP_KPARTX_ON; ++ else ++ conf->skip_kpartx = DEFAULT_SKIP_KPARTX; ++ ++ FREE(buff); ++ return 0; ++} ++ ++static int + def_ignore_new_boot_devs_handler(vector strvec) + { + char * buff; +@@ -1629,6 +1652,33 @@ hw_deferred_remove_handler(vector strvec + } + + static int ++hw_skip_kpartx_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->skip_kpartx = SKIP_KPARTX_OFF; ++ else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) || ++ (strlen(buff) == 1 && !strcmp(buff, "1"))) ++ hwe->skip_kpartx = SKIP_KPARTX_ON; ++ else ++ hwe->skip_kpartx = SKIP_KPARTX_UNDEF; ++ ++ FREE(buff); ++ return 0; ++} ++ ++static int + hw_delay_watch_checks_handler(vector strvec) + { + struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable); +@@ -2154,6 +2204,32 @@ mp_deferred_remove_handler(vector strvec + } + + static int ++mp_skip_kpartx_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") == 0) || ++ (strlen(buff) == 1 && strcmp(buff, "0") == 0)) ++ mpe->skip_kpartx = SKIP_KPARTX_OFF; ++ else if ((strlen(buff) == 3 && strcmp(buff, "yes") == 0) || ++ (strlen(buff) == 1 && strcmp(buff, "1") == 0)) ++ mpe->skip_kpartx = SKIP_KPARTX_ON; ++ else ++ mpe->skip_kpartx = SKIP_KPARTX_UNDEF; ++ ++ FREE(buff); ++ return 0; ++} ++ ++static int + mp_delay_watch_checks_handler(vector strvec) + { + struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable); +@@ -2461,6 +2537,19 @@ snprint_mp_deferred_remove (char * buff, + } + + static int ++snprint_mp_skip_kpartx (char * buff, int len, void * data) ++{ ++ struct mpentry * mpe = (struct mpentry *)data; ++ ++ if (mpe->skip_kpartx == SKIP_KPARTX_UNDEF) ++ return 0; ++ else if (mpe->skip_kpartx == SKIP_KPARTX_OFF) ++ return snprintf(buff, len, "no"); ++ else ++ return snprintf(buff, len, "yes"); ++} ++ ++static int + snprint_mp_delay_watch_checks(char * buff, int len, void * data) + { + struct mpentry * mpe = (struct mpentry *)data; +@@ -2813,6 +2902,19 @@ snprint_hw_deferred_remove(char * buff, + } + + static int ++snprint_hw_skip_kpartx(char * buff, int len, void * data) ++{ ++ struct hwentry * hwe = (struct hwentry *)data; ++ ++ if (hwe->skip_kpartx == SKIP_KPARTX_ON) ++ return snprintf(buff, len, "yes"); ++ else if (hwe->skip_kpartx == SKIP_KPARTX_OFF) ++ return snprintf(buff, len, "no"); ++ else ++ return 0; ++} ++ ++static int + snprint_hw_delay_watch_checks(char * buff, int len, void * data) + { + struct hwentry * hwe = (struct hwentry *)data; +@@ -3231,6 +3333,15 @@ snprint_def_deferred_remove(char * buff, + } + + static int ++snprint_def_skip_kpartx(char * buff, int len, void * data) ++{ ++ if (conf->skip_kpartx == SKIP_KPARTX_ON) ++ return snprintf(buff, len, "yes"); ++ else ++ return snprintf(buff, len, "no"); ++} ++ ++static int + snprint_def_ignore_new_boot_devs(char * buff, int len, void * data) + { + if (conf->ignore_new_boot_devs == 1) +@@ -3364,6 +3475,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("skip_kpartx", &def_skip_kpartx_handler, &snprint_def_skip_kpartx); + 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); +@@ -3438,6 +3550,7 @@ init_keywords(void) + 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_keyword("skip_kpartx", &hw_skip_kpartx_handler, &snprint_hw_skip_kpartx); + install_sublevel_end(); + + install_keyword_root("multipaths", &multipaths_handler); +@@ -3465,5 +3578,6 @@ init_keywords(void) + 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_keyword("skip_kpartx", &mp_skip_kpartx_handler, &snprint_mp_skip_kpartx); + install_sublevel_end(); + } +Index: multipath-tools-130222/libmultipath/propsel.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/propsel.c ++++ multipath-tools-130222/libmultipath/propsel.c +@@ -854,3 +854,29 @@ select_delay_wait_checks (struct multipa + condlog(3, "delay_wait_checks = DISABLED (internal default)"); + return 0; + } ++ ++extern int ++select_skip_kpartx (struct multipath * mp) ++{ ++ if (mp->mpe && mp->mpe->skip_kpartx != SKIP_KPARTX_UNDEF) { ++ mp->skip_kpartx = mp->mpe->skip_kpartx; ++ condlog(3, "skip_kpartx = %i (multipath setting)", ++ mp->skip_kpartx); ++ return 0; ++ } ++ if (mp->hwe && mp->hwe->skip_kpartx != SKIP_KPARTX_UNDEF) { ++ mp->skip_kpartx = mp->hwe->skip_kpartx; ++ condlog(3, "skip_kpartx = %i (controler setting)", ++ mp->skip_kpartx); ++ return 0; ++ } ++ if (conf->skip_kpartx != SKIP_KPARTX_UNDEF) { ++ mp->skip_kpartx = conf->skip_kpartx; ++ condlog(3, "skip_kpartx = %i (config file default)", ++ mp->skip_kpartx); ++ return 0; ++ } ++ mp->skip_kpartx = DEFAULT_SKIP_KPARTX; ++ condlog(3, "skip_kpartx = 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 +@@ -23,3 +23,4 @@ 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); ++int select_skip_kpartx (struct multipath * mp); +Index: multipath-tools-130222/libmultipath/structs.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/structs.h ++++ multipath-tools-130222/libmultipath/structs.h +@@ -121,6 +121,12 @@ enum deferred_remove_states { + DEFERRED_REMOVE_IN_PROGRESS, + }; + ++enum skip_kpartx_states { ++ SKIP_KPARTX_UNDEF, ++ SKIP_KPARTX_OFF, ++ SKIP_KPARTX_ON, ++}; ++ + enum scsi_protocol { + SCSI_PROTOCOL_FCP = 0, /* Fibre Channel */ + SCSI_PROTOCOL_SPI = 1, /* parallel SCSI */ +@@ -236,6 +242,7 @@ struct multipath { + int delay_watch_checks; + int delay_wait_checks; + int force_udev_reload; ++ int skip_kpartx; + unsigned int dev_loss; + uid_t uid; + gid_t gid; +Index: multipath-tools-130222/multipath/multipath.rules +=================================================================== +--- multipath-tools-130222.orig/multipath/multipath.rules ++++ multipath-tools-130222/multipath/multipath.rules +@@ -44,6 +44,7 @@ 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_SUBSYSTEM_UDEV_FLAG1}=="1", 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" +Index: multipath-tools-130222/multipathd/cli_handlers.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/cli_handlers.c ++++ multipath-tools-130222/multipathd/cli_handlers.c +@@ -825,19 +825,21 @@ cli_resume(void * v, char ** reply, int + char * param = get_keyparam(v, MAP); + int r; + struct multipath * mpp; ++ uint16_t udev_flags; + + param = convert_dev(param, 0); + mpp = find_mp_by_alias(vecs->mpvec, param); + if (!mpp) + return 1; + ++ udev_flags = (mpp->skip_kpartx)? MPATH_UDEV_NO_KPARTX_FLAG : 0; + if (mpp->wait_for_udev) { + condlog(2, "%s: device not fully created, failing resume", + mpp->alias); + return 1; + } + +- r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param, 0); ++ r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param, udev_flags); + + condlog(2, "%s: resume (operator)", param); + +Index: multipath-tools-130222/multipath/multipath.conf.5 +=================================================================== +--- multipath-tools-130222.orig/multipath/multipath.conf.5 ++++ multipath-tools-130222/multipath/multipath.conf.5 +@@ -505,6 +505,12 @@ message. This warning message will print + .I missing_uev_msg_delay + seconds until the uevent is received. the default is + .I 30 ++.TP ++.B skip_kpartx ++If set to ++.I yes ++, kpartx will not automatically create partitions on the device. The default is ++.I no + . + .SH "blacklist section" + The +@@ -612,6 +618,8 @@ section: + .B delay_watch_checks + .TP + .B delay_wait_checks ++.TP ++.B skip_kpartx + .RE + .PD + .LP +@@ -708,6 +716,8 @@ section: + .B delay_watch_checks + .TP + .B delay_wait_checks ++.TP ++.B skip_kpartx + .RE + .PD + .LP diff --git a/0162-RHBZ-1333331-huawei-config.patch b/0162-RHBZ-1333331-huawei-config.patch new file mode 100644 index 0000000..7b97e07 --- /dev/null +++ b/0162-RHBZ-1333331-huawei-config.patch @@ -0,0 +1,24 @@ +--- + libmultipath/hwtable.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +Index: multipath-tools-130222/libmultipath/hwtable.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/hwtable.c ++++ multipath-tools-130222/libmultipath/hwtable.c +@@ -1182,6 +1182,15 @@ static struct hwentry default_hw[] = { + .dev_loss = 60, + .prio_args = NULL, + }, ++ { ++ .vendor = "HUAWEI", ++ .product = "XSG1", ++ .features = DEFAULT_FEATURES, ++ .hwhandler = DEFAULT_HWHANDLER, ++ .pgpolicy = MULTIBUS, ++ .pgfailback = -FAILBACK_IMMEDIATE, ++ .checker_name = TUR, ++ }, + /* + * EOL + */ diff --git a/0163-UPBZ-1333492-resize-map.patch b/0163-UPBZ-1333492-resize-map.patch new file mode 100644 index 0000000..cc24b6f --- /dev/null +++ b/0163-UPBZ-1333492-resize-map.patch @@ -0,0 +1,24 @@ +--- + multipathd/cli_handlers.c | 2 ++ + 1 file changed, 2 insertions(+) + +Index: multipath-tools-130222/multipathd/cli_handlers.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/cli_handlers.c ++++ multipath-tools-130222/multipathd/cli_handlers.c +@@ -571,6 +571,7 @@ int resize_map(struct multipath *mpp, un + struct vectors * vecs) + { + char params[PARAMS_SIZE] = {0}; ++ unsigned long long orig_size = mpp->size; + + mpp->size = size; + update_mpp_paths(mpp, vecs->pathvec); +@@ -579,6 +580,7 @@ int resize_map(struct multipath *mpp, un + if (domap(mpp, params) <= 0) { + condlog(0, "%s: failed to resize map : %s", mpp->alias, + strerror(errno)); ++ mpp->size = orig_size; + return 1; + } + return 0; diff --git a/0164-RHBZ-1311463-dos-part-rollover.patch b/0164-RHBZ-1311463-dos-part-rollover.patch new file mode 100644 index 0000000..dc511f2 --- /dev/null +++ b/0164-RHBZ-1311463-dos-part-rollover.patch @@ -0,0 +1,17 @@ +--- + kpartx/dos.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: multipath-tools-130222/kpartx/dos.c +=================================================================== +--- multipath-tools-130222.orig/kpartx/dos.c ++++ multipath-tools-130222/kpartx/dos.c +@@ -78,7 +78,7 @@ read_dos_pt(int fd, struct slice all, st + unsigned long offset = all.start; + int i, n=4; + unsigned char *bp; +- int sector_size_mul = get_sector_size(fd)/512; ++ uint64_t sector_size_mul = get_sector_size(fd)/512; + + bp = (unsigned char *)getblock(fd, offset); + if (bp == NULL) diff --git a/0165-UPBZ-1341748-MSA-2040-conf.patch b/0165-UPBZ-1341748-MSA-2040-conf.patch new file mode 100644 index 0000000..6c6e64a --- /dev/null +++ b/0165-UPBZ-1341748-MSA-2040-conf.patch @@ -0,0 +1,30 @@ +--- + libmultipath/hwtable.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +Index: multipath-tools-130222/libmultipath/hwtable.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/hwtable.c ++++ multipath-tools-130222/libmultipath/hwtable.c +@@ -175,6 +175,21 @@ static struct hwentry default_hw[] = { + .prio_name = PRIO_ALUA, + .prio_args = NULL, + }, ++ { ++ /* HP MSA 1040/2040 product family */ ++ .vendor = "HP", ++ .product = "MSA (1|2)040 SA(N|S)", ++ .features = DEFAULT_FEATURES, ++ .hwhandler = DEFAULT_HWHANDLER, ++ .pgpolicy = GROUP_BY_PRIO, ++ .pgfailback = -FAILBACK_IMMEDIATE, ++ .rr_weight = RR_WEIGHT_NONE, ++ .no_path_retry = 18, ++ .minio = 100, ++ .checker_name = TUR, ++ .prio_name = PRIO_ALUA, ++ .prio_args = NULL, ++ }, + + { + /* HP SVSP */ diff --git a/0166-RHBZ-1323429-dont-allow-new-wwid.patch b/0166-RHBZ-1323429-dont-allow-new-wwid.patch new file mode 100644 index 0000000..b0fc664 --- /dev/null +++ b/0166-RHBZ-1323429-dont-allow-new-wwid.patch @@ -0,0 +1,24 @@ +--- + libmultipath/dmparser.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +Index: multipath-tools-130222/libmultipath/dmparser.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/dmparser.c ++++ multipath-tools-130222/libmultipath/dmparser.c +@@ -360,6 +360,15 @@ disassemble_map (vector pathvec, char * + else if (!strlen(pp->wwid)) + strncpy(pp->wwid, mpp->wwid, WWID_SIZE); + ++ /* ++ * Something went wrong. Likely the user changed the ++ * path uid_attribute after creating a device ++ */ ++ else if (strcmp(pp->wwid, mpp->wwid) != 0) { ++ condlog(0, "%s: path wwid appears to have changed. Using old wwid.\n", pp->dev_t); ++ strncpy(pp->wwid, mpp->wwid, WWID_SIZE); ++ } ++ + pgp->id ^= (long)pp; + pp->pgindex = i + 1; + diff --git a/0167-RHBZ-1335176-fix-show-cmds.patch b/0167-RHBZ-1335176-fix-show-cmds.patch new file mode 100644 index 0000000..55154b6 --- /dev/null +++ b/0167-RHBZ-1335176-fix-show-cmds.patch @@ -0,0 +1,138 @@ +--- + libmultipath/print.c | 7 +++++++ + libmultipath/structs.h | 1 + + libmultipath/structs_vec.c | 24 ++++++++++++++---------- + multipathd/cli_handlers.c | 11 ++++++++++- + multipathd/main.c | 2 ++ + 5 files changed, 34 insertions(+), 11 deletions(-) + +Index: multipath-tools-130222/libmultipath/print.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/print.c ++++ multipath-tools-130222/libmultipath/print.c +@@ -248,6 +248,12 @@ snprint_q_timeouts (char * buff, size_t + } + + static int ++snprint_map_failures (char * buff, size_t len, struct multipath * mpp) ++{ ++ return snprint_uint(buff, len, mpp->stat_map_failures); ++} ++ ++static int + snprint_multipath_uuid (char * buff, size_t len, struct multipath * mpp) + { + return snprint_str(buff, len, mpp->wwid); +@@ -546,6 +552,7 @@ struct multipath_data mpd[] = { + {'t', "dm-st", 0, snprint_dm_map_state}, + {'S', "size", 0, snprint_multipath_size}, + {'f', "features", 0, snprint_features}, ++ {'x', "failures", 0, snprint_map_failures}, + {'h', "hwhandler", 0, snprint_hwhandler}, + {'A', "action", 0, snprint_action}, + {'0', "path_faults", 0, snprint_path_faults}, +Index: multipath-tools-130222/libmultipath/structs.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/structs.h ++++ multipath-tools-130222/libmultipath/structs.h +@@ -270,6 +270,7 @@ struct multipath { + unsigned int stat_map_loads; + unsigned int stat_total_queueing_time; + unsigned int stat_queueing_timeouts; ++ unsigned int stat_map_failures; + + /* checkers shared data */ + void * mpcontext; +Index: multipath-tools-130222/libmultipath/structs_vec.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/structs_vec.c ++++ multipath-tools-130222/libmultipath/structs_vec.c +@@ -579,16 +579,20 @@ int update_multipath (struct vectors *ve + */ + void update_queue_mode_del_path(struct multipath *mpp) + { +- if (--mpp->nr_active == 0 && mpp->no_path_retry > 0) { +- /* +- * Enter retry mode. +- * meaning of +1: retry_tick may be decremented in +- * checkerloop before starting retry. +- */ +- mpp->stat_queueing_timeouts++; +- mpp->retry_tick = mpp->no_path_retry * conf->checkint + 1; +- condlog(1, "%s: Entering recovery mode: max_retries=%d", +- mpp->alias, mpp->no_path_retry); ++ if (--mpp->nr_active == 0) { ++ if (mpp->no_path_retry > 0) { ++ /* ++ * Enter retry mode. ++ * meaning of +1: retry_tick may be decremented in ++ * checkerloop before starting retry. ++ */ ++ mpp->stat_queueing_timeouts++; ++ mpp->retry_tick = mpp->no_path_retry * ++ conf->checkint + 1; ++ condlog(1, "%s: Entering recovery mode: max_retries=%d", ++ mpp->alias, mpp->no_path_retry); ++ } else if (mpp->no_path_retry != NO_PATH_RETRY_QUEUE) ++ mpp->stat_map_failures++; + } + condlog(2, "%s: remaining active paths: %d", mpp->alias, mpp->nr_active); + } +Index: multipath-tools-130222/multipathd/cli_handlers.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/cli_handlers.c ++++ multipath-tools-130222/multipathd/cli_handlers.c +@@ -319,9 +319,14 @@ show_maps (char ** r, int *len, struct v + c += snprint_multipath_header(c, reply + maxlen - c, + style); + +- vector_foreach_slot(vecs->mpvec, mpp, i) ++ vector_foreach_slot(vecs->mpvec, mpp, i) { ++ if (update_multipath(vecs, mpp->alias, 0)) { ++ i--; ++ continue; ++ } + c += snprint_multipath(c, reply + maxlen - c, + style, mpp, pretty); ++ } + + again = ((c - reply) == (maxlen - 1)); + +@@ -742,6 +747,8 @@ cli_disable_queueing(void *v, char **rep + return 1; + } + ++ if (mpp->nr_active == 0) ++ mpp->stat_map_failures++; + mpp->retry_tick = 0; + dm_queue_if_no_path(mpp->alias, 0); + return 0; +@@ -756,6 +763,8 @@ cli_disable_all_queueing(void *v, char * + + condlog(2, "disable queueing (operator)"); + vector_foreach_slot(vecs->mpvec, mpp, i) { ++ if (mpp->nr_active == 0) ++ mpp->stat_map_failures++; + mpp->retry_tick = 0; + dm_queue_if_no_path(mpp->alias, 0); + } +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -716,6 +716,7 @@ ev_remove_path (struct path *pp, struct + mpp->retry_tick = 0; + mpp->no_path_retry = NO_PATH_RETRY_FAIL; + mpp->flush_on_last_del = FLUSH_IN_PROGRESS; ++ mpp->stat_map_failures++; + dm_queue_if_no_path(mpp->alias, 0); + } + if (!flush_map(mpp, vecs, 1)) { +@@ -1184,6 +1185,7 @@ retry_count_tick(vector mpvec) + mpp->stat_total_queueing_time++; + condlog(4, "%s: Retrying.. No active path", mpp->alias); + if(--mpp->retry_tick == 0) { ++ mpp->stat_map_failures++; + dm_queue_if_no_path(mpp->alias, 0); + condlog(2, "%s: Disable queueing", mpp->alias); + } diff --git a/0168-RHBZ-1347769-shared-lock.patch b/0168-RHBZ-1347769-shared-lock.patch new file mode 100644 index 0000000..084d112 --- /dev/null +++ b/0168-RHBZ-1347769-shared-lock.patch @@ -0,0 +1,17 @@ +--- + libmultipath/configure.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: multipath-tools-130222/libmultipath/configure.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/configure.c ++++ multipath-tools-130222/libmultipath/configure.c +@@ -552,7 +552,7 @@ lock_multipath (struct multipath * mpp, + if (!pgp->paths) + continue; + vector_foreach_slot(pgp->paths, pp, j) { +- if (lock && flock(pp->fd, LOCK_EX | LOCK_NB) && ++ if (lock && flock(pp->fd, LOCK_SH | LOCK_NB) && + errno == EWOULDBLOCK) + goto fail; + else if (!lock) diff --git a/0169-UPBZ-1353357-json-output.patch b/0169-UPBZ-1353357-json-output.patch new file mode 100644 index 0000000..14fa840 --- /dev/null +++ b/0169-UPBZ-1353357-json-output.patch @@ -0,0 +1,549 @@ +--- + libmultipath/print.c | 222 ++++++++++++++++++++++++++++++++++++++++++++++ + libmultipath/print.h | 61 ++++++++++++ + multipathd/cli.c | 3 + multipathd/cli.h | 2 + multipathd/cli_handlers.c | 93 +++++++++++++++++++ + multipathd/cli_handlers.h | 2 + multipathd/main.c | 2 + multipathd/multipathd.8 | 9 + + 8 files changed, 393 insertions(+), 1 deletion(-) + +Index: multipath-tools-130222/libmultipath/print.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/print.c ++++ multipath-tools-130222/libmultipath/print.c +@@ -269,6 +269,61 @@ snprint_multipath_vpr (char * buff, size + pp->vendor_id, pp->product_id); + } + ++ ++static int ++snprint_multipath_vend (char * buff, size_t len, struct multipath * mpp) ++{ ++ struct pathgroup * pgp; ++ struct path * pp; ++ int i, j; ++ ++ vector_foreach_slot(mpp->pg, pgp, i) { ++ if (!pgp) ++ continue; ++ vector_foreach_slot(pgp->paths, pp, j) { ++ if (strlen(pp->vendor_id)) ++ return snprintf(buff, len, "%s", pp->vendor_id); ++ } ++ } ++ return snprintf(buff, len, "##"); ++} ++ ++static int ++snprint_multipath_prod (char * buff, size_t len, struct multipath * mpp) ++{ ++ struct pathgroup * pgp; ++ struct path * pp; ++ int i, j; ++ ++ vector_foreach_slot(mpp->pg, pgp, i) { ++ if (!pgp) ++ continue; ++ vector_foreach_slot(pgp->paths, pp, j) { ++ if (strlen(pp->product_id)) ++ return snprintf(buff, len, "%s", pp->product_id); ++ } ++ } ++ return snprintf(buff, len, "##"); ++} ++ ++static int ++snprint_multipath_rev (char * buff, size_t len, struct multipath * mpp) ++{ ++ struct pathgroup * pgp; ++ struct path * pp; ++ int i, j; ++ ++ vector_foreach_slot(mpp->pg, pgp, i) { ++ if (!pgp) ++ continue; ++ vector_foreach_slot(pgp->paths, pp, j) { ++ if (strlen(pp->rev)) ++ return snprintf(buff, len, "%s", pp->rev); ++ } ++ } ++ return snprintf(buff, len, "##"); ++} ++ + static int + snprint_action (char * buff, size_t len, struct multipath * mpp) + { +@@ -561,6 +616,9 @@ struct multipath_data mpd[] = { + {'3', "total_q_time", 0, snprint_total_q_time}, + {'4', "q_timeouts", 0, snprint_q_timeouts}, + {'s', "vend/prod/rev", 0, snprint_multipath_vpr}, ++ {'v', "vend", 0, snprint_multipath_vend}, ++ {'p', "prod", 0, snprint_multipath_prod}, ++ {'e', "rev", 0, snprint_multipath_rev}, + {0, NULL, 0 , NULL} + }; + +@@ -983,6 +1041,170 @@ snprint_multipath_topology (char * buff, + return fwd; + } + ++static int ++snprint_json (char * buff, int len, int indent, char *json_str) ++{ ++ int fwd = 0, i; ++ ++ for (i = 0; i < indent; i++) { ++ fwd += snprintf(buff + fwd, len - fwd, PRINT_JSON_INDENT); ++ if (fwd > len) ++ return fwd; ++ } ++ ++ fwd += snprintf(buff + fwd, len - fwd, "%s", json_str); ++ return fwd; ++} ++ ++static int ++snprint_json_header (char * buff, int len) ++{ ++ int fwd = 0; ++ ++ fwd += snprint_json(buff, len, 0, PRINT_JSON_START_ELEM); ++ if (fwd > len) ++ return fwd; ++ ++ fwd += snprintf(buff + fwd, len - fwd, PRINT_JSON_START_VERSION, ++ PRINT_JSON_MAJOR_VERSION, PRINT_JSON_MINOR_VERSION); ++ return fwd; ++} ++ ++static int ++snprint_json_elem_footer (char * buff, int len, int indent, int last) ++{ ++ int fwd = 0, i; ++ ++ for (i = 0; i < indent; i++) { ++ fwd += snprintf(buff + fwd, len - fwd, PRINT_JSON_INDENT); ++ if (fwd > len) ++ return fwd; ++ } ++ ++ if (last == 1) ++ fwd += snprintf(buff + fwd, len - fwd, "%s", PRINT_JSON_END_LAST_ELEM); ++ else ++ fwd += snprintf(buff + fwd, len - fwd, "%s", PRINT_JSON_END_ELEM); ++ return fwd; ++} ++ ++static int ++snprint_multipath_fields_json (char * buff, int len, ++ struct multipath * mpp, int last) ++{ ++ int i, j, fwd = 0; ++ struct path *pp; ++ struct pathgroup *pgp; ++ ++ fwd += snprint_multipath(buff, len, PRINT_JSON_MAP, mpp, 0); ++ if (fwd > len) ++ return fwd; ++ ++ fwd += snprint_json(buff + fwd, len - fwd, 2, PRINT_JSON_START_GROUPS); ++ if (fwd > len) ++ return fwd; ++ ++ vector_foreach_slot (mpp->pg, pgp, i) { ++ ++ pgp->selector = mpp->selector; ++ fwd += snprint_pathgroup(buff + fwd, len - fwd, PRINT_JSON_GROUP, pgp); ++ if (fwd > len) ++ return fwd; ++ ++ fwd += snprintf(buff + fwd, len - fwd, PRINT_JSON_GROUP_NUM, i + 1); ++ if (fwd > len) ++ return fwd; ++ ++ fwd += snprint_json(buff + fwd, len - fwd, 3, PRINT_JSON_START_PATHS); ++ if (fwd > len) ++ return fwd; ++ ++ vector_foreach_slot (pgp->paths, pp, j) { ++ fwd += snprint_path(buff + fwd, len - fwd, PRINT_JSON_PATH, pp, 0); ++ if (fwd > len) ++ return fwd; ++ ++ fwd += snprint_json_elem_footer(buff + fwd, ++ len - fwd, 3, j + 1 == VECTOR_SIZE(pgp->paths)); ++ if (fwd > len) ++ return fwd; ++ } ++ fwd += snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_END_ARRAY); ++ if (fwd > len) ++ return fwd; ++ ++ fwd += snprint_json_elem_footer(buff + fwd, ++ len - fwd, 2, i + 1 == VECTOR_SIZE(mpp->pg)); ++ if (fwd > len) ++ return fwd; ++ } ++ ++ fwd += snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_END_ARRAY); ++ if (fwd > len) ++ return fwd; ++ ++ fwd += snprint_json_elem_footer(buff + fwd, len - fwd, 1, last); ++ return fwd; ++} ++ ++int ++snprint_multipath_map_json (char * buff, int len, ++ struct multipath * mpp, int last){ ++ int fwd = 0; ++ ++ fwd += snprint_json_header(buff, len); ++ if (fwd > len) ++ return len; ++ ++ fwd += snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_START_MAP); ++ if (fwd > len) ++ return len; ++ ++ fwd += snprint_multipath_fields_json(buff + fwd, len - fwd, mpp, 1); ++ if (fwd > len) ++ return len; ++ ++ fwd += snprint_json(buff + fwd, len - fwd, 0, "\n"); ++ if (fwd > len) ++ return len; ++ ++ fwd += snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_END_LAST); ++ if (fwd > len) ++ return len; ++ return fwd; ++} ++ ++int ++snprint_multipath_topology_json (char * buff, int len, struct vectors * vecs) ++{ ++ int i, fwd = 0; ++ struct multipath * mpp; ++ ++ fwd += snprint_json_header(buff, len); ++ if (fwd > len) ++ return len; ++ ++ fwd += snprint_json(buff + fwd, len - fwd, 1, PRINT_JSON_START_MAPS); ++ if (fwd > len) ++ return len; ++ ++ vector_foreach_slot(vecs->mpvec, mpp, i) { ++ fwd += snprint_multipath_fields_json(buff + fwd, len - fwd, ++ mpp, i + 1 == VECTOR_SIZE(vecs->mpvec)); ++ if (fwd > len) ++ return len; ++ } ++ ++ fwd += snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_END_ARRAY); ++ if (fwd > len) ++ return len; ++ ++ fwd += snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_END_LAST); ++ if (fwd > len) ++ return len; ++ return fwd; ++} ++ + static int + snprint_hwentry (char * buff, int len, struct hwentry * hwe) + { +Index: multipath-tools-130222/libmultipath/print.h +=================================================================== +--- multipath-tools-130222.orig/libmultipath/print.h ++++ multipath-tools-130222/libmultipath/print.h +@@ -7,6 +7,63 @@ + #define PRINT_MAP_PROPS "size=%S features='%f' hwhandler='%h' wp=%r" + #define PRINT_PG_INDENT "policy='%s' prio=%p status=%t" + ++#define PRINT_JSON_MULTIPLIER 5 ++#define PRINT_JSON_MAJOR_VERSION 0 ++#define PRINT_JSON_MINOR_VERSION 1 ++#define PRINT_JSON_START_VERSION " \"major_version\": %d,\n" \ ++ " \"minor_version\": %d,\n" ++#define PRINT_JSON_START_ELEM "{\n" ++#define PRINT_JSON_START_MAP " \"map\":" ++#define PRINT_JSON_START_MAPS "\"maps\": [" ++#define PRINT_JSON_START_PATHS "\"paths\": [" ++#define PRINT_JSON_START_GROUPS "\"path_groups\": [" ++#define PRINT_JSON_END_ELEM "}," ++#define PRINT_JSON_END_LAST_ELEM "}" ++#define PRINT_JSON_END_LAST "}\n" ++#define PRINT_JSON_END_ARRAY "]\n" ++#define PRINT_JSON_INDENT " " ++#define PRINT_JSON_MAP "{\n" \ ++ " \"name\" : \"%n\",\n" \ ++ " \"uuid\" : \"%w\",\n" \ ++ " \"sysfs\" : \"%d\",\n" \ ++ " \"failback\" : \"%F\",\n" \ ++ " \"queueing\" : \"%Q\",\n" \ ++ " \"paths\" : %N,\n" \ ++ " \"write_prot\" : \"%r\",\n" \ ++ " \"dm_st\" : \"%t\",\n" \ ++ " \"features\" : \"%f\",\n" \ ++ " \"hwhandler\" : \"%h\",\n" \ ++ " \"action\" : \"%A\",\n" \ ++ " \"path_faults\" : %0,\n" \ ++ " \"vend\" : \"%v\",\n" \ ++ " \"prod\" : \"%p\",\n" \ ++ " \"rev\" : \"%e\",\n" \ ++ " \"switch_grp\" : %1,\n" \ ++ " \"map_loads\" : %2,\n" \ ++ " \"total_q_time\" : %3,\n" \ ++ " \"q_timeouts\" : %4," ++ ++#define PRINT_JSON_GROUP "{\n" \ ++ " \"selector\" : \"%s\",\n" \ ++ " \"pri\" : %p,\n" \ ++ " \"dm_st\" : \"%t\"," ++ ++#define PRINT_JSON_GROUP_NUM " \"group\" : %d,\n" ++ ++#define PRINT_JSON_PATH "{\n" \ ++ " \"dev\" : \"%d\",\n"\ ++ " \"dev_t\" : \"%D\",\n" \ ++ " \"dm_st\" : \"%t\",\n" \ ++ " \"dev_st\" : \"%o\",\n" \ ++ " \"chk_st\" : \"%T\",\n" \ ++ " \"checker\" : \"%c\",\n" \ ++ " \"pri\" : %p,\n" \ ++ " \"host_wwnn\" : \"%N\",\n" \ ++ " \"target_wwnn\" : \"%n\",\n" \ ++ " \"host_wwpn\" : \"%R\",\n" \ ++ " \"target_wwpn\" : \"%r\",\n" \ ++ " \"host_adapter\" : \"%a\"" ++ + #define MAX_LINE_LEN 80 + #define MAX_LINES 64 + #define MAX_FIELD_LEN 64 +@@ -41,6 +98,10 @@ int snprint_path (char *, int, char *, s + int snprint_multipath (char *, int, char *, struct multipath *, int); + int snprint_multipath_topology (char *, int, struct multipath * mpp, + int verbosity); ++int snprint_multipath_topology_json (char * buff, int len, ++ struct vectors * vecs); ++int snprint_multipath_map_json (char * buff, int len, ++ struct multipath * mpp, int last); + int snprint_defaults (char *, int); + int snprint_blacklist (char *, int); + int snprint_blacklist_except (char *, int); +Index: multipath-tools-130222/multipathd/cli.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/cli.c ++++ multipath-tools-130222/multipathd/cli.c +@@ -189,6 +189,7 @@ load_keys (void) + r += add_key(keys, "setprstatus", SETPRSTATUS, 0); + r += add_key(keys, "unsetprstatus", UNSETPRSTATUS, 0); + r += add_key(keys, "format", FMT, 1); ++ r += add_key(keys, "json", JSON, 0); + + if (r) { + free_keys(keys); +@@ -473,8 +474,10 @@ cli_init (void) { + add_handler(LIST+MAPS+FMT, NULL); + add_handler(LIST+MAPS+RAW+FMT, NULL); + add_handler(LIST+MAPS+TOPOLOGY, NULL); ++ add_handler(LIST+MAPS+JSON, NULL); + add_handler(LIST+TOPOLOGY, NULL); + add_handler(LIST+MAP+TOPOLOGY, NULL); ++ add_handler(LIST+MAP+JSON, NULL); + add_handler(LIST+CONFIG, NULL); + add_handler(LIST+BLACKLIST, NULL); + add_handler(LIST+DEVICES, NULL); +Index: multipath-tools-130222/multipathd/cli.h +=================================================================== +--- multipath-tools-130222.orig/multipathd/cli.h ++++ multipath-tools-130222/multipathd/cli.h +@@ -36,6 +36,7 @@ enum { + __SETPRSTATUS, + __UNSETPRSTATUS, + __FMT, ++ __JSON, + }; + + #define LIST (1 << __LIST) +@@ -74,6 +75,7 @@ enum { + #define SETPRSTATUS (1ULL << __SETPRSTATUS) + #define UNSETPRSTATUS (1ULL << __UNSETPRSTATUS) + #define FMT (1ULL << __FMT) ++#define JSON (1ULL << __JSON) + + #define INITIAL_REPLY_LEN 1200 + +Index: multipath-tools-130222/multipathd/cli_handlers.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/cli_handlers.c ++++ multipath-tools-130222/multipathd/cli_handlers.c +@@ -127,6 +127,70 @@ show_maps_topology (char ** r, int * len + } + + int ++show_maps_json (char ** r, int * len, struct vectors * vecs) ++{ ++ int i; ++ struct multipath * mpp; ++ char * c; ++ char * reply; ++ unsigned int maxlen = INITIAL_REPLY_LEN * ++ PRINT_JSON_MULTIPLIER * VECTOR_SIZE(vecs->mpvec); ++ int again = 1; ++ ++ vector_foreach_slot(vecs->mpvec, mpp, i) { ++ if (update_multipath(vecs, mpp->alias, 0)) { ++ return 1; ++ } ++ } ++ ++ reply = MALLOC(maxlen); ++ ++ while (again) { ++ if (!reply) ++ return 1; ++ ++ c = reply; ++ ++ c += snprint_multipath_topology_json(c, maxlen, vecs); ++ again = ((c - reply) == maxlen); ++ ++ REALLOC_REPLY(reply, again, maxlen); ++ } ++ *r = reply; ++ *len = (int)(c - reply); ++ return 0; ++} ++ ++int ++show_map_json (char ** r, int * len, struct multipath * mpp, ++ struct vectors * vecs) ++{ ++ char * c; ++ char * reply; ++ unsigned int maxlen = INITIAL_REPLY_LEN; ++ int again = 1; ++ ++ if (update_multipath(vecs, mpp->alias, 0)) ++ return 1; ++ reply = MALLOC(maxlen); ++ ++ while (again) { ++ if (!reply) ++ return 1; ++ ++ c = reply; ++ ++ c += snprint_multipath_map_json(c, maxlen, mpp, 1); ++ again = ((c - reply) == maxlen); ++ ++ REALLOC_REPLY(reply, again, maxlen); ++ } ++ *r = reply; ++ *len = (int)(c - reply); ++ return 0; ++} ++ ++int + show_config (char ** r, int * len) + { + char * c; +@@ -239,6 +303,35 @@ cli_list_maps_topology (void * v, char * + } + + int ++cli_list_map_json (void * v, char ** reply, int * len, void * data) ++{ ++ struct multipath * mpp; ++ struct vectors * vecs = (struct vectors *)data; ++ char * param = get_keyparam(v, MAP); ++ ++ param = convert_dev(param, 0); ++ get_path_layout(vecs->pathvec, 0); ++ mpp = find_mp_by_str(vecs->mpvec, param); ++ ++ if (!mpp) ++ return 1; ++ ++ condlog(3, "list multipath json %s (operator)", param); ++ ++ return show_map_json(reply, len, mpp, vecs); ++} ++ ++int ++cli_list_maps_json (void * v, char ** reply, int * len, void * data) ++{ ++ struct vectors * vecs = (struct vectors *)data; ++ ++ condlog(3, "list multipaths json (operator)"); ++ ++ return show_maps_json(reply, len, vecs); ++} ++ ++int + cli_list_wildcards (void * v, char ** reply, int * len, void * data) + { + char * c; +Index: multipath-tools-130222/multipathd/cli_handlers.h +=================================================================== +--- multipath-tools-130222.orig/multipathd/cli_handlers.h ++++ multipath-tools-130222/multipathd/cli_handlers.h +@@ -10,6 +10,8 @@ int cli_list_maps_status (void * v, char + int cli_list_maps_stats (void * v, char ** reply, int * len, void * data); + int cli_list_map_topology (void * v, char ** reply, int * len, void * data); + int cli_list_maps_topology (void * v, char ** reply, int * len, void * data); ++int cli_list_map_json (void * v, char ** reply, int * len, void * data); ++int cli_list_maps_json (void * v, char ** reply, int * len, void * data); + int cli_list_config (void * v, char ** reply, int * len, void * data); + int cli_list_blacklist (void * v, char ** reply, int * len, void * data); + int cli_list_devices (void * v, char ** reply, int * len, void * data); +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -981,7 +981,9 @@ uxlsnrloop (void * ap) + set_handler_callback(LIST+MAPS+RAW+FMT, cli_list_maps_raw); + set_handler_callback(LIST+MAPS+TOPOLOGY, cli_list_maps_topology); + set_handler_callback(LIST+TOPOLOGY, cli_list_maps_topology); ++ set_handler_callback(LIST+MAPS+JSON, cli_list_maps_json); + set_handler_callback(LIST+MAP+TOPOLOGY, cli_list_map_topology); ++ set_handler_callback(LIST+MAP+JSON, cli_list_map_json); + set_handler_callback(LIST+CONFIG, cli_list_config); + set_handler_callback(LIST+BLACKLIST, cli_list_blacklist); + set_handler_callback(LIST+DEVICES, cli_list_devices); +Index: multipath-tools-130222/multipathd/multipathd.8 +=================================================================== +--- multipath-tools-130222.orig/multipathd/multipathd.8 ++++ multipath-tools-130222/multipathd/multipathd.8 +@@ -53,11 +53,15 @@ using a format string with multipath for + Show the status of all multipath devices that the multipathd is monitoring. + .TP + .B list|show maps|multipaths stats +-Show some statistics of all multipath devices that the multipathd is monitoring. ++Show some statistics of all multipath devices that multipathd is monitoring. + .TP + .B list|show maps|multipaths topology + Show the current multipath topology. Same as "multipath \-ll". + .TP ++.B list|show maps|multipaths json ++Show the multipath devices that multipathd is monitoring, using JSON ++formatted output. ++.TP + .B list|show topology + Show the current multipath topology. Same as "multipath \-ll". + .TP +@@ -65,6 +69,9 @@ Show the current multipath topology. Sam + Show topology of a single multipath device specified by $map, e.g. 36005076303ffc56200000000000010aa. + This map could be obtained from "list maps". + .TP ++.B list|show map|multipath $map json ++Show a single multipath device specified by $map, using JSON formatted output. ++.TP + .B list|show wildcards + Show the format wildcards used in interactive commands taking $format + .TP diff --git a/0170-UPBZ-1352925-fix-typo.patch b/0170-UPBZ-1352925-fix-typo.patch new file mode 100644 index 0000000..2521c3d --- /dev/null +++ b/0170-UPBZ-1352925-fix-typo.patch @@ -0,0 +1,26 @@ +--- + multipath/main.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: multipath-tools-130222/multipath/main.c +=================================================================== +--- multipath-tools-130222.orig/multipath/main.c ++++ multipath-tools-130222/multipath/main.c +@@ -286,7 +286,7 @@ configure (void) + if (failed == 2 && conf->cmd == CMD_VALID_PATH) + printf("%s is not a valid multipath device path\n", conf->dev); + else +- condlog(3, "scope is nul"); ++ condlog(3, "scope is null"); + goto out; + } + if (conf->cmd == CMD_REMOVE_WWID) { +@@ -358,7 +358,7 @@ configure (void) + + + if (conf->cmd == CMD_VALID_PATH) { +- /* This only happens if find_multipaths is and ++ /* This only happens if find_multipaths and + * ignore_wwids is set. + * If there is currently a multipath device matching + * the refwwid, or there is more than one path matching diff --git a/0171-UPBZ-1356651-allow-zero-size.patch b/0171-UPBZ-1356651-allow-zero-size.patch new file mode 100644 index 0000000..0fe05b5 --- /dev/null +++ b/0171-UPBZ-1356651-allow-zero-size.patch @@ -0,0 +1,79 @@ +--- + libmultipath/discovery.c | 5 +++++ + libmultipath/structs_vec.c | 2 +- + multipathd/main.c | 26 +++++--------------------- + 3 files changed, 11 insertions(+), 22 deletions(-) + +Index: multipath-tools-130222/libmultipath/discovery.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/discovery.c ++++ multipath-tools-130222/libmultipath/discovery.c +@@ -1188,6 +1188,11 @@ pathinfo (struct path *pp, vector hwtabl + if (pp->state == PATH_UNCHECKED || + pp->state == PATH_WILD) + goto blank; ++ if (pp->state == PATH_UP && !pp->size) { ++ condlog(3, "%s: device size is 0, " ++ "path unuseable", pp->dev); ++ pp->state = PATH_GHOST; ++ } + } else { + condlog(3, "%s: path inaccessible", pp->dev); + pp->chkrstate = pp->state = path_state; +Index: multipath-tools-130222/libmultipath/structs_vec.c +=================================================================== +--- multipath-tools-130222.orig/libmultipath/structs_vec.c ++++ multipath-tools-130222/libmultipath/structs_vec.c +@@ -551,7 +551,7 @@ int update_multipath (struct vectors *ve + + if (pp->state != PATH_DOWN) { + int oldstate = pp->state; +- condlog(2, "%s: mark as failed", pp->dev_t); ++ condlog(2, "%s: mark as failed", pp->dev); + mpp->stat_path_failures++; + pp->state = PATH_DOWN; + if (oldstate == PATH_UP || +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -538,15 +538,10 @@ ev_add_path (struct path * pp, struct ve + pp->mpp = mpp; + rescan: + if (mpp) { +- if ((!pp->size) || (mpp->size != pp->size)) { +- if (!pp->size) +- condlog(0, "%s: failed to add new path %s, " +- "device size is 0", +- mpp->alias, pp->dev); +- else +- condlog(0, "%s: failed to add new path %s, " +- "device size mismatch", +- mpp->alias, pp->dev); ++ if (pp->size && mpp->size != pp->size) { ++ condlog(0, "%s: failed to add new path %s, " ++ "device size mismatch", ++ mpp->alias, pp->dev); + int i = find_slot(vecs->pathvec, (void *)pp); + if (i != -1) + vector_del_slot(vecs->pathvec, i); +@@ -563,18 +558,7 @@ rescan: + verify_paths(mpp, vecs, NULL); + mpp->flush_on_last_del = FLUSH_UNDEF; + mpp->action = ACT_RELOAD; +- } +- else { +- if (!pp->size) { +- condlog(0, "%s: failed to create new map," +- " device size is 0 ", pp->dev); +- int i = find_slot(vecs->pathvec, (void *)pp); +- if (i != -1) +- vector_del_slot(vecs->pathvec, i); +- free_path(pp); +- return 1; +- } +- ++ } else { + if (!should_multipath(pp, vecs->pathvec)) { + orphan_path(pp); + return 0; diff --git a/0172-RHBZ-1350931-no-active-add.patch b/0172-RHBZ-1350931-no-active-add.patch new file mode 100644 index 0000000..4e79e32 --- /dev/null +++ b/0172-RHBZ-1350931-no-active-add.patch @@ -0,0 +1,37 @@ +--- + multipathd/main.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +Index: multipath-tools-130222/multipathd/main.c +=================================================================== +--- multipath-tools-130222.orig/multipathd/main.c ++++ multipath-tools-130222/multipathd/main.c +@@ -530,9 +530,15 @@ ev_add_path (struct path * pp, struct ve + } + mpp = find_mp_by_wwid(vecs->mpvec, pp->wwid); + if (mpp && mpp->wait_for_udev) { +- mpp->wait_for_udev = 2; +- orphan_path(pp); +- return 0; ++ if (pathcount(mpp, PATH_UP) == 0 && ++ (pathcount(mpp, PATH_GHOST) == 0 || ++ pp->tpgs == TPGS_IMPLICIT)) ++ mpp->force_udev_reload = 1; ++ else { ++ mpp->wait_for_udev = 2; ++ orphan_path(pp); ++ return 0; ++ } + } + + pp->mpp = mpp; +@@ -551,7 +557,8 @@ rescan: + + condlog(4,"%s: adopting all paths for path %s", + mpp->alias, pp->dev); +- mpp->force_udev_reload = !pathcount(mpp, PATH_WILD); ++ if (pathcount(mpp, PATH_WILD) == 0) ++ mpp->force_udev_reload = 1; + if (adopt_paths(vecs->pathvec, mpp, 1)) + goto fail; /* leave path added to pathvec */ + diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index b1a066c..6a4b517 100644 --- a/device-mapper-multipath.spec +++ b/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: 82%{?dist} +Release: 83%{?dist} License: GPL+ Group: System Environment/Base URL: http://christophe.varoqui.free.fr/ @@ -167,6 +167,19 @@ Patch0156: 0156-UPBZ-1313324-dont-fail-discovery.patch Patch0157: 0157-RHBZ-1319853-multipath-c-error-msg.patch Patch0158: 0158-RHBZ-1318581-timestamp-doc-fix.patch Patch0159: 0159-UPBZ-1255885-udev-waits.patch +Patch0160: 0160-RH-udev-flags.patch +Patch0161: 0161-RHBZ-1311659-no-kpartx.patch +Patch0162: 0162-RHBZ-1333331-huawei-config.patch +Patch0163: 0163-UPBZ-1333492-resize-map.patch +Patch0164: 0164-RHBZ-1311463-dos-part-rollover.patch +Patch0165: 0165-UPBZ-1341748-MSA-2040-conf.patch +Patch0166: 0166-RHBZ-1323429-dont-allow-new-wwid.patch +Patch0167: 0167-RHBZ-1335176-fix-show-cmds.patch +Patch0168: 0168-RHBZ-1347769-shared-lock.patch +Patch0169: 0169-UPBZ-1353357-json-output.patch +Patch0170: 0170-UPBZ-1352925-fix-typo.patch +Patch0171: 0171-UPBZ-1356651-allow-zero-size.patch +Patch0172: 0172-RHBZ-1350931-no-active-add.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -379,6 +392,19 @@ kpartx manages partition creation and removal for device-mapper devices. %patch0157 -p1 %patch0158 -p1 %patch0159 -p1 +%patch0160 -p1 +%patch0161 -p1 +%patch0162 -p1 +%patch0163 -p1 +%patch0164 -p1 +%patch0165 -p1 +%patch0166 -p1 +%patch0167 -p1 +%patch0168 -p1 +%patch0169 -p1 +%patch0170 -p1 +%patch0171 -p1 +%patch0172 -p1 cp %{SOURCE1} . %build @@ -480,6 +506,42 @@ fi %{_mandir}/man8/kpartx.8.gz %changelog +* Fri Jul 22 2016 Benjamin Marzinski 0.4.9-83 +- Modify 0135-RHBZ-1299600-path-dev-uevents.patch + * trigger uevents when adding wwids for existing devices during startup +- Refresh 0136-RHBZ-1304687-wait-for-map-add.patch +- Refresh 0150-RHBZ-1253913-fix-startup-msg.patch +- Modify 0159-UPBZ-1255885-udev-waits.patch + * fix bug in failure path +- Add 0160-RH-udev-flags.patch +- Add 0161-RHBZ-1311659-no-kpartx.patch + * skip_kpartx option disables kpartx running on multipath devices +- Add 0162-RHBZ-1333331-huawei-config.patch + * Add default config for Huawei XSG1 array +- Add 0163-UPBZ-1333492-resize-map.patch + * restore old size if resize fails +- Add 0164-RHBZ-1311463-dos-part-rollover.patch + * fix incorrect partition size due to 4k device size rollover +- Add 0165-UPBZ-1341748-MSA-2040-conf.patch + * Add default config for MSA 2040 array +- Add 0166-RHBZ-1323429-dont-allow-new-wwid.patch + * don't allow path wwid to change while it is in use +- Add 0167-RHBZ-1335176-fix-show-cmds.patch + * and new show multipath format wildcard, 'f' to sho number of failures. + This will hopefully be useful for tracking what happens to multipath + devices for bz #1335176 +- Add 0168-RHBZ-1347769-shared-lock.patch + * make multipath lock the path devices with a shared lock +- Add 0169-UPBZ-1353357-json-output.patch + * add mulitpathd json output command +- Add 0170-UPBZ-1352925-fix-typo.patch +- Add 0171-UPBZ-1356651-allow-zero-size.patch + * Allow zero-sized paths to be added to a multipath device +- Add 0172-RHBZ-1350931-no-active-add.patch + * Allow paths to be added to a new map if no active paths exist. Also + fixes 1351430 + + * Thu Apr 21 2016 Benjamin Marzinski 0.4.9-82 - Modify 0005-RH-add-mpathconf.patch * changed warning message