From: Hannes Reinecke <hare@suse.de>
To: Christophe Varoqui <christophe.varoqui@gmail.com>
Cc: dm-devel@redhat.com
Subject: [PATCH 22/29] multipath: Implement 'property' blacklist
Date: Mon, 15 Jul 2013 15:00:23 +0200 [thread overview]
Message-ID: <1373893230-26077-23-git-send-email-hare@suse.de> (raw)
In-Reply-To: <1373893230-26077-1-git-send-email-hare@suse.de>
Multipath can only handle device properly which support the VPD
page 0x83. Originally this was ensured by 'scsi_id', which would
not present an ID_SERIAL value in these cases.
With the move to udev 'ID_SERIAL' is now always present, so
multipath would try to attach to _all_ SCSI devices.
This patch implements an 'property' blacklist, which allows to
blacklist a device based on the existence of udev properties.
Any device not providing the udev property from the whitelist
will be ignored.
The default whitelist is set to '(ID_WWN|ID_SCSI_VPD)'.
Signed-off-by: Hannes Reinecke <hare@suse.de>
---
libmultipath/blacklist.c | 105 +++++++++++++++++++++++++++++++++++---------
libmultipath/blacklist.h | 19 +++++---
libmultipath/config.c | 19 +++++++-
libmultipath/config.h | 2 +
libmultipath/dict.c | 36 ++++++++++++++-
libmultipath/discovery.c | 3 ++
libmultipath/print.c | 31 +++++++++++++
multipath.conf.defaults | 1 +
multipath/multipath.conf.5 | 19 +++++++-
9 files changed, 203 insertions(+), 32 deletions(-)
diff --git a/libmultipath/blacklist.c b/libmultipath/blacklist.c
index 49a40f9..d597350 100644
--- a/libmultipath/blacklist.c
+++ b/libmultipath/blacklist.c
@@ -2,6 +2,7 @@
* Copyright (c) 2004, 2005 Christophe Varoqui
*/
#include <stdio.h>
+#include <libudev.h>
#include "checkers.h"
#include "memory.h"
@@ -96,7 +97,7 @@ set_ble_device (vector blist, char * vendor, char * product, int origin)
}
int
-_blacklist_exceptions (vector elist, char * str)
+_blacklist_exceptions (vector elist, const char * str)
{
int i;
struct blentry * ele;
@@ -109,7 +110,7 @@ _blacklist_exceptions (vector elist, char * str)
}
int
-_blacklist (vector blist, char * str)
+_blacklist (vector blist, const char * str)
{
int i;
struct blentry * ble;
@@ -175,6 +176,12 @@ setup_default_blist (struct config * conf)
if (store_ble(conf->blist_devnode, str, ORIGIN_DEFAULT))
return 1;
+ str = STRDUP("(ID_SCSI_VPD|ID_WWN)");
+ if (!str)
+ return 1;
+ if (store_ble(conf->elist_property, str, ORIGIN_DEFAULT))
+ return 1;
+
vector_foreach_slot (conf->hwtable, hwe, i) {
if (hwe->bl_product) {
if (_blacklist_device(conf->blist_device, hwe->vendor,
@@ -196,16 +203,20 @@ setup_default_blist (struct config * conf)
return 0;
}
-#define LOG_BLIST(M) \
- if (vendor && product) \
- condlog(3, "%s: (%s:%s) %s", dev, vendor, product, (M)); \
- else if (wwid) \
- condlog(3, "%s: (%s) %s", dev, wwid, (M)); \
- else \
- condlog(3, "%s: %s", dev, (M))
+#define LOG_BLIST(M,S) \
+ if (vendor && product) \
+ condlog(3, "%s: (%s:%s) %s %s", \
+ dev, vendor, product, (M), (S)); \
+ else if (wwid) \
+ condlog(3, "%s: %s %s %s", dev, (M), wwid, (S)); \
+ else if (env) \
+ condlog(3, "%s: %s %s %s", dev, (M), env, (S)); \
+ else \
+ condlog(3, "%s: %s %s", dev, (M), (S))
void
-log_filter (char *dev, char *vendor, char *product, char *wwid, int r)
+log_filter (const char *dev, char *vendor, char *product, char *wwid,
+ const char *env, int r)
{
/*
* Try to sort from most likely to least.
@@ -214,22 +225,31 @@ log_filter (char *dev, char *vendor, char *product, char *wwid, int r)
case MATCH_NOTHING:
break;
case MATCH_DEVICE_BLIST:
- LOG_BLIST("vendor/product blacklisted");
+ LOG_BLIST("vendor/product", "blacklisted");
break;
case MATCH_WWID_BLIST:
- LOG_BLIST("wwid blacklisted");
+ LOG_BLIST("wwid", "blacklisted");
break;
case MATCH_DEVNODE_BLIST:
- LOG_BLIST("device node name blacklisted");
+ LOG_BLIST("device node name", "blacklisted");
+ break;
+ case MATCH_PROPERTY_BLIST:
+ LOG_BLIST("udev property", "blacklisted");
break;
case MATCH_DEVICE_BLIST_EXCEPT:
- LOG_BLIST("vendor/product whitelisted");
+ LOG_BLIST("vendor/product", "whitelisted");
break;
case MATCH_WWID_BLIST_EXCEPT:
- LOG_BLIST("wwid whitelisted");
+ LOG_BLIST("wwid", "whitelisted");
break;
case MATCH_DEVNODE_BLIST_EXCEPT:
- LOG_BLIST("device node name whitelisted");
+ LOG_BLIST("device node name", "whitelisted");
+ break;
+ case MATCH_PROPERTY_BLIST_EXCEPT:
+ LOG_BLIST("udev property", "whitelisted");
+ break;
+ case MATCH_PROPERTY_BLIST_MISSING:
+ LOG_BLIST("blacklisted,", "udev property missing");
break;
}
}
@@ -250,7 +270,7 @@ int
filter_device (vector blist, vector elist, char * vendor, char * product)
{
int r = _filter_device(blist, elist, vendor, product);
- log_filter(NULL, vendor, product, NULL, r);
+ log_filter(NULL, vendor, product, NULL, NULL, r);
return r;
}
@@ -270,7 +290,7 @@ int
filter_devnode (vector blist, vector elist, char * dev)
{
int r = _filter_devnode(blist, elist, dev);
- log_filter(dev, NULL, NULL, NULL, r);
+ log_filter(dev, NULL, NULL, NULL, NULL, r);
return r;
}
@@ -290,7 +310,7 @@ int
filter_wwid (vector blist, vector elist, char * wwid)
{
int r = _filter_wwid(blist, elist, wwid);
- log_filter(NULL, NULL, NULL, wwid, r);
+ log_filter(NULL, NULL, NULL, wwid, NULL, r);
return r;
}
@@ -314,10 +334,55 @@ int
filter_path (struct config * conf, struct path * pp)
{
int r=_filter_path(conf, pp);
- log_filter(pp->dev, pp->vendor_id, pp->product_id, pp->wwid, r);
+ log_filter(pp->dev, pp->vendor_id, pp->product_id, pp->wwid, NULL, r);
return r;
}
+int
+_filter_property (struct config *conf, const char *env)
+{
+ if (_blacklist_exceptions(conf->elist_property, env))
+ return MATCH_PROPERTY_BLIST_EXCEPT;
+ if (_blacklist(conf->blist_property, env))
+ return MATCH_PROPERTY_BLIST;
+
+ return 0;
+}
+
+int
+filter_property(struct config * conf, struct udev_device * udev)
+{
+ const char *devname = udev_device_get_sysname(udev);
+ struct udev_list_entry *list_entry;
+ int r;
+
+ if (!udev)
+ return 0;
+
+ udev_list_entry_foreach(list_entry,
+ udev_device_get_properties_list_entry(udev)) {
+ const char *env;
+
+ env = udev_list_entry_get_name(list_entry);
+ if (!env)
+ continue;
+
+ r = _filter_property(conf, env);
+ if (r) {
+ log_filter(devname, NULL, NULL, NULL, env, r);
+ return r;
+ }
+ }
+
+ /*
+ * This is the inverse of the 'normal' matching;
+ * the environment variable _has_ to match.
+ */
+ log_filter(devname, NULL, NULL, NULL, NULL,
+ MATCH_PROPERTY_BLIST_MISSING);
+ return MATCH_PROPERTY_BLIST_MISSING;
+}
+
void
free_blacklist (vector blist)
{
diff --git a/libmultipath/blacklist.h b/libmultipath/blacklist.h
index cdbebef..0e90e9a 100644
--- a/libmultipath/blacklist.h
+++ b/libmultipath/blacklist.h
@@ -1,15 +1,19 @@
#ifndef _BLACKLIST_H
#define _BLACKLIST_H
+#include <libudev.h>
#include "regex.h"
-#define MATCH_NOTHING 0
-#define MATCH_WWID_BLIST 1
-#define MATCH_DEVICE_BLIST 2
-#define MATCH_DEVNODE_BLIST 3
-#define MATCH_WWID_BLIST_EXCEPT -MATCH_WWID_BLIST
-#define MATCH_DEVICE_BLIST_EXCEPT -MATCH_DEVICE_BLIST
-#define MATCH_DEVNODE_BLIST_EXCEPT -MATCH_DEVNODE_BLIST
+#define MATCH_NOTHING 0
+#define MATCH_WWID_BLIST 1
+#define MATCH_DEVICE_BLIST 2
+#define MATCH_DEVNODE_BLIST 3
+#define MATCH_PROPERTY_BLIST 4
+#define MATCH_PROPERTY_BLIST_MISSING 5
+#define MATCH_WWID_BLIST_EXCEPT -MATCH_WWID_BLIST
+#define MATCH_DEVICE_BLIST_EXCEPT -MATCH_DEVICE_BLIST
+#define MATCH_DEVNODE_BLIST_EXCEPT -MATCH_DEVNODE_BLIST
+#define MATCH_PROPERTY_BLIST_EXCEPT -MATCH_PROPERTY_BLIST
struct blentry {
char * str;
@@ -31,6 +35,7 @@ int filter_devnode (vector, vector, char *);
int filter_wwid (vector, vector, char *);
int filter_device (vector, vector, char *, char *);
int filter_path (struct config *, struct path *);
+int filter_property(struct config *, struct udev_device *);
int store_ble (vector, char *, int);
int set_ble_device (vector, char *, char *, int);
void free_blacklist (vector);
diff --git a/libmultipath/config.c b/libmultipath/config.c
index 8013a07..9b7adda 100644
--- a/libmultipath/config.c
+++ b/libmultipath/config.c
@@ -513,10 +513,12 @@ free_config (struct config * conf)
free_blacklist(conf->blist_devnode);
free_blacklist(conf->blist_wwid);
+ free_blacklist(conf->blist_property);
free_blacklist_device(conf->blist_device);
free_blacklist(conf->elist_devnode);
free_blacklist(conf->elist_wwid);
+ free_blacklist(conf->elist_property);
free_blacklist_device(conf->elist_device);
free_mptable(conf->mptable);
@@ -619,8 +621,12 @@ load_config (char * file, struct udev *udev)
if (!conf->blist_device)
goto out;
}
- if (setup_default_blist(conf))
- goto out;
+ if (conf->blist_property == NULL) {
+ conf->blist_property = vector_alloc();
+
+ if (!conf->blist_property)
+ goto out;
+ }
if (conf->elist_devnode == NULL) {
conf->elist_devnode = vector_alloc();
@@ -642,6 +648,15 @@ load_config (char * file, struct udev *udev)
goto out;
}
+ if (conf->elist_property == NULL) {
+ conf->elist_property = vector_alloc();
+
+ if (!conf->elist_property)
+ goto out;
+ }
+ if (setup_default_blist(conf))
+ goto out;
+
if (conf->mptable == NULL) {
conf->mptable = vector_alloc();
if (!conf->mptable)
diff --git a/libmultipath/config.h b/libmultipath/config.h
index ca65f88..9c467e8 100644
--- a/libmultipath/config.h
+++ b/libmultipath/config.h
@@ -136,9 +136,11 @@ struct config {
vector blist_devnode;
vector blist_wwid;
vector blist_device;
+ vector blist_property;
vector elist_devnode;
vector elist_wwid;
vector elist_device;
+ vector elist_property;
};
struct config * conf;
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
index 0408e03..0bf9587 100644
--- a/libmultipath/dict.c
+++ b/libmultipath/dict.c
@@ -691,8 +691,10 @@ blacklist_handler(vector strvec)
conf->blist_devnode = vector_alloc();
conf->blist_wwid = vector_alloc();
conf->blist_device = vector_alloc();
+ conf->blist_property = vector_alloc();
- if (!conf->blist_devnode || !conf->blist_wwid || !conf->blist_device)
+ if (!conf->blist_devnode || !conf->blist_wwid ||
+ !conf->blist_device || !conf->blist_property)
return 1;
return 0;
@@ -704,8 +706,10 @@ blacklist_exceptions_handler(vector strvec)
conf->elist_devnode = vector_alloc();
conf->elist_wwid = vector_alloc();
conf->elist_device = vector_alloc();
+ conf->elist_property = vector_alloc();
- if (!conf->elist_devnode || !conf->elist_wwid || !conf->elist_device)
+ if (!conf->elist_devnode || !conf->elist_wwid ||
+ !conf->elist_device || !conf->elist_property)
return 1;
return 0;
@@ -764,6 +768,32 @@ ble_except_wwid_handler(vector strvec)
}
static int
+ble_property_handler(vector strvec)
+{
+ char * buff;
+
+ buff = set_value(strvec);
+
+ if (!buff)
+ return 1;
+
+ return store_ble(conf->blist_property, buff, ORIGIN_CONFIG);
+}
+
+static int
+ble_except_property_handler(vector strvec)
+{
+ char * buff;
+
+ buff = set_value(strvec);
+
+ if (!buff)
+ return 1;
+
+ return store_ble(conf->elist_property, buff, ORIGIN_CONFIG);
+}
+
+static int
ble_device_handler(vector strvec)
{
return alloc_ble_device(conf->blist_device);
@@ -2830,6 +2860,7 @@ init_keywords(void)
install_keyword_root("blacklist", &blacklist_handler);
install_keyword_multi("devnode", &ble_devnode_handler, &snprint_ble_simple);
install_keyword_multi("wwid", &ble_wwid_handler, &snprint_ble_simple);
+ install_keyword_multi("property", &ble_property_handler, &snprint_ble_simple);
install_keyword_multi("device", &ble_device_handler, NULL);
install_sublevel();
install_keyword("vendor", &ble_vendor_handler, &snprint_bled_vendor);
@@ -2838,6 +2869,7 @@ init_keywords(void)
install_keyword_root("blacklist_exceptions", &blacklist_exceptions_handler);
install_keyword_multi("devnode", &ble_except_devnode_handler, &snprint_ble_simple);
install_keyword_multi("wwid", &ble_except_wwid_handler, &snprint_ble_simple);
+ install_keyword_multi("property", &ble_except_property_handler, &snprint_ble_simple);
install_keyword_multi("device", &ble_except_device_handler, NULL);
install_sublevel();
install_keyword("vendor", &ble_except_vendor_handler, &snprint_bled_vendor);
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index 82f086b..e9c6a50 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -82,6 +82,9 @@ path_discover (vector pathvec, struct config * conf,
if (!devname)
return 0;
+ if (filter_property(conf, udevice) > 0)
+ return 0;
+
if (filter_devnode(conf->blist_devnode, conf->elist_devnode,
(char *)devname) > 0)
return 0;
diff --git a/libmultipath/print.c b/libmultipath/print.c
index b6d08b7..7feeb26 100644
--- a/libmultipath/print.c
+++ b/libmultipath/print.c
@@ -1078,6 +1078,19 @@ snprint_blacklist_report (char * buff, int len)
if ((len - fwd - threshold) <= 0)
return len;
+ fwd += snprintf(buff + fwd, len - fwd, "udev property rules:\n"
+ "- blacklist:\n");
+ if (!snprint_blacklist_group(buff, len, &fwd, &conf->blist_property))
+ return len;
+
+ if ((len - fwd - threshold) <= 0)
+ return len;
+ fwd += snprintf(buff + fwd, len - fwd, "- exceptions:\n");
+ if (snprint_blacklist_group(buff, len, &fwd, &conf->elist_property) == 0)
+ return len;
+
+ if ((len - fwd - threshold) <= 0)
+ return len;
fwd += snprintf(buff + fwd, len - fwd, "wwid rules:\n"
"- blacklist:\n");
if (snprint_blacklist_group(buff, len, &fwd, &conf->blist_wwid) == 0)
@@ -1143,6 +1156,15 @@ snprint_blacklist (char * buff, int len)
if (fwd > len)
return len;
}
+ vector_foreach_slot (conf->blist_property, ble, i) {
+ kw = find_keyword(rootkw->sub, "property");
+ if (!kw)
+ return 0;
+ fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n",
+ kw, ble);
+ if (fwd > len)
+ return len;
+ }
rootkw = find_keyword(rootkw->sub, "device");
if (!rootkw)
return 0;
@@ -1211,6 +1233,15 @@ snprint_blacklist_except (char * buff, int len)
if (fwd > len)
return len;
}
+ vector_foreach_slot (conf->elist_property, ele, i) {
+ kw = find_keyword(rootkw->sub, "property");
+ if (!kw)
+ return 0;
+ fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n",
+ kw, ele);
+ if (fwd > len)
+ return len;
+ }
rootkw = find_keyword(rootkw->sub, "device");
if (!rootkw)
return 0;
diff --git a/multipath.conf.defaults b/multipath.conf.defaults
index f278f1f..636c1e6 100644
--- a/multipath.conf.defaults
+++ b/multipath.conf.defaults
@@ -70,6 +70,7 @@
# }
#}
#blacklist_exceptions {
+# property "(ID_SCSI_VPD|ID_WWN)"
#}
#devices {
# device {
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
index a937db9..0fd3035 100644
--- a/multipath/multipath.conf.5
+++ b/multipath/multipath.conf.5
@@ -422,6 +422,9 @@ The \fIWorld Wide Identification\fR of a device.
.B devnode
Regular expression of the device nodes to be excluded.
.TP
+.B property
+Regular expresion of the udev property to be excluded.
+.TP
.B device
Subsection for the device description. This subsection recognizes the
.I vendor
@@ -446,8 +449,12 @@ The following keywords are recognized:
.B wwid
The \fIWorld Wide Identification\fR of a device.
.TP
+.B property
+Regular expresion of the udev property to be whitelisted. Defaults to
+.I (ID_WWN|ID_SCSI_VPD)
+.TP
.B devnode
-Regular expression of the device nodes to be excluded.
+Regular expression of the device nodes to be whitelisted.
.TP
.B device
Subsection for the device description. This subsection recognizes the
@@ -457,6 +464,16 @@ and
keywords. For a full description of these keywords please see the
.I devices
section description.
+.LP
+The
+.I property
+blacklist and whitelist handling is different from the usual handling
+in the sense that the whitelist
+.B has
+to be set, otherwise the device will be blacklisted.
+In these cases the message
+.I blacklisted, udev property missing
+will be displayed.
.SH "multipaths section"
The only recognized attribute for the
.B multipaths
--
1.7.10.4
next prev parent reply other threads:[~2013-07-15 13:00 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-15 13:00 [PATCH 00/29] SLES resync Hannes Reinecke
2013-07-15 13:00 ` [PATCH 01/29] multipath: bind lifetime of udev context to main thread Hannes Reinecke
2013-07-15 13:00 ` [PATCH 02/29] Document 'infinity' as possible value for dev_loss_tmo Hannes Reinecke
2013-07-15 13:00 ` [PATCH 03/29] alua: Do not add preferred path priority for active/optimized Hannes Reinecke
2013-07-15 13:00 ` [PATCH 04/29] multipath: Increase dev_loss_tmo prior to fast_io_fail Hannes Reinecke
2013-07-15 13:00 ` [PATCH 05/29] libmultipath: return PATH_DOWN for quiesced paths Hannes Reinecke
2013-07-15 13:00 ` [PATCH 06/29] libmultipath: Implement PATH_TIMEOUT Hannes Reinecke
2013-07-15 13:00 ` [PATCH 07/29] Deprecate pg_timeout Hannes Reinecke
2013-07-15 13:00 ` [PATCH 08/29] kpartx: create correct symlinks for PATH_FAILED events Hannes Reinecke
2013-07-15 13:00 ` [PATCH 09/29] multipath: Deprecate 'getuid' configuration variable Hannes Reinecke
2013-07-15 13:00 ` [PATCH 10/29] kpartx: support disk with non-512B sectors Hannes Reinecke
2013-07-15 13:00 ` [PATCH 11/29] multipath: Add 'Datacore Virtual Disk' to internal hardware table Hannes Reinecke
2013-07-15 13:00 ` [PATCH 12/29] Minor fixes for priority handling Hannes Reinecke
2013-07-15 13:00 ` [PATCH 13/29] Check return value from pathinfo() Hannes Reinecke
2013-07-15 13:00 ` [PATCH 14/29] Read directly from sysfs when checking the device size Hannes Reinecke
2013-07-15 13:00 ` [PATCH 15/29] multipath.conf.annotated: Document rr_min_io_rq Hannes Reinecke
2013-07-15 13:00 ` [PATCH 16/29] Correctly print out 'max' for max_fds Hannes Reinecke
2013-07-15 13:00 ` [PATCH 17/29] Correctly set max_fds in case of failure Hannes Reinecke
2013-07-15 13:00 ` [PATCH 18/29] Update multipath.conf.defaults Hannes Reinecke
2013-07-15 13:00 ` [PATCH 19/29] Correctly set pgfailback Hannes Reinecke
2013-07-15 13:00 ` [PATCH 20/29] multipath.conf.5: clarify 'no_path_retry' default setting Hannes Reinecke
2013-07-15 13:00 ` [PATCH 21/29] multipath.conf.annotated: remove 'udev_dir' Hannes Reinecke
2013-07-15 13:00 ` Hannes Reinecke [this message]
2013-07-15 13:00 ` [PATCH 23/29] Do not print error when rport is blocked Hannes Reinecke
2013-07-15 13:00 ` [PATCH 24/29] multipath: reference the udev context when starting event queue Hannes Reinecke
2013-07-15 13:00 ` [PATCH 25/29] multipathd: valgrind fixes Hannes Reinecke
2013-07-15 13:00 ` [PATCH 26/29] multipathd: increase stacksize for uevent listener Hannes Reinecke
2013-07-15 13:00 ` [PATCH 27/29] Specify checker_timeout in seconds Hannes Reinecke
2013-07-15 13:00 ` [PATCH 28/29] multipath: fix setting of fast_io_fail_tmo Hannes Reinecke
2013-07-15 13:00 ` [PATCH 29/29] multipath: reset queue_if_no_path if flush failed Hannes Reinecke
2013-07-15 13:53 ` [PATCH 00/29] SLES resync Sebastian Riemer
2013-07-15 14:12 ` Hannes Reinecke
2013-07-16 7:10 ` Hannes Reinecke
2013-07-16 9:20 ` Sebastian Riemer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1373893230-26077-23-git-send-email-hare@suse.de \
--to=hare@suse.de \
--cc=christophe.varoqui@gmail.com \
--cc=dm-devel@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.