device-mapper-multipath/0030-RH-early-blacklist.patch
Benjamin Marzinski 775d7c1eb9 device-mapper-multipath-0.4.9-38
Add 0026-RH-fix-mpathpersist-fns.patch
Add 0027-RH-default-partition-delimiters.patch
  * Only use the -p delimiter when the device name ends in a number
Add 0028-RH-storagetek-config.patch
Add 0029-RH-kpartx-retry.patch
  * retry delete on busy loop devices
Add 0030-RH-early-blacklist.patch
  * multipath will now blacklist devices by device type and wwid in
    store_pathinfo, so that it doesn't do a bunch of unnecessary work
    on paths that it would only be removing later on.
2012-11-30 08:55:32 -06:00

570 lines
15 KiB
Diff

---
libmultipath/alias.c | 47 +++++++++++++++++-------------
libmultipath/alias.h | 2 -
libmultipath/configure.c | 70 ++++++++++++++++++++++++++++++----------------
libmultipath/configure.h | 2 -
libmultipath/discovery.c | 47 +++++++++++++++++++++++-------
libmultipath/discovery.h | 11 ++++---
libmultipath/util.c | 2 -
multipath/main.c | 14 ++++-----
multipathd/cli_handlers.c | 11 +++----
multipathd/main.c | 22 ++++++--------
10 files changed, 140 insertions(+), 88 deletions(-)
Index: multipath-tools-120821/libmultipath/discovery.c
===================================================================
--- multipath-tools-120821.orig/libmultipath/discovery.c
+++ multipath-tools-120821/libmultipath/discovery.c
@@ -28,37 +28,45 @@
#include "prio.h"
#include "defaults.h"
-struct path *
+int
store_pathinfo (vector pathvec, vector hwtable, struct udev_device *udevice,
- int flag)
+ int flag, struct path **pp_ptr)
{
+ int err = 1;
struct path * pp;
const char * devname;
+ if (pp_ptr)
+ *pp_ptr = NULL;
+
devname = udev_device_get_sysname(udevice);
if (!devname)
- return NULL;
+ return 1;
pp = alloc_path();
if (!pp)
- return NULL;
+ return 1;
if(safe_sprintf(pp->dev, "%s", devname)) {
condlog(0, "pp->dev too small");
goto out;
}
pp->udev = udev_device_ref(udevice);
- if (pathinfo(pp, hwtable, flag))
+ err = pathinfo(pp, hwtable, flag | DI_BLACKLIST);
+ if (err)
goto out;
- if (store_path(pathvec, pp))
+ err = store_path(pathvec, pp);
+ if (err)
goto out;
- return pp;
out:
- free_path(pp);
- return NULL;
+ if (err)
+ free_path(pp);
+ else if (pp_ptr)
+ *pp_ptr = pp;
+ return err;
}
static int
@@ -78,9 +86,11 @@ path_discover (vector pathvec, struct co
pp = find_path_by_dev(pathvec, (char *)devname);
if (!pp) {
- pp = store_pathinfo(pathvec, conf->hwtable,
- udevice, flag);
- return (pp ? 0 : 1);
+ if (store_pathinfo(pathvec, conf->hwtable,
+ udevice, flag, NULL) != 1)
+ return 0;
+ else
+ return 1;
}
return pathinfo(pp, conf->hwtable, flag);
}
@@ -853,6 +863,13 @@ pathinfo (struct path *pp, vector hwtabl
if (mask & DI_SYSFS && sysfs_pathinfo(pp))
return 1;
+ if (mask & DI_BLACKLIST && mask & DI_SYSFS) {
+ if (filter_device(conf->blist_device, conf->elist_device,
+ pp->vendor_id, pp->product_id) > 0) {
+ return 2;
+ }
+ }
+
path_state = path_offline(pp);
/*
@@ -906,6 +923,12 @@ pathinfo (struct path *pp, vector hwtabl
if (path_state == PATH_UP && (mask & DI_WWID) && !strlen(pp->wwid))
get_uid(pp);
+ if (mask & DI_BLACKLIST && mask & DI_WWID) {
+ if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
+ pp->wwid) > 0) {
+ return 2;
+ }
+ }
return 0;
Index: multipath-tools-120821/libmultipath/discovery.h
===================================================================
--- multipath-tools-120821.orig/libmultipath/discovery.h
+++ multipath-tools-120821/libmultipath/discovery.h
@@ -33,8 +33,9 @@ int do_tur (char *);
int path_offline (struct path *);
int get_state (struct path * pp, int daemon);
int pathinfo (struct path *, vector hwtable, int mask);
-struct path * store_pathinfo (vector pathvec, vector hwtable,
- struct udev_device *udevice, int flag);
+int store_pathinfo (vector pathvec, vector hwtable,
+ struct udev_device *udevice, int flag,
+ struct path **pp_ptr);
int sysfs_set_scsi_tmo (struct multipath *mpp);
int sysfs_get_timeout(struct path *pp, unsigned int *timeout);
@@ -46,14 +47,16 @@ enum discovery_mode {
__DI_SERIAL,
__DI_CHECKER,
__DI_PRIO,
- __DI_WWID
+ __DI_WWID,
+ __DI_BLACKLIST,
};
#define DI_SYSFS (1 << __DI_SYSFS)
#define DI_SERIAL (1 << __DI_SERIAL)
#define DI_CHECKER (1 << __DI_CHECKER)
#define DI_PRIO (1 << __DI_PRIO)
-#define DI_WWID (1 << __DI_WWID)
+#define DI_WWID (1 << __DI_WWID)
+#define DI_BLACKLIST (1 << __DI_BLACKLIST)
#define DI_ALL (DI_SYSFS | DI_SERIAL | DI_CHECKER | DI_PRIO | \
DI_WWID)
Index: multipath-tools-120821/libmultipath/alias.c
===================================================================
--- multipath-tools-120821.orig/libmultipath/alias.c
+++ multipath-tools-120821/libmultipath/alias.c
@@ -13,6 +13,9 @@
#include "uxsock.h"
#include "alias.h"
#include "file.h"
+#include "vector.h"
+#include "checkers.h"
+#include "structs.h"
/*
@@ -121,23 +124,23 @@ lookup_binding(FILE *f, char *map_wwid,
}
static int
-rlookup_binding(FILE *f, char **map_wwid, char *map_alias)
+rlookup_binding(FILE *f, char *buff, char *map_alias)
{
- char buf[LINE_MAX];
+ char line[LINE_MAX];
unsigned int line_nr = 0;
int id = 0;
- *map_wwid = NULL;
+ buff[0] = '\0';
- while (fgets(buf, LINE_MAX, f)) {
+ while (fgets(line, LINE_MAX, f)) {
char *c, *alias, *wwid;
int curr_id;
line_nr++;
- c = strpbrk(buf, "#\n\r");
+ c = strpbrk(line, "#\n\r");
if (c)
*c = '\0';
- alias = strtok(buf, " \t");
+ alias = strtok(line, " \t");
if (!alias) /* blank line */
continue;
curr_id = scan_devname(alias, NULL); /* TBD: Why this call? */
@@ -150,13 +153,16 @@ rlookup_binding(FILE *f, char **map_wwid
line_nr);
continue;
}
+ if (strlen(wwid) > WWID_SIZE - 1) {
+ condlog(3,
+ "Ignoring too large wwid at %u in bindings file", line_nr);
+ continue;
+ }
if (strcmp(alias, map_alias) == 0){
condlog(3, "Found matching alias [%s] in bindings file."
"\nSetting wwid to %s", alias, wwid);
- *map_wwid = strdup(wwid);
- if (*map_wwid == NULL)
- condlog(0, "Cannot copy alias from bindings "
- "file : %s", strerror(errno));
+ strncpy(buff, wwid, WWID_SIZE);
+ buff[WWID_SIZE - 1] = '\0';
return id;
}
}
@@ -255,36 +261,35 @@ get_user_friendly_alias(char *wwid, char
return alias;
}
-char *
-get_user_friendly_wwid(char *alias, char *file)
+int
+get_user_friendly_wwid(char *alias, char *buff, char *file)
{
- char *wwid;
- int fd, id, unused;
+ int fd, unused;
FILE *f;
if (!alias || *alias == '\0') {
condlog(3, "Cannot find binding for empty alias");
- return NULL;
+ return -1;
}
fd = open_file(file, &unused, BINDINGS_FILE_HEADER);
if (fd < 0)
- return NULL;
+ return -1;
f = fdopen(fd, "r");
if (!f) {
condlog(0, "cannot fdopen on bindings file descriptor : %s",
strerror(errno));
close(fd);
- return NULL;
+ return -1;
}
- id = rlookup_binding(f, &wwid, alias);
- if (id < 0) {
+ rlookup_binding(f, buff, alias);
+ if (!strlen(buff)) {
fclose(f);
- return NULL;
+ return -1;
}
fclose(f);
- return wwid;
+ return 0;
}
Index: multipath-tools-120821/libmultipath/alias.h
===================================================================
--- multipath-tools-120821.orig/libmultipath/alias.h
+++ multipath-tools-120821/libmultipath/alias.h
@@ -9,4 +9,4 @@
char *get_user_friendly_alias(char *wwid, char *file, char *prefix,
int bindings_readonly);
-char *get_user_friendly_wwid(char *alias, char *file);
+int get_user_friendly_wwid(char *alias, char *buff, char *file);
Index: multipath-tools-120821/libmultipath/configure.c
===================================================================
--- multipath-tools-120821.orig/libmultipath/configure.c
+++ multipath-tools-120821/libmultipath/configure.c
@@ -687,21 +687,32 @@ coalesce_paths (struct vectors * vecs, v
return 0;
}
-extern char *
-get_refwwid (char * dev, enum devtypes dev_type, vector pathvec)
+/*
+ * returns:
+ * 0 - success
+ * 1 - failure
+ * 2 - blacklist
+ */
+extern int
+get_refwwid (char * dev, enum devtypes dev_type, vector pathvec, char **wwid)
{
+ int ret = 1;
struct path * pp;
char buff[FILE_NAME_SIZE];
char * refwwid = NULL, tmpwwid[WWID_SIZE];
+ if (!wwid)
+ return 1;
+ *wwid = NULL;
+
if (dev_type == DEV_NONE)
- return NULL;
+ return 1;
if (dev_type == DEV_DEVNODE) {
if (basenamecpy(dev, buff, FILE_NAME_SIZE) == 0) {
condlog(1, "basename failed for '%s' (%s)",
dev, buff);
- return NULL;
+ return 1;
}
pp = find_path_by_dev(pathvec, buff);
@@ -710,14 +721,16 @@ get_refwwid (char * dev, enum devtypes d
if (!udevice) {
condlog(2, "%s: can't get udev device", buff);
- return NULL;
+ return 1;
}
- pp = store_pathinfo(pathvec, conf->hwtable, udevice,
- DI_SYSFS | DI_WWID);
+ ret = store_pathinfo(pathvec, conf->hwtable, udevice,
+ DI_SYSFS | DI_WWID, &pp);
udev_device_unref(udevice);
if (!pp) {
- condlog(0, "%s can't store path info", buff);
- return NULL;
+ if (ret == 1)
+ condlog(0, "%s can't store path info",
+ buff);
+ return ret;
}
}
refwwid = pp->wwid;
@@ -732,14 +745,16 @@ get_refwwid (char * dev, enum devtypes d
if (!udevice) {
condlog(2, "%s: can't get udev device", dev);
- return NULL;
+ return 1;
}
- pp = store_pathinfo(pathvec, conf->hwtable, udevice,
- DI_SYSFS | DI_WWID);
+ ret = store_pathinfo(pathvec, conf->hwtable, udevice,
+ DI_SYSFS | DI_WWID, &pp);
udev_device_unref(udevice);
if (!pp) {
- condlog(0, "%s can't store path info", buff);
- return NULL;
+ if (ret == 1)
+ condlog(0, "%s can't store path info",
+ buff);
+ return ret;
}
}
refwwid = pp->wwid;
@@ -749,17 +764,17 @@ get_refwwid (char * dev, enum devtypes d
if (((dm_get_uuid(dev, tmpwwid)) == 0) && (strlen(tmpwwid))) {
refwwid = tmpwwid;
- goto out;
+ goto check;
}
/*
* may be a binding
*/
- refwwid = get_user_friendly_wwid(dev,
- conf->bindings_file);
-
- if (refwwid)
- return refwwid;
+ if (get_user_friendly_wwid(dev, tmpwwid,
+ conf->bindings_file) == 0) {
+ refwwid = tmpwwid;
+ goto check;
+ }
/*
* or may be an alias
@@ -771,12 +786,21 @@ get_refwwid (char * dev, enum devtypes d
*/
if (!refwwid)
refwwid = dev;
+
+check:
+ if (refwwid && strlen(refwwid)) {
+ if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
+ refwwid) > 0)
+ return 2;
+ }
}
out:
- if (refwwid && strlen(refwwid))
- return STRDUP(refwwid);
+ if (refwwid && strlen(refwwid)) {
+ *wwid = STRDUP(refwwid);
+ return 0;
+ }
- return NULL;
+ return 1;
}
extern int reload_map(struct vectors *vecs, struct multipath *mpp)
Index: multipath-tools-120821/libmultipath/configure.h
===================================================================
--- multipath-tools-120821.orig/libmultipath/configure.h
+++ multipath-tools-120821/libmultipath/configure.h
@@ -27,6 +27,6 @@ int setup_map (struct multipath * mpp, c
int domap (struct multipath * mpp, char * params);
int reinstate_paths (struct multipath *mpp);
int coalesce_paths (struct vectors *vecs, vector curmp, char * refwwid, int force_reload);
-char * get_refwwid (char * dev, enum devtypes dev_type, vector pathvec);
+int get_refwwid (char * dev, enum devtypes dev_type, vector pathvec, char **wwid);
int reload_map(struct vectors *vecs, struct multipath *mpp);
Index: multipath-tools-120821/libmultipath/util.c
===================================================================
--- multipath-tools-120821.orig/libmultipath/util.c
+++ multipath-tools-120821/libmultipath/util.c
@@ -27,7 +27,7 @@ basenamecpy (const char * str1, char * s
if (!str1 || !strlen(str1))
return 0;
- if (strlen(str1) > str2len)
+ if (strlen(str1) >= str2len)
return 0;
if (!str2)
Index: multipath-tools-120821/multipath/main.c
===================================================================
--- multipath-tools-120821.orig/multipath/main.c
+++ multipath-tools-120821/multipath/main.c
@@ -262,7 +262,7 @@ configure (void)
/*
* if we have a blacklisted device parameter, exit early
*/
- if (dev &&
+ if (dev && conf->dev_type == DEV_DEVNODE &&
(filter_devnode(conf->blist_devnode,
conf->elist_devnode, dev) > 0)) {
if (conf->dry_run == 2)
@@ -275,16 +275,16 @@ configure (void)
* failing the translation is fatal (by policy)
*/
if (conf->dev) {
- refwwid = get_refwwid(conf->dev, conf->dev_type, pathvec);
-
+ int failed = get_refwwid(conf->dev, conf->dev_type, pathvec,
+ &refwwid);
if (!refwwid) {
- condlog(3, "scope is nul");
+ if (failed == 2 && conf->dry_run == 2)
+ printf("%s is not a valid multipath device path\n", conf->dev);
+ else
+ condlog(3, "scope is nul");
goto out;
}
condlog(3, "scope limited to %s", refwwid);
- if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
- refwwid) > 0)
- goto out;
if (conf->dry_run == 2) {
if (check_wwids_file(refwwid, 0) == 0){
printf("%s is a valid multipath device path\n", conf->dev);
Index: multipath-tools-120821/multipathd/cli_handlers.c
===================================================================
--- multipath-tools-120821.orig/multipathd/cli_handlers.c
+++ multipath-tools-120821/multipathd/cli_handlers.c
@@ -433,19 +433,18 @@ cli_add_path (void * v, char ** reply, i
udevice = udev_device_new_from_subsystem_sysname(conf->udev,
"block",
param);
- pp = store_pathinfo(vecs->pathvec, conf->hwtable,
- udevice, DI_ALL);
+ r = store_pathinfo(vecs->pathvec, conf->hwtable,
+ udevice, DI_ALL, &pp);
udev_device_unref(udevice);
if (!pp) {
+ if (r == 2)
+ goto blacklisted;
condlog(0, "%s: failed to store path info", param);
return 1;
}
pp->checkint = conf->checkint;
}
- r = ev_add_path(pp, vecs);
- if (r == 2)
- goto blacklisted;
- return r;
+ return ev_add_path(pp, vecs);
blacklisted:
*reply = strdup("blacklisted\n");
*len = strlen(*reply) + 1;
Index: multipath-tools-120821/multipathd/main.c
===================================================================
--- multipath-tools-120821.orig/multipathd/main.c
+++ multipath-tools-120821/multipathd/main.c
@@ -300,7 +300,7 @@ ev_add_map (char * dev, char * alias, st
condlog(2, "%s: devmap %s registered", alias, dev);
return 0;
}
- refwwid = get_refwwid(dev, DEV_DEVMAP, vecs->pathvec);
+ r = get_refwwid(dev, DEV_DEVMAP, vecs->pathvec, &refwwid);
if (refwwid) {
r = coalesce_paths(vecs, NULL, refwwid, 0);
@@ -309,6 +309,8 @@ ev_add_map (char * dev, char * alias, st
if (!r)
condlog(2, "%s: devmap %s added", alias, dev);
+ else if (r == 2)
+ condlog(2, "%s: uev_add_map %s blacklisted", alias, dev);
else
condlog(0, "%s: uev_add_map %s failed", alias, dev);
@@ -374,6 +376,7 @@ static int
uev_add_path (struct uevent *uev, struct vectors * vecs)
{
struct path *pp;
+ int ret;
condlog(2, "%s: add path (uevent)", uev->kernel);
if (strstr(uev->kernel, "..") != NULL) {
@@ -394,8 +397,11 @@ uev_add_path (struct uevent *uev, struct
/*
* get path vital state
*/
- if (!(pp = store_pathinfo(vecs->pathvec, conf->hwtable,
- uev->udev, DI_ALL))) {
+ ret = store_pathinfo(vecs->pathvec, conf->hwtable,
+ uev->udev, DI_ALL, &pp);
+ if (!pp) {
+ if (ret == 2)
+ return 0;
condlog(0, "%s: failed to store path info",
uev->kernel);
return 1;
@@ -403,14 +409,13 @@ uev_add_path (struct uevent *uev, struct
pp->checkint = conf->checkint;
}
- return (ev_add_path(pp, vecs) != 1)? 0 : 1;
+ return ev_add_path(pp, vecs);
}
/*
* returns:
* 0: added
* 1: error
- * 2: blacklisted
*/
int
ev_add_path (struct path * pp, struct vectors * vecs)
@@ -428,13 +433,6 @@ ev_add_path (struct path * pp, struct ve
condlog(0, "%s: failed to get path uid", pp->dev);
goto fail; /* leave path added to pathvec */
}
- if (filter_path(conf, pp) > 0){
- int i = find_slot(vecs->pathvec, (void *)pp);
- if (i != -1)
- vector_del_slot(vecs->pathvec, i);
- free_path(pp);
- return 2;
- }
mpp = pp->mpp = find_mp_by_wwid(vecs->mpvec, pp->wwid);
rescan:
if (mpp) {