Blame SOURCES/0191-RHBZ-1169168-disable-changed-paths.patch

d88bf6
---
45d01a
 libmultipath/config.c      |    1 +
45d01a
 libmultipath/config.h      |    1 +
45d01a
 libmultipath/dict.c        |   33 +++++++++++++++++++++++++++++++++
45d01a
 libmultipath/discovery.c   |   11 ++++++-----
45d01a
 libmultipath/discovery.h   |    1 +
45d01a
 libmultipath/structs.h     |    1 +
45d01a
 multipath/multipath.conf.5 |    6 ++++++
45d01a
 multipathd/main.c          |   26 ++++++++++++++++++++++++++
45d01a
 8 files changed, 75 insertions(+), 5 deletions(-)
d88bf6
d88bf6
Index: multipath-tools-130222/libmultipath/discovery.c
d88bf6
===================================================================
d88bf6
--- multipath-tools-130222.orig/libmultipath/discovery.c
d88bf6
+++ multipath-tools-130222/libmultipath/discovery.c
d88bf6
@@ -1155,8 +1155,8 @@ free_dev:
d88bf6
 	return ret;
d88bf6
 }
d88bf6
 
d88bf6
-static int
d88bf6
-get_uid (struct path * pp)
d88bf6
+int
d88bf6
+get_uid (struct path * pp, struct udev_device *udev)
d88bf6
 {
d88bf6
 	char *c;
d88bf6
 	const char *value;
d88bf6
@@ -1165,7 +1165,7 @@ get_uid (struct path * pp)
d88bf6
 	if (!pp->uid_attribute)
d88bf6
 		select_getuid(pp);
d88bf6
 
d88bf6
-	if (!pp->udev) {
d88bf6
+	if (!udev) {
d88bf6
 		condlog(1, "%s: no udev information", pp->dev);
d88bf6
 		return 1;
d88bf6
 	}
d88bf6
@@ -1180,7 +1180,7 @@ get_uid (struct path * pp)
d88bf6
 			pp->tick = conf->retrigger_delay;
d88bf6
 		}
d88bf6
 	} else {
d88bf6
-		value = udev_device_get_property_value(pp->udev,
d88bf6
+		value = udev_device_get_property_value(udev,
d88bf6
 						       pp->uid_attribute);
d88bf6
 		if ((!value || strlen(value) == 0) &&
d88bf6
 		     conf->cmd == CMD_VALID_PATH)
d88bf6
@@ -1194,6 +1194,7 @@ get_uid (struct path * pp)
d88bf6
 				len = strlen(value);
d88bf6
 			}
d88bf6
 			strncpy(pp->wwid, value, len);
d88bf6
+			condlog(4, "%s: got wwid of '%s'", pp->dev, pp->wwid);
d88bf6
 			pp->missing_udev_info = INFO_OK;
d88bf6
 			pp->tick = 0;
d88bf6
 		} else {
d88bf6
@@ -1282,7 +1283,7 @@ pathinfo (struct path *pp, vector hwtabl
d88bf6
 	}
d88bf6
 
d88bf6
 	if ((mask & DI_WWID) && !strlen(pp->wwid))
d88bf6
-		get_uid(pp);
d88bf6
+		get_uid(pp, pp->udev);
d88bf6
 	if (mask & DI_BLACKLIST && mask & DI_WWID) {
d88bf6
 		if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
d88bf6
 				pp->wwid) > 0) {
d88bf6
Index: multipath-tools-130222/libmultipath/discovery.h
d88bf6
===================================================================
d88bf6
--- multipath-tools-130222.orig/libmultipath/discovery.h
d88bf6
+++ multipath-tools-130222/libmultipath/discovery.h
d88bf6
@@ -44,6 +44,7 @@ int sysfs_set_scsi_tmo (struct multipath
d88bf6
 int sysfs_get_timeout(struct path *pp, unsigned int *timeout);
d88bf6
 int sysfs_get_host_pci_name(struct path *pp, char *pci_name);
d88bf6
 int sysfs_get_iscsi_ip_address(struct path *pp, char *ip_address);
d88bf6
+int get_uid (struct path * pp, struct udev_device *udev);
d88bf6
 
d88bf6
 /*
d88bf6
  * discovery bitmask
d88bf6
Index: multipath-tools-130222/libmultipath/structs.h
d88bf6
===================================================================
d88bf6
--- multipath-tools-130222.orig/libmultipath/structs.h
d88bf6
+++ multipath-tools-130222/libmultipath/structs.h
d88bf6
@@ -209,6 +209,7 @@ struct path {
d88bf6
 	int fd;
d88bf6
 	int missing_udev_info;
d88bf6
 	int retriggers;
d88bf6
+	int wwid_changed;
d88bf6
 
d88bf6
 	/* configlet pointers */
d88bf6
 	struct hwentry * hwe;
d88bf6
Index: multipath-tools-130222/multipathd/main.c
d88bf6
===================================================================
d88bf6
--- multipath-tools-130222.orig/multipathd/main.c
d88bf6
+++ multipath-tools-130222/multipathd/main.c
d88bf6
@@ -784,6 +784,26 @@ uev_update_path (struct uevent *uev, str
d88bf6
 	if (pp->missing_udev_info == INFO_REQUESTED)
d88bf6
 		return uev_add_path(uev, vecs);
d88bf6
 
d88bf6
+	if (conf->disable_changed_wwids &&
d88bf6
+	    (strlen(pp->wwid) || pp->wwid_changed)) {
d88bf6
+		char wwid[WWID_SIZE];
d88bf6
+
d88bf6
+		strcpy(wwid, pp->wwid);
d88bf6
+		get_uid(pp, uev->udev);
d88bf6
+		if (strcmp(wwid, pp->wwid) != 0) {
d88bf6
+			condlog(0, "%s: path wwid changed from '%s' to '%s'. disallowing", uev->kernel, wwid, pp->wwid);
d88bf6
+			strcpy(pp->wwid, wwid);
d88bf6
+			if (!pp->wwid_changed) {
d88bf6
+				pp->wwid_changed = 1;
d88bf6
+				pp->tick = 1;
d88bf6
+				dm_fail_path(pp->mpp->alias, pp->dev_t);
d88bf6
+			}
d88bf6
+		}
d88bf6
+		else {
d88bf6
+			pp->wwid_changed = 0;
d88bf6
+		}
d88bf6
+	}
d88bf6
+
d88bf6
 	/* reinit the prio values on change event, in case something is
d88bf6
 	 * different */
d88bf6
 	prio_init(&pp->prio);
d88bf6
@@ -1284,6 +1304,12 @@ check_path (struct vectors * vecs, struc
d88bf6
 	else
d88bf6
 		checker_clear_message(&pp->checker);
d88bf6
 
d88bf6
+	if (pp->wwid_changed) {
d88bf6
+		condlog(2, "%s: path wwid has changed. Refusing to use",
d88bf6
+			pp->dev);
d88bf6
+		newstate = PATH_DOWN;
d88bf6
+	}
d88bf6
+
d88bf6
 	if (newstate == PATH_WILD || newstate == PATH_UNCHECKED) {
d88bf6
 		condlog(2, "%s: unusable path", pp->dev);
d88bf6
 		pathinfo(pp, conf->hwtable, 0);
d88bf6
Index: multipath-tools-130222/libmultipath/config.c
d88bf6
===================================================================
d88bf6
--- multipath-tools-130222.orig/libmultipath/config.c
d88bf6
+++ multipath-tools-130222/libmultipath/config.c
d88bf6
@@ -681,6 +681,7 @@ load_config (char * file, struct udev *u
d88bf6
 	conf->uev_wait_timeout = DEFAULT_UEV_WAIT_TIMEOUT;
d88bf6
 	conf->skip_kpartx = DEFAULT_SKIP_KPARTX;
d88bf6
 	conf->remove_retries = 0;
d88bf6
+	conf->disable_changed_wwids = 0;
d88bf6
 
d88bf6
 	/*
d88bf6
 	 * preload default hwtable
d88bf6
Index: multipath-tools-130222/libmultipath/config.h
d88bf6
===================================================================
d88bf6
--- multipath-tools-130222.orig/libmultipath/config.h
d88bf6
+++ multipath-tools-130222/libmultipath/config.h
d88bf6
@@ -147,6 +147,7 @@ struct config {
d88bf6
 	int uev_wait_timeout;
d88bf6
 	int skip_kpartx;
d88bf6
 	int remove_retries;
d88bf6
+	int disable_changed_wwids;
d88bf6
 	unsigned int version[3];
d88bf6
 
d88bf6
 	char * dev;
d88bf6
Index: multipath-tools-130222/libmultipath/dict.c
d88bf6
===================================================================
d88bf6
--- multipath-tools-130222.orig/libmultipath/dict.c
d88bf6
+++ multipath-tools-130222/libmultipath/dict.c
d88bf6
@@ -953,6 +953,29 @@ def_remove_retries_handler(vector strvec
d88bf6
 	return 0;
d88bf6
 }
d88bf6
 
d88bf6
+static int
d88bf6
+def_disable_changed_wwids_handler(vector strvec)
d88bf6
+{
d88bf6
+	char * buff;
d88bf6
+
d88bf6
+	buff = set_value(strvec);
d88bf6
+
d88bf6
+	if (!buff)
d88bf6
+		return 1;
d88bf6
+
d88bf6
+	if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
d88bf6
+	    (strlen(buff) == 1 && !strcmp(buff, "0")))
d88bf6
+		conf->disable_changed_wwids = 0;
d88bf6
+	else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
d88bf6
+		 (strlen(buff) == 1 && !strcmp(buff, "1")))
d88bf6
+		conf->disable_changed_wwids = 1;
d88bf6
+	else
d88bf6
+		conf->disable_changed_wwids = 0;
d88bf6
+
d88bf6
+	FREE(buff);
d88bf6
+	return 0;
d88bf6
+}
d88bf6
+
d88bf6
 /*
d88bf6
  * blacklist block handlers
d88bf6
  */
d88bf6
@@ -3429,6 +3452,15 @@ snprint_def_remove_retries (char * buff,
d88bf6
 }
d88bf6
 
d88bf6
 static int
d88bf6
+snprint_def_disable_changed_wwids(char * buff, int len, void * data)
d88bf6
+{
d88bf6
+	if (conf->disable_changed_wwids == 1)
d88bf6
+		return snprintf(buff, len, "yes");
d88bf6
+	else
d88bf6
+		return snprintf(buff, len, "no");
d88bf6
+}
d88bf6
+
d88bf6
+static int
d88bf6
 snprint_ble_simple (char * buff, int len, void * data)
d88bf6
 {
d88bf6
 	struct blentry * ble = (struct blentry *)data;
d88bf6
@@ -3508,6 +3540,7 @@ init_keywords(void)
d88bf6
 	install_keyword("missing_uev_wait_timeout", &def_uev_wait_timeout_handler, &snprint_def_uev_wait_timeout);
d88bf6
 	install_keyword("new_bindings_in_boot", &def_new_bindings_in_boot_handler, &snprint_def_new_bindings_in_boot);
d88bf6
 	install_keyword("remove_retries", &def_remove_retries_handler, &snprint_def_remove_retries);
d88bf6
+	install_keyword("disable_changed_wwids", &def_disable_changed_wwids_handler, &snprint_def_disable_changed_wwids);
d88bf6
 	__deprecated install_keyword("default_selector", &def_selector_handler, NULL);
d88bf6
 	__deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
d88bf6
 	__deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
45d01a
Index: multipath-tools-130222/multipath/multipath.conf.5
45d01a
===================================================================
45d01a
--- multipath-tools-130222.orig/multipath/multipath.conf.5
45d01a
+++ multipath-tools-130222/multipath/multipath.conf.5
45d01a
@@ -557,6 +557,12 @@ regular filesystem, the device will be r
45d01a
 default is
45d01a
 .I no
45d01a
 .TP
45d01a
+.B disable_changed_wwids
45d01a
+If set to \fIyes\fR, multipathd will check the path wwid on change events, and
45d01a
+if it has changed from the wwid of the multipath device, multipathd will
45d01a
+disable access to the path until the wwid changes back. The default is
45d01a
+.I no
45d01a
+.TP
45d01a
 .B remove_retries
45d01a
 This sets how may times multipath will retry removing a device that is in-use.
45d01a
 Between each attempt, multipath will sleep 1 second. The default is