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