Blame SOURCES/0232-RHBZ-1456955-property-blacklist.patch

45d01a
---
45d01a
 libmultipath/blacklist.c   |   79 +++++++++++++++++++++++++++++++++++++++++----
45d01a
 libmultipath/blacklist.h   |    5 ++
45d01a
 libmultipath/config.c      |   20 ++++++++++-
45d01a
 libmultipath/config.h      |    2 +
45d01a
 libmultipath/configure.c   |    8 ++++
45d01a
 libmultipath/dict.c        |   38 ++++++++++++++++++++-
45d01a
 libmultipath/discovery.c   |    2 +
45d01a
 libmultipath/print.c       |   31 +++++++++++++++++
45d01a
 multipath/multipath.conf.5 |   27 ++++++++++++++-
45d01a
 9 files changed, 200 insertions(+), 12 deletions(-)
45d01a
45d01a
Index: multipath-tools-130222/libmultipath/blacklist.c
45d01a
===================================================================
45d01a
--- multipath-tools-130222.orig/libmultipath/blacklist.c
45d01a
+++ multipath-tools-130222/libmultipath/blacklist.c
45d01a
@@ -2,6 +2,7 @@
45d01a
  * Copyright (c) 2004, 2005 Christophe Varoqui
45d01a
  */
45d01a
 #include <stdio.h>
45d01a
+#include <libudev.h>
45d01a
 
45d01a
 #include "checkers.h"
45d01a
 #include "memory.h"
45d01a
@@ -102,7 +103,7 @@ set_ble_device (vector blist, char * ven
45d01a
 }
45d01a
 
45d01a
 int
45d01a
-_blacklist_exceptions (vector elist, char * str)
45d01a
+_blacklist_exceptions (vector elist, const char * str)
45d01a
 {
45d01a
 	int i;
45d01a
 	struct blentry * ele;
45d01a
@@ -115,7 +116,7 @@ _blacklist_exceptions (vector elist, cha
45d01a
 }
45d01a
 
45d01a
 int
45d01a
-_blacklist (vector blist, char * str)
45d01a
+_blacklist (vector blist, const char * str)
45d01a
 {
45d01a
 	int i;
45d01a
 	struct blentry * ble;
45d01a
@@ -208,11 +209,14 @@ setup_default_blist (struct config * con
45d01a
 		condlog(3, "%s: (%s:%s) %s", dev, vendor, product, (M)); \
45d01a
 	else if (wwid)							 \
45d01a
 		condlog(3, "%s: (%s) %s", dev, wwid, (M));		 \
45d01a
+	else if (env)							 \
45d01a
+		condlog(3, "%s: (%s) %s", dev, env, (M));		 \
45d01a
 	else								 \
45d01a
 		condlog(3, "%s: %s", dev, (M))
45d01a
 
45d01a
 void
45d01a
-log_filter (char *dev, char *vendor, char *product, char *wwid, int r)
45d01a
+log_filter (const char *dev, char *vendor, char *product, char *wwid,
45d01a
+	    const char *env, int r)
45d01a
 {
45d01a
 	/*
45d01a
 	 * Try to sort from most likely to least.
45d01a
@@ -229,6 +233,9 @@ log_filter (char *dev, char *vendor, cha
45d01a
 	case MATCH_DEVNODE_BLIST:
45d01a
 		LOG_BLIST("device node name blacklisted");
45d01a
 		break;
45d01a
+	case MATCH_PROPERTY_BLIST:
45d01a
+		LOG_BLIST("udev property blacklisted");
45d01a
+		break;
45d01a
 	case MATCH_DEVICE_BLIST_EXCEPT:
45d01a
 		LOG_BLIST("vendor/product whitelisted");
45d01a
 		break;
45d01a
@@ -238,6 +245,12 @@ log_filter (char *dev, char *vendor, cha
45d01a
 	case MATCH_DEVNODE_BLIST_EXCEPT:
45d01a
 		LOG_BLIST("device node name whitelisted");
45d01a
 		break;
45d01a
+	case MATCH_PROPERTY_BLIST_EXCEPT:
45d01a
+		LOG_BLIST("udev property whitelisted");
45d01a
+		break;
45d01a
+	case MATCH_PROPERTY_BLIST_MISSING:
45d01a
+		LOG_BLIST("blacklisted, udev property missing");
45d01a
+		break;
45d01a
 	}
45d01a
 }
45d01a
 
45d01a
@@ -257,7 +270,7 @@ int
45d01a
 filter_device (vector blist, vector elist, char * vendor, char * product)
45d01a
 {
45d01a
 	int r = _filter_device(blist, elist, vendor, product);
45d01a
-	log_filter(NULL, vendor, product, NULL, r);
45d01a
+	log_filter(NULL, vendor, product, NULL, NULL, r);
45d01a
 	return r;
45d01a
 }
45d01a
 
45d01a
@@ -277,7 +290,7 @@ int
45d01a
 filter_devnode (vector blist, vector elist, char * dev)
45d01a
 {
45d01a
 	int r = _filter_devnode(blist, elist, dev);
45d01a
-	log_filter(dev, NULL, NULL, NULL, r);
45d01a
+	log_filter(dev, NULL, NULL, NULL, NULL, r);
45d01a
 	return r;
45d01a
 }
45d01a
 
45d01a
@@ -297,15 +310,67 @@ int
45d01a
 filter_wwid (vector blist, vector elist, char * wwid)
45d01a
 {
45d01a
 	int r = _filter_wwid(blist, elist, wwid);
45d01a
-	log_filter(NULL, NULL, NULL, wwid, r);
45d01a
+	log_filter(NULL, NULL, NULL, wwid, NULL, r);
45d01a
 	return r;
45d01a
 }
45d01a
 
45d01a
 int
45d01a
+_filter_property (struct config *conf, const char *env)
45d01a
+{
45d01a
+	if (_blacklist_exceptions(conf->elist_property, env))
45d01a
+		return MATCH_PROPERTY_BLIST_EXCEPT;
45d01a
+	if (_blacklist(conf->blist_property, env))
45d01a
+		return MATCH_PROPERTY_BLIST;
45d01a
+
45d01a
+	return 0;
45d01a
+}
45d01a
+
45d01a
+int
45d01a
+filter_property(struct config * conf, struct udev_device * udev)
45d01a
+{
45d01a
+	const char *devname = udev_device_get_sysname(udev);
45d01a
+	struct udev_list_entry *list_entry;
45d01a
+	int r;
45d01a
+
45d01a
+	if (!udev || (!VECTOR_SIZE(conf->elist_property) &&
45d01a
+		      !VECTOR_SIZE(conf->blist_property)))
45d01a
+		return 0;
45d01a
+
45d01a
+	udev_list_entry_foreach(list_entry,
45d01a
+				udev_device_get_properties_list_entry(udev)) {
45d01a
+		const char *env;
45d01a
+
45d01a
+		env = udev_list_entry_get_name(list_entry);
45d01a
+		if (!env)
45d01a
+			continue;
45d01a
+
45d01a
+		r = _filter_property(conf, env);
45d01a
+		if (r) {
45d01a
+			log_filter(devname, NULL, NULL, NULL, env, r);
45d01a
+			return r;
45d01a
+		}
45d01a
+	}
45d01a
+
45d01a
+	/*
45d01a
+	 * This is the inverse of the 'normal' matching;
45d01a
+	 * the environment variable _has_ to match.
45d01a
+	 */
45d01a
+	if (VECTOR_SIZE(conf->elist_property)) {
45d01a
+		log_filter(devname, NULL, NULL, NULL, NULL,
45d01a
+				MATCH_PROPERTY_BLIST_MISSING);
45d01a
+		return MATCH_PROPERTY_BLIST_MISSING;
45d01a
+	}
45d01a
+	return 0;
45d01a
+}
45d01a
+
45d01a
+int
45d01a
 _filter_path (struct config * conf, struct path * pp)
45d01a
 {
45d01a
 	int r;
45d01a
 
45d01a
+	r = filter_property(conf, pp->udev);
45d01a
+	if (r > 0)
45d01a
+		return r;
45d01a
 	r = _filter_devnode(conf->blist_devnode, conf->elist_devnode,pp->dev);
45d01a
 	if (r > 0)
45d01a
 		return r;
45d01a
@@ -321,7 +386,7 @@ int
45d01a
 filter_path (struct config * conf, struct path * pp)
45d01a
 {
45d01a
 	int r=_filter_path(conf, pp);
45d01a
-	log_filter(pp->dev, pp->vendor_id, pp->product_id, pp->wwid, r);
45d01a
+	log_filter(pp->dev, pp->vendor_id, pp->product_id, pp->wwid, NULL, r);
45d01a
 	return r;
45d01a
 }
45d01a
 
45d01a
Index: multipath-tools-130222/libmultipath/blacklist.h
45d01a
===================================================================
45d01a
--- multipath-tools-130222.orig/libmultipath/blacklist.h
45d01a
+++ multipath-tools-130222/libmultipath/blacklist.h
45d01a
@@ -1,15 +1,19 @@
45d01a
 #ifndef _BLACKLIST_H
45d01a
 #define _BLACKLIST_H
45d01a
 
45d01a
+#include <libudev.h>
45d01a
 #include "regex.h"
45d01a
 
45d01a
 #define MATCH_NOTHING       0
45d01a
 #define MATCH_WWID_BLIST    1
45d01a
 #define MATCH_DEVICE_BLIST  2
45d01a
 #define MATCH_DEVNODE_BLIST 3
45d01a
+#define MATCH_PROPERTY_BLIST 4
45d01a
+#define MATCH_PROPERTY_BLIST_MISSING 5
45d01a
 #define MATCH_WWID_BLIST_EXCEPT    -MATCH_WWID_BLIST
45d01a
 #define MATCH_DEVICE_BLIST_EXCEPT  -MATCH_DEVICE_BLIST
45d01a
 #define MATCH_DEVNODE_BLIST_EXCEPT -MATCH_DEVNODE_BLIST
45d01a
+#define MATCH_PROPERTY_BLIST_EXCEPT -MATCH_PROPERTY_BLIST
45d01a
 
45d01a
 struct blentry {
45d01a
 	char * str;
45d01a
@@ -31,6 +35,7 @@ int filter_devnode (vector, vector, char
45d01a
 int filter_wwid (vector, vector, char *);
45d01a
 int filter_device (vector, vector, char *, char *);
45d01a
 int filter_path (struct config *, struct path *);
45d01a
+int filter_property(struct config *, struct udev_device *);
45d01a
 int store_ble (vector, char *, int);
45d01a
 int set_ble_device (vector, char *, char *, int);
45d01a
 void free_blacklist (vector);
45d01a
Index: multipath-tools-130222/libmultipath/config.c
45d01a
===================================================================
45d01a
--- multipath-tools-130222.orig/libmultipath/config.c
45d01a
+++ multipath-tools-130222/libmultipath/config.c
45d01a
@@ -597,10 +597,12 @@ free_config (struct config * conf)
45d01a
 
45d01a
 	free_blacklist(conf->blist_devnode);
45d01a
 	free_blacklist(conf->blist_wwid);
45d01a
+	free_blacklist(conf->blist_property);
45d01a
 	free_blacklist_device(conf->blist_device);
45d01a
 
45d01a
 	free_blacklist(conf->elist_devnode);
45d01a
 	free_blacklist(conf->elist_wwid);
45d01a
+	free_blacklist(conf->elist_property);
45d01a
 	free_blacklist_device(conf->elist_device);
45d01a
 
45d01a
 	free_mptable(conf->mptable);
45d01a
@@ -779,8 +781,12 @@ load_config (char * file, struct udev *u
45d01a
 		if (!conf->blist_device)
45d01a
 			goto out;
45d01a
 	}
45d01a
-	if (setup_default_blist(conf))
45d01a
-		goto out;
45d01a
+	if (conf->blist_property == NULL) {
45d01a
+		conf->blist_property = vector_alloc();
45d01a
+
45d01a
+		if (!conf->blist_property)
45d01a
+			goto out;
45d01a
+	}
45d01a
 
45d01a
 	if (conf->elist_devnode == NULL) {
45d01a
 		conf->elist_devnode = vector_alloc();
45d01a
@@ -802,6 +808,16 @@ load_config (char * file, struct udev *u
45d01a
 			goto out;
45d01a
 	}
45d01a
 
45d01a
+	if (conf->elist_property == NULL) {
45d01a
+		conf->elist_property = vector_alloc();
45d01a
+
45d01a
+		if (!conf->elist_property)
45d01a
+			goto out;
45d01a
+	}
45d01a
+
45d01a
+	if (setup_default_blist(conf))
45d01a
+		goto out;
45d01a
+
45d01a
 	if (conf->mptable == NULL) {
45d01a
 		conf->mptable = vector_alloc();
45d01a
 		if (!conf->mptable)
45d01a
Index: multipath-tools-130222/libmultipath/config.h
45d01a
===================================================================
45d01a
--- multipath-tools-130222.orig/libmultipath/config.h
45d01a
+++ multipath-tools-130222/libmultipath/config.h
45d01a
@@ -189,9 +189,11 @@ struct config {
45d01a
 	vector blist_devnode;
45d01a
 	vector blist_wwid;
45d01a
 	vector blist_device;
45d01a
+	vector blist_property;
45d01a
 	vector elist_devnode;
45d01a
 	vector elist_wwid;
45d01a
 	vector elist_device;
45d01a
+	vector elist_property;
45d01a
 };
45d01a
 
45d01a
 struct config * conf;
45d01a
Index: multipath-tools-130222/libmultipath/configure.c
45d01a
===================================================================
45d01a
--- multipath-tools-130222.orig/libmultipath/configure.c
45d01a
+++ multipath-tools-130222/libmultipath/configure.c
45d01a
@@ -1027,6 +1027,10 @@ get_refwwid (char * dev, enum devtypes d
45d01a
 				return ret;
45d01a
 			}
45d01a
 		}
45d01a
+		if (pp->udev && pp->uid_attribute &&
45d01a
+		    filter_property(conf, pp->udev) > 0)
45d01a
+			return 2;
45d01a
+
45d01a
 		refwwid = pp->wwid;
45d01a
 		goto out;
45d01a
 	}
45d01a
@@ -1051,6 +1055,10 @@ get_refwwid (char * dev, enum devtypes d
45d01a
 				return ret;
45d01a
 			}
45d01a
 		}
45d01a
+		if (pp->udev && pp->uid_attribute &&
45d01a
+		    filter_property(conf, pp->udev) > 0)
45d01a
+			return 2;
45d01a
+
45d01a
 		refwwid = pp->wwid;
45d01a
 		goto out;
45d01a
 	}
45d01a
Index: multipath-tools-130222/libmultipath/dict.c
45d01a
===================================================================
45d01a
--- multipath-tools-130222.orig/libmultipath/dict.c
45d01a
+++ multipath-tools-130222/libmultipath/dict.c
45d01a
@@ -1063,8 +1063,11 @@ blacklist_handler(vector strvec)
45d01a
 		conf->blist_wwid = vector_alloc();
45d01a
 	if (!conf->blist_device)
45d01a
 		conf->blist_device = vector_alloc();
45d01a
+	if (!conf->blist_property)
45d01a
+		conf->blist_property = vector_alloc();
45d01a
 
45d01a
-	if (!conf->blist_devnode || !conf->blist_wwid || !conf->blist_device)
45d01a
+	if (!conf->blist_devnode || !conf->blist_wwid ||
45d01a
+	    !conf->blist_device || !conf->blist_property)
45d01a
 		return 1;
45d01a
 
45d01a
 	return 0;
45d01a
@@ -1079,8 +1082,11 @@ blacklist_exceptions_handler(vector strv
45d01a
 		conf->elist_wwid = vector_alloc();
45d01a
 	if (!conf->elist_device)
45d01a
 		conf->elist_device = vector_alloc();
45d01a
+	if (!conf->elist_property)
45d01a
+		conf->elist_property = vector_alloc();
45d01a
 
45d01a
-	if (!conf->elist_devnode || !conf->elist_wwid || !conf->elist_device)
45d01a
+	if (!conf->elist_devnode || !conf->elist_wwid ||
45d01a
+	    !conf->elist_device || !conf->elist_property)
45d01a
 		return 1;
45d01a
 
45d01a
 	return 0;
45d01a
@@ -1139,6 +1145,32 @@ ble_except_wwid_handler(vector strvec)
45d01a
 }
45d01a
 
45d01a
 static int
45d01a
+ble_property_handler(vector strvec)
45d01a
+{
45d01a
+	char * buff;
45d01a
+
45d01a
+	buff = set_value(strvec);
45d01a
+
45d01a
+	if (!buff)
45d01a
+		return 1;
45d01a
+
45d01a
+	return store_ble(conf->blist_property, buff, ORIGIN_CONFIG);
45d01a
+}
45d01a
+
45d01a
+static int
45d01a
+ble_except_property_handler(vector strvec)
45d01a
+{
45d01a
+	char * buff;
45d01a
+
45d01a
+	buff = set_value(strvec);
45d01a
+
45d01a
+	if (!buff)
45d01a
+		return 1;
45d01a
+
45d01a
+	return store_ble(conf->elist_property, buff, ORIGIN_CONFIG);
45d01a
+}
45d01a
+
45d01a
+static int
45d01a
 ble_device_handler(vector strvec)
45d01a
 {
45d01a
 	return alloc_ble_device(conf->blist_device);
45d01a
@@ -3903,6 +3935,7 @@ init_keywords(void)
45d01a
 	install_keyword_root("blacklist", &blacklist_handler);
45d01a
 	install_keyword_multi("devnode", &ble_devnode_handler, &snprint_ble_simple);
45d01a
 	install_keyword_multi("wwid", &ble_wwid_handler, &snprint_ble_simple);
45d01a
+	install_keyword_multi("property", &ble_property_handler, &snprint_ble_simple);
45d01a
 	install_keyword_multi("device", &ble_device_handler, NULL);
45d01a
 	install_sublevel();
45d01a
 	install_keyword("vendor", &ble_vendor_handler, &snprint_bled_vendor);
45d01a
@@ -3911,6 +3944,7 @@ init_keywords(void)
45d01a
 	install_keyword_root("blacklist_exceptions", &blacklist_exceptions_handler);
45d01a
 	install_keyword_multi("devnode", &ble_except_devnode_handler, &snprint_ble_simple);
45d01a
 	install_keyword_multi("wwid", &ble_except_wwid_handler, &snprint_ble_simple);
45d01a
+	install_keyword_multi("property", &ble_except_property_handler, &snprint_ble_simple);
45d01a
 	install_keyword_multi("device", &ble_except_device_handler, NULL);
45d01a
 	install_sublevel();
45d01a
 	install_keyword("vendor", &ble_except_vendor_handler, &snprint_bled_vendor);
45d01a
Index: multipath-tools-130222/libmultipath/discovery.c
45d01a
===================================================================
45d01a
--- multipath-tools-130222.orig/libmultipath/discovery.c
45d01a
+++ multipath-tools-130222/libmultipath/discovery.c
45d01a
@@ -1332,6 +1332,8 @@ pathinfo (struct path *pp, vector hwtabl
45d01a
 	 * limited by DI_BLACKLIST and occurs before this debug
45d01a
 	 * message with the mask value.
45d01a
 	 */
45d01a
+	if (pp->udev && filter_property(conf, pp->udev) > 0)
45d01a
+		return PATHINFO_SKIPPED;
45d01a
 	if (filter_devnode(conf->blist_devnode,
45d01a
 			   conf->elist_devnode,
45d01a
 			   pp->dev) > 0)
45d01a
Index: multipath-tools-130222/libmultipath/print.c
45d01a
===================================================================
45d01a
--- multipath-tools-130222.orig/libmultipath/print.c
45d01a
+++ multipath-tools-130222/libmultipath/print.c
45d01a
@@ -1415,6 +1415,19 @@ snprint_blacklist_report (char * buff, i
45d01a
 
45d01a
 	if ((len - fwd - threshold) <= 0)
45d01a
 		return len;
45d01a
+	fwd += snprintf(buff + fwd, len - fwd, "udev property rules:\n"
45d01a
+					       "- blacklist:\n");
45d01a
+	if (!snprint_blacklist_group(buff, len, &fwd, &conf->blist_property))
45d01a
+		return len;
45d01a
+
45d01a
+	if ((len - fwd - threshold) <= 0)
45d01a
+		return len;
45d01a
+	fwd += snprintf(buff + fwd, len - fwd, "- exceptions:\n");
45d01a
+	if (snprint_blacklist_group(buff, len, &fwd, &conf->elist_property) == 0)
45d01a
+		return len;
45d01a
+
45d01a
+	if ((len - fwd - threshold) <= 0)
45d01a
+		return len;
45d01a
 	fwd += snprintf(buff + fwd, len - fwd, "wwid rules:\n"
45d01a
 					       "- blacklist:\n");
45d01a
 	if (snprint_blacklist_group(buff, len, &fwd, &conf->blist_wwid) == 0)
45d01a
@@ -1480,6 +1493,15 @@ snprint_blacklist (char * buff, int len)
45d01a
 		if (fwd > len)
45d01a
 			return len;
45d01a
 	}
45d01a
+	vector_foreach_slot (conf->blist_property, ble, i) {
45d01a
+		kw = find_keyword(rootkw->sub, "property");
45d01a
+		if (!kw)
45d01a
+			return 0;
45d01a
+		fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n",
45d01a
+				       kw, ble);
45d01a
+		if (fwd > len)
45d01a
+			return len;
45d01a
+	}
45d01a
 	rootkw = find_keyword(rootkw->sub, "device");
45d01a
 	if (!rootkw)
45d01a
 		return 0;
45d01a
@@ -1544,6 +1566,15 @@ snprint_blacklist_except (char * buff, i
45d01a
 		if (!kw)
45d01a
 			return 0;
45d01a
 		fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n",
45d01a
+				       kw, ele);
45d01a
+		if (fwd > len)
45d01a
+			return len;
45d01a
+	}
45d01a
+	vector_foreach_slot (conf->elist_property, ele, i) {
45d01a
+		kw = find_keyword(rootkw->sub, "property");
45d01a
+		if (!kw)
45d01a
+			return 0;
45d01a
+		fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n",
45d01a
 				       kw, ele);
45d01a
 		if (fwd > len)
45d01a
 			return len;
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
@@ -626,6 +626,9 @@ The \fIWorld Wide Identification\fR of a
45d01a
 .B devnode
45d01a
 Regular expression of the device nodes to be excluded.
45d01a
 .TP
45d01a
+.B property
45d01a
+Regular expresion of the udev property to be excluded.
45d01a
+.TP
45d01a
 .B device
45d01a
 Subsection for the device description. This subsection recognizes the
45d01a
 .I vendor
45d01a
@@ -650,8 +653,11 @@ The following keywords are recognized:
45d01a
 .B wwid
45d01a
 The \fIWorld Wide Identification\fR of a device.
45d01a
 .TP
45d01a
+.B property
45d01a
+Regular expresion of the udev property to be whitelisted.
45d01a
+.TP
45d01a
 .B devnode
45d01a
-Regular expression of the device nodes to be excluded.
45d01a
+Regular expression of the device nodes to be whitelisted.
45d01a
 .TP
45d01a
 .B device
45d01a
 Subsection for the device description. This subsection recognizes the
45d01a
@@ -661,6 +667,25 @@ and
45d01a
 keywords. For a full description of these keywords please see the
45d01a
 .I devices
45d01a
 section description.
45d01a
+.LP
45d01a
+The
45d01a
+.I property
45d01a
+blacklist and whitelist handling is different from the usual handling
45d01a
+in the sense that if the whitelist is set, it
45d01a
+.B has
45d01a
+to match, otherwise the device will be blacklisted.
45d01a
+In these cases the message
45d01a
+.I blacklisted, udev property missing
45d01a
+will be displayed. For example settting the
45d01a
+.I property
45d01a
+blacklist_exception to
45d01a
+.I (SCSI_IDENT_|ID_WWN)
45d01a
+will blacklist all devices that have no udev property whose name regex matches
45d01a
+either
45d01a
+.I SCSI_IDENT_
45d01a
+or
45d01a
+.I ID_WWN.
45d01a
+This works to exclude most non-multipathable devices.
45d01a
 .SH "multipaths section"
45d01a
 The only recognized attribute for the
45d01a
 .B multipaths