Blame SOURCES/0161-RHBZ-1311659-no-kpartx.patch

4728c8
---
4728c8
 libmultipath/config.c      |    3 +
4728c8
 libmultipath/config.h      |    3 +
4728c8
 libmultipath/configure.c   |   15 +++--
4728c8
 libmultipath/defaults.h    |    1 
4728c8
 libmultipath/devmapper.c   |   35 +++++++++----
4728c8
 libmultipath/devmapper.h   |    8 ++-
4728c8
 libmultipath/dict.c        |  114 +++++++++++++++++++++++++++++++++++++++++++++
4728c8
 libmultipath/propsel.c     |   26 ++++++++++
4728c8
 libmultipath/propsel.h     |    1 
4728c8
 libmultipath/structs.h     |    7 ++
4728c8
 multipath/multipath.conf.5 |   10 +++
4728c8
 multipath/multipath.rules  |    1 
4728c8
 multipathd/cli_handlers.c  |    4 +
4728c8
 13 files changed, 211 insertions(+), 17 deletions(-)
4728c8
4728c8
Index: multipath-tools-130222/libmultipath/config.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/config.c
4728c8
+++ multipath-tools-130222/libmultipath/config.c
4728c8
@@ -343,6 +343,7 @@ merge_hwe (struct hwentry * dst, struct
4728c8
 	merge_num(deferred_remove);
4728c8
 	merge_num(delay_watch_checks);
4728c8
 	merge_num(delay_wait_checks);
4728c8
+	merge_num(skip_kpartx);
4728c8
 
4728c8
 	/*
4728c8
 	 * Make sure features is consistent with
4728c8
@@ -403,6 +404,7 @@ overwrite_hwe (struct hwentry * dst, str
4728c8
 	overwrite_num(deferred_remove);
4728c8
 	overwrite_num(delay_watch_checks);
4728c8
 	overwrite_num(delay_wait_checks);
4728c8
+	overwrite_num(skip_kpartx);
4728c8
 
4728c8
 	/*
4728c8
 	 * Make sure features is consistent with
4728c8
@@ -677,6 +679,7 @@ load_config (char * file, struct udev *u
4728c8
 	conf->retrigger_delay = DEFAULT_RETRIGGER_DELAY;
4728c8
 	conf->new_bindings_in_boot = 0;
4728c8
 	conf->uev_wait_timeout = DEFAULT_UEV_WAIT_TIMEOUT;
4728c8
+	conf->skip_kpartx = DEFAULT_SKIP_KPARTX;
4728c8
 
4728c8
 	/*
4728c8
 	 * preload default hwtable
4728c8
Index: multipath-tools-130222/libmultipath/config.h
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/config.h
4728c8
+++ multipath-tools-130222/libmultipath/config.h
4728c8
@@ -64,6 +64,7 @@ struct hwentry {
4728c8
 	int deferred_remove;
4728c8
 	int delay_watch_checks;
4728c8
 	int delay_wait_checks;
4728c8
+	int skip_kpartx;
4728c8
 	char * bl_product;
4728c8
 };
4728c8
 
4728c8
@@ -90,6 +91,7 @@ struct mpentry {
4728c8
 	int deferred_remove;
4728c8
 	int delay_watch_checks;
4728c8
 	int delay_wait_checks;
4728c8
+	int skip_kpartx;
4728c8
 	uid_t uid;
4728c8
 	gid_t gid;
4728c8
 	mode_t mode;
4728c8
@@ -143,6 +145,7 @@ struct config {
4728c8
 	int new_bindings_in_boot;
4728c8
 	int delayed_reconfig;
4728c8
 	int uev_wait_timeout;
4728c8
+	int skip_kpartx;
4728c8
 	unsigned int version[3];
4728c8
 
4728c8
 	char * dev;
4728c8
Index: multipath-tools-130222/libmultipath/configure.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/configure.c
4728c8
+++ multipath-tools-130222/libmultipath/configure.c
4728c8
@@ -294,6 +294,7 @@ setup_map (struct multipath * mpp, char
4728c8
 	select_deferred_remove(mpp);
4728c8
 	select_delay_watch_checks(mpp);
4728c8
 	select_delay_wait_checks(mpp);
4728c8
+	select_skip_kpartx(mpp);
4728c8
 
4728c8
 	sysfs_set_scsi_tmo(mpp);
4728c8
 	/*
4728c8
@@ -446,6 +447,7 @@ select_action (struct multipath * mpp, v
4728c8
 	}
4728c8
 	mpp->force_udev_reload = !pathcount(mpp, PATH_WILD);
4728c8
 	if (cmpp->size != mpp->size) {
4728c8
+		mpp->force_udev_reload = 1;
4728c8
 		mpp->action = ACT_RESIZE;
4728c8
 		condlog(3, "%s: set ACT_RESIZE (size change)",
4728c8
 			mpp->alias);
4728c8
@@ -609,6 +611,7 @@ extern int
4728c8
 domap (struct multipath * mpp, char * params)
4728c8
 {
4728c8
 	int r = 0;
4728c8
+	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);
4728c8
 
4728c8
 	/*
4728c8
 	 * last chance to quit before touching the devmaps
4728c8
@@ -654,25 +657,27 @@ domap (struct multipath * mpp, char * pa
4728c8
 	case ACT_RELOAD:
4728c8
 		r = dm_addmap_reload(mpp, params);
4728c8
 		if (r)
4728c8
-			r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, (mpp->force_udev_reload)? 0 : MPATH_UDEV_RELOAD_FLAG);
4728c8
+			r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias,
4728c8
+						 udev_flags);
4728c8
 		break;
4728c8
 
4728c8
 	case ACT_RESIZE:
4728c8
 		r = dm_addmap_reload(mpp, params);
4728c8
 		if (r)
4728c8
-			r = dm_simplecmd_flush(DM_DEVICE_RESUME, mpp->alias, 1, 0);
4728c8
+			r = dm_simplecmd_flush(DM_DEVICE_RESUME, mpp->alias, 1,
4728c8
+					       udev_flags);
4728c8
 		break;
4728c8
 
4728c8
 	case ACT_RENAME:
4728c8
-		r = dm_rename(mpp->alias_old, mpp->alias);
4728c8
+		r = dm_rename(mpp->alias_old, mpp->alias, mpp->skip_kpartx);
4728c8
 		break;
4728c8
 
4728c8
 	case ACT_RENAME2:
4728c8
-		r = dm_rename(mpp->alias_old, mpp->alias);
4728c8
+		r = dm_rename(mpp->alias_old, mpp->alias, mpp->skip_kpartx);
4728c8
 		if (r) {
4728c8
 			r = dm_addmap_reload(mpp, params);
4728c8
 			if (r)
4728c8
-				r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, (mpp->force_udev_reload)? 0 : MPATH_UDEV_RELOAD_FLAG);
4728c8
+				r = dm_simplecmd_noflush(DM_DEVICE_RESUME, mpp->alias, udev_flags);
4728c8
 		}
4728c8
 		break;
4728c8
 
4728c8
Index: multipath-tools-130222/libmultipath/defaults.h
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/defaults.h
4728c8
+++ multipath-tools-130222/libmultipath/defaults.h
4728c8
@@ -24,6 +24,7 @@
4728c8
 #define DEFAULT_RETRIGGER_DELAY 10
4728c8
 #define DEFAULT_RETRIGGER_TRIES 3
4728c8
 #define DEFAULT_UEV_WAIT_TIMEOUT 30
4728c8
+#define DEFAULT_SKIP_KPARTX SKIP_KPARTX_OFF
4728c8
 
4728c8
 #define DEFAULT_CHECKINT	5
4728c8
 #define MAX_CHECKINT(a)		(a << 2)
4728c8
Index: multipath-tools-130222/libmultipath/devmapper.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/devmapper.c
4728c8
+++ multipath-tools-130222/libmultipath/devmapper.c
4728c8
@@ -262,13 +262,14 @@ dm_device_remove (const char *name, int
4728c8
 			    deferred_remove);
4728c8
 }
4728c8
 
4728c8
-extern int
4728c8
+static int
4728c8
 dm_addmap (int task, const char *target, struct multipath *mpp, char * params,
4728c8
-	   int use_uuid, int ro) {
4728c8
+	   int use_uuid, int ro, int skip_kpartx) {
4728c8
 	int r = 0;
4728c8
 	struct dm_task *dmt;
4728c8
 	char *prefixed_uuid = NULL;
4728c8
 	uint32_t cookie = 0;
4728c8
+	uint16_t udev_flags = ((conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0) | ((skip_kpartx == SKIP_KPARTX_ON)? MPATH_UDEV_NO_KPARTX_FLAG : 0);
4728c8
 
4728c8
 	if (!(dmt = dm_task_create (task)))
4728c8
 		return 0;
4728c8
@@ -309,7 +310,7 @@ dm_addmap (int task, const char *target,
4728c8
 	dm_task_no_open_count(dmt);
4728c8
 
4728c8
 	if (task == DM_DEVICE_CREATE &&
4728c8
-	    !dm_task_set_cookie(dmt, &cookie, (conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0))
4728c8
+	    !dm_task_set_cookie(dmt, &cookie, udev_flags))
4728c8
 		goto freeout;
4728c8
 	r = dm_task_run (dmt);
4728c8
 
4728c8
@@ -332,7 +333,8 @@ dm_addmap_create (struct multipath *mpp,
4728c8
 	for (ro = 0; ro <= 1; ro++) {
4728c8
 		int err;
4728c8
 
4728c8
-		if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH, mpp, params, 1, ro))
4728c8
+		if (dm_addmap(DM_DEVICE_CREATE, TGT_MPATH,
4728c8
+			      mpp, params, 1, ro, mpp->skip_kpartx))
4728c8
 			return 1;
4728c8
 		/*
4728c8
 		 * DM_DEVICE_CREATE is actually DM_DEV_CREATE + DM_TABLE_LOAD.
4728c8
@@ -354,11 +356,11 @@ dm_addmap_create (struct multipath *mpp,
4728c8
 
4728c8
 extern int
4728c8
 dm_addmap_reload (struct multipath *mpp, char *params) {
4728c8
-	if (dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RW))
4728c8
+	if (dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RW, SKIP_KPARTX_OFF))
4728c8
 		return 1;
4728c8
 	if (errno != EROFS)
4728c8
 		return 0;
4728c8
-	return dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RO);
4728c8
+	return dm_addmap(DM_DEVICE_RELOAD, TGT_MPATH, mpp, params, 0, ADDMAP_RO, SKIP_KPARTX_OFF);
4728c8
 }
4728c8
 
4728c8
 extern int
4728c8
@@ -720,6 +722,12 @@ out:
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+has_partmap(const char *name, void *data)
4728c8
+{
4728c8
+	return 1;
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 partmap_in_use(const char *name, void *data)
4728c8
 {
4728c8
 	int part_count, *ret_count = (int *)data;
4728c8
@@ -798,10 +806,16 @@ dm_suspend_and_flush_map (const char * m
4728c8
 	int s = 0, queue_if_no_path = 0;
4728c8
 	unsigned long long mapsize;
4728c8
 	char params[PARAMS_SIZE] = {0};
4728c8
+	int udev_flags = 0;
4728c8
 
4728c8
 	if (!dm_is_mpath(mapname))
4728c8
 		return 0; /* nothing to do */
4728c8
 
4728c8
+	/* if the device currently has no partitions, do not
4728c8
+	   run kpartx on it if you fail to delete it */
4728c8
+	if (do_foreach_partmaps(mapname, has_partmap, NULL) == 0)
4728c8
+		udev_flags |= MPATH_UDEV_NO_KPARTX_FLAG;
4728c8
+
4728c8
 	if (!dm_get_map(mapname, &mapsize, params)) {
4728c8
 		if (strstr(params, "queue_if_no_path"))
4728c8
 			queue_if_no_path = 1;
4728c8
@@ -820,7 +834,7 @@ dm_suspend_and_flush_map (const char * m
4728c8
 		return 0;
4728c8
 	}
4728c8
 	condlog(2, "failed to remove multipath map %s", mapname);
4728c8
-	dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname, 0);
4728c8
+	dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname, udev_flags);
4728c8
 	if (queue_if_no_path)
4728c8
 		s = dm_queue_if_no_path((char *)mapname, 1);
4728c8
 	return 1;
4728c8
@@ -1349,7 +1363,7 @@ rename_partmap (const char *name, void *
4728c8
 	for (offset = strlen(rd->old); name[offset] && !(isdigit(name[offset])); offset++); /* do nothing */
4728c8
 	snprintf(buff, PARAMS_SIZE, "%s%s%s", rd->new, rd->delim,
4728c8
 		 name + offset);
4728c8
-	dm_rename(name, buff);
4728c8
+	dm_rename(name, buff, SKIP_KPARTX_OFF);
4728c8
 	condlog(4, "partition map %s renamed", name);
4728c8
 	return 0;
4728c8
 }
4728c8
@@ -1369,11 +1383,12 @@ dm_rename_partmaps (const char * old, ch
4728c8
 }
4728c8
 
4728c8
 int
4728c8
-dm_rename (const char * old, char * new)
4728c8
+dm_rename (const char * old, char * new, int skip_kpartx)
4728c8
 {
4728c8
 	int r = 0;
4728c8
 	struct dm_task *dmt;
4728c8
 	uint32_t cookie;
4728c8
+	uint16_t udev_flags = ((conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0) | ((skip_kpartx == SKIP_KPARTX_ON)? MPATH_UDEV_NO_KPARTX_FLAG : 0);
4728c8
 
4728c8
 	if (dm_rename_partmaps(old, new))
4728c8
 		return r;
4728c8
@@ -1389,7 +1404,7 @@ dm_rename (const char * old, char * new)
4728c8
 
4728c8
 	dm_task_no_open_count(dmt);
4728c8
 
4728c8
-	if (!dm_task_set_cookie(dmt, &cookie, (conf->daemon)? DM_UDEV_DISABLE_LIBRARY_FALLBACK : 0))
4728c8
+	if (!dm_task_set_cookie(dmt, &cookie, udev_flags))
4728c8
 		goto out;
4728c8
 	r = dm_task_run(dmt);
4728c8
 
4728c8
Index: multipath-tools-130222/libmultipath/devmapper.h
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/devmapper.h
4728c8
+++ multipath-tools-130222/libmultipath/devmapper.h
4728c8
@@ -12,6 +12,12 @@
4728c8
 #define MPATH_UDEV_RELOAD_FLAG 0
4728c8
 #endif
4728c8
 
4728c8
+#ifdef DM_SUBSYSTEM_UDEV_FLAG1
4728c8
+#define MPATH_UDEV_NO_KPARTX_FLAG DM_SUBSYSTEM_UDEV_FLAG1
4728c8
+#else
4728c8
+#define MPATH_UDEV_NO_KPARTX_FLAG 0
4728c8
+#endif
4728c8
+
4728c8
 void dm_init(void);
4728c8
 int dm_prereq (void);
4728c8
 int dm_drv_version (unsigned int * version, char * str);
4728c8
@@ -47,7 +53,7 @@ int dm_remove_partmaps (const char * map
4728c8
 			int deferred_remove);
4728c8
 int dm_get_uuid(char *name, char *uuid);
4728c8
 int dm_get_info (char * mapname, struct dm_info ** dmi);
4728c8
-int dm_rename (const char * old, char * new);
4728c8
+int dm_rename (const char * old, char * new, int skip_kpartx);
4728c8
 int dm_reassign(const char * mapname);
4728c8
 int dm_reassign_table(const char *name, char *old, char *new);
4728c8
 int dm_setgeometry(struct multipath *mpp);
4728c8
Index: multipath-tools-130222/libmultipath/dict.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/dict.c
4728c8
+++ multipath-tools-130222/libmultipath/dict.c
4728c8
@@ -779,6 +779,29 @@ def_deferred_remove_handler(vector strve
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+def_skip_kpartx_handler(vector strvec)
4728c8
+{
4728c8
+	char * buff;
4728c8
+
4728c8
+	buff = set_value(strvec);
4728c8
+
4728c8
+	if (!buff)
4728c8
+		return 1;
4728c8
+
4728c8
+	if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
4728c8
+	    (strlen(buff) == 1 && !strcmp(buff, "0")))
4728c8
+		conf->skip_kpartx = SKIP_KPARTX_OFF;
4728c8
+	else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
4728c8
+		 (strlen(buff) == 1 && !strcmp(buff, "1")))
4728c8
+		conf->skip_kpartx = SKIP_KPARTX_ON;
4728c8
+	else
4728c8
+		conf->skip_kpartx = DEFAULT_SKIP_KPARTX;
4728c8
+
4728c8
+	FREE(buff);
4728c8
+	return 0;
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 def_ignore_new_boot_devs_handler(vector strvec)
4728c8
 {
4728c8
 	char * buff;
4728c8
@@ -1629,6 +1652,33 @@ hw_deferred_remove_handler(vector strvec
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+hw_skip_kpartx_handler(vector strvec)
4728c8
+{
4728c8
+	struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
4728c8
+	char * buff;
4728c8
+
4728c8
+	if (!hwe)
4728c8
+		return 1;
4728c8
+
4728c8
+	buff = set_value(strvec);
4728c8
+
4728c8
+	if (!buff)
4728c8
+		return 1;
4728c8
+
4728c8
+	if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
4728c8
+	    (strlen(buff) == 1 && !strcmp(buff, "0")))
4728c8
+		hwe->skip_kpartx = SKIP_KPARTX_OFF;
4728c8
+	else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
4728c8
+		 (strlen(buff) == 1 && !strcmp(buff, "1")))
4728c8
+		hwe->skip_kpartx = SKIP_KPARTX_ON;
4728c8
+	else
4728c8
+		hwe->skip_kpartx = SKIP_KPARTX_UNDEF;
4728c8
+
4728c8
+	FREE(buff);
4728c8
+	return 0;
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 hw_delay_watch_checks_handler(vector strvec)
4728c8
 {
4728c8
 	struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
4728c8
@@ -2154,6 +2204,32 @@ mp_deferred_remove_handler(vector strvec
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+mp_skip_kpartx_handler(vector strvec)
4728c8
+{
4728c8
+	struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
4728c8
+	char * buff;
4728c8
+
4728c8
+	if (!mpe)
4728c8
+		return 1;
4728c8
+
4728c8
+	buff = set_value(strvec);
4728c8
+	if (!buff)
4728c8
+		return 1;
4728c8
+
4728c8
+	if ((strlen(buff) == 2 && strcmp(buff, "no") == 0) ||
4728c8
+	    (strlen(buff) == 1 && strcmp(buff, "0") == 0))
4728c8
+		mpe->skip_kpartx = SKIP_KPARTX_OFF;
4728c8
+	else if ((strlen(buff) == 3 && strcmp(buff, "yes") == 0) ||
4728c8
+		 (strlen(buff) == 1 && strcmp(buff, "1") == 0))
4728c8
+		mpe->skip_kpartx = SKIP_KPARTX_ON;
4728c8
+	else
4728c8
+		mpe->skip_kpartx = SKIP_KPARTX_UNDEF;
4728c8
+
4728c8
+	FREE(buff);
4728c8
+	return 0;
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 mp_delay_watch_checks_handler(vector strvec)
4728c8
 {
4728c8
 	struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
4728c8
@@ -2461,6 +2537,19 @@ snprint_mp_deferred_remove (char * buff,
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+snprint_mp_skip_kpartx (char * buff, int len, void * data)
4728c8
+{
4728c8
+	struct mpentry * mpe = (struct mpentry *)data;
4728c8
+
4728c8
+	if (mpe->skip_kpartx == SKIP_KPARTX_UNDEF)
4728c8
+		return 0;
4728c8
+	else if (mpe->skip_kpartx == SKIP_KPARTX_OFF)
4728c8
+		return snprintf(buff, len, "no");
4728c8
+	else
4728c8
+		return snprintf(buff, len, "yes");
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 snprint_mp_delay_watch_checks(char * buff, int len, void * data)
4728c8
 {
4728c8
 	struct mpentry * mpe = (struct mpentry *)data;
4728c8
@@ -2813,6 +2902,19 @@ snprint_hw_deferred_remove(char * buff,
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+snprint_hw_skip_kpartx(char * buff, int len, void * data)
4728c8
+{
4728c8
+	struct hwentry * hwe = (struct hwentry *)data;
4728c8
+
4728c8
+	if (hwe->skip_kpartx == SKIP_KPARTX_ON)
4728c8
+		return snprintf(buff, len, "yes");
4728c8
+	else if (hwe->skip_kpartx == SKIP_KPARTX_OFF)
4728c8
+		return snprintf(buff, len, "no");
4728c8
+	else
4728c8
+		return 0;
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 snprint_hw_delay_watch_checks(char * buff, int len, void * data)
4728c8
 {
4728c8
 	struct hwentry * hwe = (struct hwentry *)data;
4728c8
@@ -3231,6 +3333,15 @@ snprint_def_deferred_remove(char * buff,
4728c8
 }
4728c8
 
4728c8
 static int
4728c8
+snprint_def_skip_kpartx(char * buff, int len, void * data)
4728c8
+{
4728c8
+	if (conf->skip_kpartx == SKIP_KPARTX_ON)
4728c8
+		return snprintf(buff, len, "yes");
4728c8
+	else
4728c8
+		return snprintf(buff, len, "no");
4728c8
+}
4728c8
+
4728c8
+static int
4728c8
 snprint_def_ignore_new_boot_devs(char * buff, int len, void * data)
4728c8
 {
4728c8
 	if (conf->ignore_new_boot_devs == 1)
4728c8
@@ -3364,6 +3475,7 @@ init_keywords(void)
4728c8
 	install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync);
4728c8
 	install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove);
4728c8
 	install_keyword("ignore_new_boot_devs", &def_ignore_new_boot_devs_handler, &snprint_def_ignore_new_boot_devs);
4728c8
+	install_keyword("skip_kpartx", &def_skip_kpartx_handler, &snprint_def_skip_kpartx);
4728c8
 	install_keyword("config_dir", &def_config_dir_handler, &snprint_def_config_dir);
4728c8
 	install_keyword("delay_watch_checks", &def_delay_watch_checks_handler, &snprint_def_delay_watch_checks);
4728c8
 	install_keyword("delay_wait_checks", &def_delay_wait_checks_handler, &snprint_def_delay_wait_checks);
4728c8
@@ -3438,6 +3550,7 @@ init_keywords(void)
4728c8
 	install_keyword("deferred_remove", &hw_deferred_remove_handler, &snprint_hw_deferred_remove);
4728c8
 	install_keyword("delay_watch_checks", &hw_delay_watch_checks_handler, &snprint_hw_delay_watch_checks);
4728c8
 	install_keyword("delay_wait_checks", &hw_delay_wait_checks_handler, &snprint_hw_delay_wait_checks);
4728c8
+	install_keyword("skip_kpartx", &hw_skip_kpartx_handler, &snprint_hw_skip_kpartx);
4728c8
 	install_sublevel_end();
4728c8
 
4728c8
 	install_keyword_root("multipaths", &multipaths_handler);
4728c8
@@ -3465,5 +3578,6 @@ init_keywords(void)
4728c8
 	install_keyword("deferred_remove", &mp_deferred_remove_handler, &snprint_mp_deferred_remove);
4728c8
 	install_keyword("delay_watch_checks", &mp_delay_watch_checks_handler, &snprint_mp_delay_watch_checks);
4728c8
 	install_keyword("delay_wait_checks", &mp_delay_wait_checks_handler, &snprint_mp_delay_wait_checks);
4728c8
+	install_keyword("skip_kpartx", &mp_skip_kpartx_handler, &snprint_mp_skip_kpartx);
4728c8
 	install_sublevel_end();
4728c8
 }
4728c8
Index: multipath-tools-130222/libmultipath/propsel.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/propsel.c
4728c8
+++ multipath-tools-130222/libmultipath/propsel.c
4728c8
@@ -854,3 +854,29 @@ select_delay_wait_checks (struct multipa
4728c8
 	condlog(3, "delay_wait_checks = DISABLED (internal default)");
4728c8
 	return 0;
4728c8
 }
4728c8
+
4728c8
+extern int
4728c8
+select_skip_kpartx (struct multipath * mp)
4728c8
+{
4728c8
+	if (mp->mpe && mp->mpe->skip_kpartx != SKIP_KPARTX_UNDEF) {
4728c8
+		mp->skip_kpartx = mp->mpe->skip_kpartx;
4728c8
+		condlog(3, "skip_kpartx = %i (multipath setting)",
4728c8
+				mp->skip_kpartx);
4728c8
+		return 0;
4728c8
+	}
4728c8
+	if (mp->hwe && mp->hwe->skip_kpartx != SKIP_KPARTX_UNDEF) {
4728c8
+		mp->skip_kpartx = mp->hwe->skip_kpartx;
4728c8
+		condlog(3, "skip_kpartx = %i (controler setting)",
4728c8
+				mp->skip_kpartx);
4728c8
+		return 0;
4728c8
+	}
4728c8
+	if (conf->skip_kpartx != SKIP_KPARTX_UNDEF) {
4728c8
+		mp->skip_kpartx = conf->skip_kpartx;
4728c8
+		condlog(3, "skip_kpartx = %i (config file default)",
4728c8
+				mp->skip_kpartx);
4728c8
+		return 0;
4728c8
+	}
4728c8
+	mp->skip_kpartx = DEFAULT_SKIP_KPARTX;
4728c8
+	condlog(3, "skip_kpartx = DISABLED (internal default)");
4728c8
+	return 0;
4728c8
+}
4728c8
Index: multipath-tools-130222/libmultipath/propsel.h
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/propsel.h
4728c8
+++ multipath-tools-130222/libmultipath/propsel.h
4728c8
@@ -23,3 +23,4 @@ int select_detect_prio(struct path * pp)
4728c8
 int select_deferred_remove(struct multipath *mp);
4728c8
 int select_delay_watch_checks (struct multipath * mp);
4728c8
 int select_delay_wait_checks (struct multipath * mp);
4728c8
+int select_skip_kpartx (struct multipath * mp);
4728c8
Index: multipath-tools-130222/libmultipath/structs.h
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/libmultipath/structs.h
4728c8
+++ multipath-tools-130222/libmultipath/structs.h
4728c8
@@ -121,6 +121,12 @@ enum deferred_remove_states {
4728c8
 	DEFERRED_REMOVE_IN_PROGRESS,
4728c8
 };
4728c8
 
4728c8
+enum skip_kpartx_states {
4728c8
+	SKIP_KPARTX_UNDEF,
4728c8
+	SKIP_KPARTX_OFF,
4728c8
+	SKIP_KPARTX_ON,
4728c8
+};
4728c8
+
4728c8
 enum scsi_protocol {
4728c8
 	SCSI_PROTOCOL_FCP = 0,	/* Fibre Channel */
4728c8
 	SCSI_PROTOCOL_SPI = 1,	/* parallel SCSI */
4728c8
@@ -236,6 +242,7 @@ struct multipath {
4728c8
 	int delay_watch_checks;
4728c8
 	int delay_wait_checks;
4728c8
 	int force_udev_reload;
4728c8
+	int skip_kpartx;
4728c8
 	unsigned int dev_loss;
4728c8
 	uid_t uid;
4728c8
 	gid_t gid;
4728c8
Index: multipath-tools-130222/multipath/multipath.rules
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/multipath/multipath.rules
4728c8
+++ multipath-tools-130222/multipath/multipath.rules
4728c8
@@ -44,6 +44,7 @@ KERNEL!="dm-*", GOTO="end_mpath"
4728c8
 ENV{DM_UUID}=="mpath-?*|part[0-9]*-mpath-?*", OPTIONS+="link_priority=10"
4728c8
 ACTION!="change", GOTO="end_mpath"
4728c8
 ENV{DM_UUID}!="mpath-?*", GOTO="end_mpath"
4728c8
+ENV{DM_SUBSYSTEM_UDEV_FLAG1}=="1", GOTO="end_mpath"
4728c8
 ENV{DM_ACTIVATION}=="1", ENV{DM_MULTIPATH_NEED_KPARTX}="1"
4728c8
 ENV{DM_SUSPENDED}=="1", GOTO="end_mpath"
4728c8
 ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath"
4728c8
Index: multipath-tools-130222/multipathd/cli_handlers.c
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/multipathd/cli_handlers.c
4728c8
+++ multipath-tools-130222/multipathd/cli_handlers.c
4728c8
@@ -825,19 +825,21 @@ cli_resume(void * v, char ** reply, int
4728c8
 	char * param = get_keyparam(v, MAP);
4728c8
 	int r;
4728c8
 	struct multipath * mpp;
4728c8
+	uint16_t udev_flags;
4728c8
 
4728c8
 	param = convert_dev(param, 0);
4728c8
 	mpp = find_mp_by_alias(vecs->mpvec, param);
4728c8
 	if (!mpp)
4728c8
 		return 1;
4728c8
 
4728c8
+	udev_flags = (mpp->skip_kpartx)? MPATH_UDEV_NO_KPARTX_FLAG : 0;
4728c8
 	if (mpp->wait_for_udev) {
4728c8
 		condlog(2, "%s: device not fully created, failing resume",
4728c8
 			mpp->alias);
4728c8
 		return 1;
4728c8
 	}
4728c8
 
4728c8
-	r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param, 0);
4728c8
+	r = dm_simplecmd_noflush(DM_DEVICE_RESUME, param, udev_flags);
4728c8
 
4728c8
 	condlog(2, "%s: resume (operator)", param);
4728c8
 
4728c8
Index: multipath-tools-130222/multipath/multipath.conf.5
4728c8
===================================================================
4728c8
--- multipath-tools-130222.orig/multipath/multipath.conf.5
4728c8
+++ multipath-tools-130222/multipath/multipath.conf.5
4728c8
@@ -505,6 +505,12 @@ automatically enabling device reloads. U
4728c8
 on a device until it receives a change uevent from the initial table load. The
4728c8
 default is
4728c8
 .I 30
4728c8
+.TP
4728c8
+.B skip_kpartx
4728c8
+If set to
4728c8
+.I yes
4728c8
+, kpartx will not automatically create partitions on the device. The default is
4728c8
+.I no
4728c8
 .
4728c8
 .SH "blacklist section"
4728c8
 The
4728c8
@@ -612,6 +618,8 @@ section:
4728c8
 .B delay_watch_checks
4728c8
 .TP
4728c8
 .B delay_wait_checks
4728c8
+.TP
4728c8
+.B skip_kpartx
4728c8
 .RE
4728c8
 .PD
4728c8
 .LP
4728c8
@@ -708,6 +716,8 @@ section:
4728c8
 .B delay_watch_checks
4728c8
 .TP
4728c8
 .B delay_wait_checks
4728c8
+.TP
4728c8
+.B skip_kpartx
4728c8
 .RE
4728c8
 .PD
4728c8
 .LP