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
This commit is contained in:
Benjamin Marzinski 2016-07-22 15:20:02 -05:00
parent 6738b34a0b
commit 906e1e1128
18 changed files with 1727 additions and 175 deletions

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);

View File

@ -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);

20
0160-RH-udev-flags.patch Normal file
View File

@ -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;

View File

@ -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

View File

@ -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
*/

View File

@ -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;

View File

@ -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)

View File

@ -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 */

View File

@ -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;

View File

@ -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);
}

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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 <bmarzins@redhat.com> 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 <bmarzins@redhat.com> 0.4.9-82
- Modify 0005-RH-add-mpathconf.patch
* changed warning message