This commit is contained in:
parent
a03d4e1ef9
commit
631b272723
45
multipath-tools-adapt-to-new-sysfs-layout
Normal file
45
multipath-tools-adapt-to-new-sysfs-layout
Normal file
@ -0,0 +1,45 @@
|
||||
From b33a53646ba745dca3ef93ca29c45cbef2dfa171 Mon Sep 17 00:00:00 2001
|
||||
From: Hannes Reinecke <hare@suse.de>
|
||||
Date: Tue, 18 Nov 2008 08:29:17 +0100
|
||||
Subject: [PATCH] Adapt to new sysfs layout in uev_discard()
|
||||
|
||||
Later kernel moved the block sysfs entry below the device path,
|
||||
so we have to check for the 'block' directory somewhere in the
|
||||
devpath, not at the beginning.
|
||||
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
||||
---
|
||||
multipathd/main.c | 13 +++++++++----
|
||||
1 files changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index a4b0311..6908902 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -603,14 +603,19 @@ uxsock_trigger (char * str, char ** reply, int * len, void * trigger_data)
|
||||
static int
|
||||
uev_discard(char * devpath)
|
||||
{
|
||||
- char a[10], b[10];
|
||||
+ char a[10], b[10], *c;
|
||||
|
||||
/*
|
||||
* keep only block devices, discard partitions
|
||||
*/
|
||||
- if (sscanf(devpath, "/block/%10s", a) != 1 ||
|
||||
- sscanf(devpath, "/block/%10[^/]/%10s", a, b) == 2) {
|
||||
- condlog(4, "discard event on %s", devpath);
|
||||
+ c = strstr(devpath,"/block");
|
||||
+ if (!c) {
|
||||
+ condlog(3, "discard non-block event on %s", devpath);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ if (sscanf(c, "/block/%10s", a) != 1 ||
|
||||
+ sscanf(c, "/block/%10[^/]/%10s", a, b) == 2) {
|
||||
+ condlog(3, "discard event on %s", c);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
--
|
||||
1.5.3.2
|
||||
|
38
multipath-tools-allow-zero-paths
Normal file
38
multipath-tools-allow-zero-paths
Normal file
@ -0,0 +1,38 @@
|
||||
From 6ebe82d29b759049d1df1cb689f9c35bdaf58808 Mon Sep 17 00:00:00 2001
|
||||
From: Hannes Reinecke <hare@suse.de>
|
||||
Date: Thu, 20 Nov 2008 13:33:10 +0100
|
||||
Subject: [PATCH] Allow zero paths for device-mapper strings
|
||||
|
||||
There is no reason why we shouldn't allow zero paths in the device
|
||||
mapper output.
|
||||
|
||||
References: 435688
|
||||
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
||||
---
|
||||
libmultipath/dmparser.c | 7 ++++---
|
||||
1 files changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/dmparser.c b/libmultipath/dmparser.c
|
||||
index 9441b11..0cef666 100644
|
||||
--- a/libmultipath/dmparser.c
|
||||
+++ b/libmultipath/dmparser.c
|
||||
@@ -187,11 +187,12 @@ disassemble_map (vector pathvec, char * params, struct multipath * mpp)
|
||||
num_pg = atoi(word);
|
||||
FREE(word);
|
||||
|
||||
- if (num_pg > 0 && !mpp->pg)
|
||||
+ if (num_pg > 0 && !mpp->pg) {
|
||||
mpp->pg = vector_alloc();
|
||||
|
||||
- if (!mpp->pg)
|
||||
- return 1;
|
||||
+ if (!mpp->pg)
|
||||
+ return 1;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* first pg to try
|
||||
--
|
||||
1.5.3.2
|
||||
|
94
multipath-tools-always-allocate-alias
Normal file
94
multipath-tools-always-allocate-alias
Normal file
@ -0,0 +1,94 @@
|
||||
From 1532369e0269ddc8bbb295f3cc26f102b247bca0 Mon Sep 17 00:00:00 2001
|
||||
From: Hannes Reinecke <hare@suse.de>
|
||||
Date: Thu, 20 Nov 2008 08:50:10 +0100
|
||||
Subject: [PATCH] Always allocate space for alias
|
||||
|
||||
We should always allocate memory for the alias, this makes freeing
|
||||
up the string less error-prone.
|
||||
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
||||
---
|
||||
libmultipath/devmapper.c | 8 ++++----
|
||||
libmultipath/propsel.c | 6 +++---
|
||||
libmultipath/structs.c | 4 +---
|
||||
3 files changed, 8 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index 92afae7..bc4f9db 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -765,7 +765,7 @@ dm_get_name(char *uuid, char *name)
|
||||
{
|
||||
vector vec;
|
||||
struct multipath *mpp;
|
||||
- int i;
|
||||
+ int i, retval = 0;
|
||||
|
||||
vec = vector_alloc();
|
||||
|
||||
@@ -779,14 +779,14 @@ dm_get_name(char *uuid, char *name)
|
||||
|
||||
vector_foreach_slot(vec, mpp, i) {
|
||||
if (!strcmp(uuid, mpp->wwid)) {
|
||||
- vector_free(vec);
|
||||
strcpy(name, mpp->alias);
|
||||
- return 1;
|
||||
+ retval = 1;
|
||||
}
|
||||
+ free_multipath(mpp, KEEP_PATHS);
|
||||
}
|
||||
|
||||
vector_free(vec);
|
||||
- return 0;
|
||||
+ return retval;
|
||||
}
|
||||
|
||||
int
|
||||
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
|
||||
index 43611ff..5a16182 100644
|
||||
--- a/libmultipath/propsel.c
|
||||
+++ b/libmultipath/propsel.c
|
||||
@@ -159,7 +159,7 @@ extern int
|
||||
select_alias (struct multipath * mp)
|
||||
{
|
||||
if (mp->mpe && mp->mpe->alias)
|
||||
- mp->alias = mp->mpe->alias;
|
||||
+ mp->alias = strdup(mp->mpe->alias);
|
||||
else {
|
||||
mp->alias = NULL;
|
||||
if (conf->user_friendly_names)
|
||||
@@ -175,7 +175,7 @@ select_alias (struct multipath * mp)
|
||||
}
|
||||
}
|
||||
if (mp->alias == NULL)
|
||||
- mp->alias = mp->wwid;
|
||||
+ mp->alias = strdup(mp->wwid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -365,6 +365,6 @@ select_pg_timeout(struct multipath *mp)
|
||||
return 0;
|
||||
}
|
||||
mp->pg_timeout = PGTIMEOUT_UNDEF;
|
||||
- condlog(3, "pg_timeout = NONE (internal default)");
|
||||
+ condlog(3, "%s: pg_timeout = NONE (internal default)", mp->alias);
|
||||
return 0;
|
||||
}
|
||||
diff --git a/libmultipath/structs.c b/libmultipath/structs.c
|
||||
index bb0d9f7..d2bfc2d 100644
|
||||
--- a/libmultipath/structs.c
|
||||
+++ b/libmultipath/structs.c
|
||||
@@ -161,9 +161,7 @@ free_multipath (struct multipath * mpp, int free_paths)
|
||||
|
||||
free_multipath_attributes(mpp);
|
||||
|
||||
- if (mpp->alias &&
|
||||
- (!mpp->mpe || (mpp->mpe && mpp->alias != mpp->mpe->alias)) &&
|
||||
- (mpp->wwid && mpp->alias != mpp->wwid)) {
|
||||
+ if (mpp->alias) {
|
||||
FREE(mpp->alias);
|
||||
mpp->alias = NULL;
|
||||
}
|
||||
--
|
||||
1.5.3.2
|
||||
|
114
multipath-tools-basename-return-value
Normal file
114
multipath-tools-basename-return-value
Normal file
@ -0,0 +1,114 @@
|
||||
From 53c7a13bf5383814a7118607d3b1da41de51c4b1 Mon Sep 17 00:00:00 2001
|
||||
From: Hannes Reinecke <hare@suse.de>
|
||||
Date: Thu, 20 Nov 2008 08:40:59 +0100
|
||||
Subject: [PATCH] Return number of characters written in basename()
|
||||
|
||||
basename() can fail, so we should return the number of
|
||||
characters written to get some error indicator.
|
||||
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
||||
---
|
||||
libmultipath/configure.c | 12 +++++++++---
|
||||
libmultipath/discovery.h | 1 -
|
||||
libmultipath/util.c | 13 +++++++++++--
|
||||
libmultipath/util.h | 2 +-
|
||||
4 files changed, 21 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
|
||||
index 8444ef2..494ea70 100644
|
||||
--- a/libmultipath/configure.c
|
||||
+++ b/libmultipath/configure.c
|
||||
@@ -34,13 +34,14 @@
|
||||
#include "dict.h"
|
||||
#include "alias.h"
|
||||
#include "prio.h"
|
||||
+#include "util.h"
|
||||
|
||||
extern int
|
||||
setup_map (struct multipath * mpp)
|
||||
{
|
||||
struct pathgroup * pgp;
|
||||
int i;
|
||||
-
|
||||
+
|
||||
/*
|
||||
* don't bother if devmap size is unknown
|
||||
*/
|
||||
@@ -579,9 +580,14 @@ get_refwwid (char * dev, enum devtypes dev_type, vector pathvec)
|
||||
return NULL;
|
||||
|
||||
if (dev_type == DEV_DEVNODE) {
|
||||
- basename(dev, buff);
|
||||
+ if (basename(dev, buff) == 0) {
|
||||
+ condlog(1, "basename failed for '%s' (%s)",
|
||||
+ dev, buff);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
pp = find_path_by_dev(pathvec, buff);
|
||||
-
|
||||
+
|
||||
if (!pp) {
|
||||
pp = alloc_path();
|
||||
|
||||
diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h
|
||||
index c7cf7e8..05b1cfe 100644
|
||||
--- a/libmultipath/discovery.h
|
||||
+++ b/libmultipath/discovery.h
|
||||
@@ -27,7 +27,6 @@
|
||||
int sysfs_get_dev (struct sysfs_device * dev, char * buff, size_t len);
|
||||
int path_discovery (vector pathvec, struct config * conf, int flag);
|
||||
|
||||
-void basename (char *, char *);
|
||||
int do_tur (char *);
|
||||
int devt2devname (char *, char *);
|
||||
int pathinfo (struct path *, vector hwtable, int mask);
|
||||
diff --git a/libmultipath/util.c b/libmultipath/util.c
|
||||
index c7fe6b4..3afe7ea 100644
|
||||
--- a/libmultipath/util.c
|
||||
+++ b/libmultipath/util.c
|
||||
@@ -38,10 +38,18 @@ strchop(char *str)
|
||||
str[++i] = '\0';
|
||||
}
|
||||
|
||||
-void
|
||||
+int
|
||||
basename (char * str1, char * str2)
|
||||
{
|
||||
- char *p = str1 + (strlen(str1) - 1);
|
||||
+ char *p;
|
||||
+
|
||||
+ if (!str1 || !strlen(str1))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!str2)
|
||||
+ return 0;
|
||||
+
|
||||
+ p = str1 + (strlen(str1) - 1);
|
||||
|
||||
while (*--p != '/' && p != str1)
|
||||
continue;
|
||||
@@ -50,6 +58,7 @@ basename (char * str1, char * str2)
|
||||
p++;
|
||||
|
||||
strcpy(str2, p);
|
||||
+ return strlen(p);
|
||||
}
|
||||
|
||||
int
|
||||
diff --git a/libmultipath/util.h b/libmultipath/util.h
|
||||
index d0df8aa..14af696 100644
|
||||
--- a/libmultipath/util.h
|
||||
+++ b/libmultipath/util.h
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
int strcmp_chomp(char *, char *);
|
||||
void strchop(char *);
|
||||
-void basename (char * src, char * dst);
|
||||
+int basename (char * src, char * dst);
|
||||
int filepresent (char * run);
|
||||
int get_word (char * sentence, char ** word);
|
||||
size_t strlcpy(char *dst, const char *src, size_t size);
|
||||
--
|
||||
1.5.3.2
|
||||
|
54
multipath-tools-crash-in-update-multipath
Normal file
54
multipath-tools-crash-in-update-multipath
Normal file
@ -0,0 +1,54 @@
|
||||
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
|
||||
index eb7ac03..3903b28 100644
|
||||
--- a/libmultipath/configure.c
|
||||
+++ b/libmultipath/configure.c
|
||||
@@ -114,6 +114,9 @@ pgcmp (struct multipath * mpp, struct multipath * cmpp)
|
||||
struct pathgroup * cpgp;
|
||||
int r = 0;
|
||||
|
||||
+ if (!mpp)
|
||||
+ return 0;
|
||||
+
|
||||
vector_foreach_slot (mpp->pg, pgp, i) {
|
||||
compute_pgid(pgp);
|
||||
|
||||
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
|
||||
index e3cace9..3770566 100644
|
||||
--- a/libmultipath/structs_vec.c
|
||||
+++ b/libmultipath/structs_vec.c
|
||||
@@ -163,6 +163,9 @@ _remove_maps (struct vectors * vecs, int stop_waiter)
|
||||
int i;
|
||||
struct multipath * mpp;
|
||||
|
||||
+ if (!vecs)
|
||||
+ return;
|
||||
+
|
||||
vector_foreach_slot (vecs->mpvec, mpp, i) {
|
||||
_remove_map(mpp, vecs, stop_waiter, 1);
|
||||
i--;
|
||||
@@ -451,6 +454,9 @@ verify_paths(struct multipath * mpp, struct vectors * vecs, vector rpvec)
|
||||
int count = 0;
|
||||
int i, j;
|
||||
|
||||
+ if (!mpp)
|
||||
+ return 0;
|
||||
+
|
||||
vector_foreach_slot (mpp->paths, pp, i) {
|
||||
/*
|
||||
* see if path is in sysfs
|
||||
diff --git a/libmultipath/vector.h b/libmultipath/vector.h
|
||||
index 993ba79..aa9e134 100644
|
||||
--- a/libmultipath/vector.h
|
||||
+++ b/libmultipath/vector.h
|
||||
@@ -36,9 +36,9 @@ typedef struct _vector *vector;
|
||||
#define VECTOR_LAST_SLOT(V) ((V)->slot[((V)->allocated - 1)])
|
||||
|
||||
#define vector_foreach_slot(v,p,i) \
|
||||
- for (i = 0; i < (v)->allocated && ((p) = (v)->slot[i]); i++)
|
||||
+ for (i = 0; (v) && i < (v)->allocated && ((p) = (v)->slot[i]); i++)
|
||||
#define vector_foreach_slot_after(v,p,i) \
|
||||
- for (; i < (v)->allocated && ((p) = (v)->slot[i]); i++)
|
||||
+ for (; (v) && i < (v)->allocated && ((p) = (v)->slot[i]); i++)
|
||||
|
||||
/* Prototypes */
|
||||
extern vector vector_alloc(void);
|
526
multipath-tools-make-params-local
Normal file
526
multipath-tools-make-params-local
Normal file
@ -0,0 +1,526 @@
|
||||
From 28b790ea42f100c74f682f1abea6c33e7d0e3553 Mon Sep 17 00:00:00 2001
|
||||
From: Hannes Reinecke <hare@suse.de>
|
||||
Date: Thu, 20 Nov 2008 12:36:24 +0100
|
||||
Subject: [PATCH] Make 'params' and 'status' local variables
|
||||
|
||||
The 'params' and 'status' fields in the multipath structure are
|
||||
just scratch variables where the output from device-mapper is stored
|
||||
into. And as we call device-mapper quite frequently it really looks
|
||||
not thread-safe as the multipath structure can be accessed from
|
||||
all threads. So better make them local variables to eliminate this
|
||||
problem.
|
||||
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
||||
---
|
||||
libmultipath/configure.c | 30 ++++++++++++++++--------------
|
||||
libmultipath/configure.h | 4 ++--
|
||||
libmultipath/devmapper.c | 12 +++++++-----
|
||||
libmultipath/dmparser.c | 19 +++++++++++--------
|
||||
libmultipath/dmparser.h | 2 +-
|
||||
libmultipath/print.c | 6 +++---
|
||||
libmultipath/print.h | 2 +-
|
||||
libmultipath/structs.h | 2 --
|
||||
libmultipath/structs_vec.c | 20 ++++++++++++++++----
|
||||
libmultipath/waiter.c | 1 +
|
||||
multipath/main.c | 13 +++++++++----
|
||||
multipathd/cli_handlers.c | 6 ++++--
|
||||
multipathd/main.c | 15 +++++++++++----
|
||||
13 files changed, 82 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/configure.c b/libmultipath/configure.c
|
||||
index 494ea70..eb7ac03 100644
|
||||
--- a/libmultipath/configure.c
|
||||
+++ b/libmultipath/configure.c
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "util.h"
|
||||
|
||||
extern int
|
||||
-setup_map (struct multipath * mpp)
|
||||
+setup_map (struct multipath * mpp, char * params, int params_size)
|
||||
{
|
||||
struct pathgroup * pgp;
|
||||
int i;
|
||||
@@ -89,7 +89,7 @@ setup_map (struct multipath * mpp)
|
||||
* transform the mp->pg vector of vectors of paths
|
||||
* into a mp->params strings to feed the device-mapper
|
||||
*/
|
||||
- if (assemble_map(mpp)) {
|
||||
+ if (assemble_map(mpp, params, params_size)) {
|
||||
condlog(0, "%s: problem assembing map", mpp->alias);
|
||||
return 1;
|
||||
}
|
||||
@@ -298,7 +298,7 @@ lock_multipath (struct multipath * mpp, int lock)
|
||||
#define DOMAP_DRY 3
|
||||
|
||||
extern int
|
||||
-domap (struct multipath * mpp)
|
||||
+domap (struct multipath * mpp, char * params)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
@@ -337,25 +337,25 @@ domap (struct multipath * mpp)
|
||||
break;
|
||||
}
|
||||
|
||||
- r = dm_addmap_create(mpp->alias, mpp->params, mpp->size,
|
||||
+ r = dm_addmap_create(mpp->alias, params, mpp->size,
|
||||
mpp->wwid);
|
||||
|
||||
if (!r)
|
||||
- r = dm_addmap_create_ro(mpp->alias, mpp->params,
|
||||
+ r = dm_addmap_create_ro(mpp->alias, params,
|
||||
mpp->size, mpp->wwid);
|
||||
|
||||
lock_multipath(mpp, 0);
|
||||
break;
|
||||
|
||||
case ACT_RELOAD:
|
||||
- r = (dm_addmap_reload(mpp->alias, mpp->params, mpp->size, NULL)
|
||||
+ r = (dm_addmap_reload(mpp->alias, params, mpp->size, NULL)
|
||||
&& dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, 1));
|
||||
break;
|
||||
|
||||
case ACT_RESIZE:
|
||||
- r = dm_addmap_reload(mpp->alias, mpp->params, mpp->size, NULL);
|
||||
+ r = dm_addmap_reload(mpp->alias, params, mpp->size, NULL);
|
||||
if (!r)
|
||||
- r = dm_addmap_reload_ro(mpp->alias, mpp->params,
|
||||
+ r = dm_addmap_reload_ro(mpp->alias, params,
|
||||
mpp->size, NULL);
|
||||
if (r)
|
||||
r = dm_simplecmd(DM_DEVICE_RESUME, mpp->alias, 0);
|
||||
@@ -383,7 +383,7 @@ domap (struct multipath * mpp)
|
||||
/* multipath daemon mode */
|
||||
mpp->stat_map_loads++;
|
||||
condlog(2, "%s: load table [0 %llu %s %s]", mpp->alias,
|
||||
- mpp->size, TGT_MPATH, mpp->params);
|
||||
+ mpp->size, TGT_MPATH, params);
|
||||
/*
|
||||
* Required action is over, reset for the stateful daemon
|
||||
*/
|
||||
@@ -422,6 +422,7 @@ coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, int force_r
|
||||
int r = 1;
|
||||
int k, i;
|
||||
char empty_buff[WWID_SIZE];
|
||||
+ char params[PARAMS_SIZE];
|
||||
struct multipath * mpp;
|
||||
struct path * pp1;
|
||||
struct path * pp2;
|
||||
@@ -493,8 +494,9 @@ coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, int force_r
|
||||
mpp->action = ACT_REJECT;
|
||||
}
|
||||
verify_paths(mpp, vecs, NULL);
|
||||
-
|
||||
- if (setup_map(mpp)) {
|
||||
+
|
||||
+ params[0] = '\0';
|
||||
+ if (setup_map(mpp, params, PARAMS_SIZE)) {
|
||||
remove_map(mpp, vecs, 0);
|
||||
continue;
|
||||
}
|
||||
@@ -502,7 +504,7 @@ coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid, int force_r
|
||||
if (mpp->action == ACT_UNDEF)
|
||||
select_action(mpp, curmp, force_reload);
|
||||
|
||||
- r = domap(mpp);
|
||||
+ r = domap(mpp, params);
|
||||
|
||||
if (r == DOMAP_FAIL || r == DOMAP_RETRY) {
|
||||
condlog(3, "%s: domap (%u) failure "
|
||||
@@ -610,7 +612,7 @@ get_refwwid (char * dev, enum devtypes dev_type, vector pathvec)
|
||||
|
||||
if (dev_type == DEV_DEVT) {
|
||||
pp = find_path_by_devt(pathvec, dev);
|
||||
-
|
||||
+
|
||||
if (!pp) {
|
||||
if (devt2devname(buff, dev))
|
||||
return NULL;
|
||||
@@ -624,7 +626,7 @@ get_refwwid (char * dev, enum devtypes dev_type, vector pathvec)
|
||||
|
||||
if (pathinfo(pp, conf->hwtable, DI_SYSFS | DI_WWID))
|
||||
return NULL;
|
||||
-
|
||||
+
|
||||
if (store_path(pathvec, pp)) {
|
||||
free_path(pp);
|
||||
return NULL;
|
||||
diff --git a/libmultipath/configure.h b/libmultipath/configure.h
|
||||
index 25891ba..ec2800d 100644
|
||||
--- a/libmultipath/configure.h
|
||||
+++ b/libmultipath/configure.h
|
||||
@@ -23,8 +23,8 @@ enum actions {
|
||||
#define FLUSH_ONE 1
|
||||
#define FLUSH_ALL 2
|
||||
|
||||
-int setup_map (struct multipath * mpp);
|
||||
-int domap (struct multipath * mpp);
|
||||
+int setup_map (struct multipath * mpp, char * params, int params_size);
|
||||
+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);
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index cde98eb..a7ab41f 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -206,6 +206,8 @@ dm_addmap (int task, const char *name, const char *target,
|
||||
goto freeout;
|
||||
}
|
||||
|
||||
+ condlog(4, "%s: addmap [0 %llu %s %s]\n", name, size, target, params);
|
||||
+
|
||||
dm_task_no_open_count(dmt);
|
||||
|
||||
r = dm_task_run (dmt);
|
||||
@@ -323,7 +325,10 @@ dm_get_map(char * name, unsigned long long * size, char * outparams)
|
||||
if (size)
|
||||
*size = length;
|
||||
|
||||
- if (snprintf(outparams, PARAMS_SIZE, "%s", params) <= PARAMS_SIZE)
|
||||
+ if (outparams) {
|
||||
+ if (snprintf(outparams, PARAMS_SIZE, "%s", params) <= PARAMS_SIZE)
|
||||
+ r = 0;
|
||||
+ } else
|
||||
r = 0;
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
@@ -756,10 +761,7 @@ dm_get_maps (vector mp)
|
||||
goto out1;
|
||||
|
||||
if (info > 0) {
|
||||
- if (dm_get_map(names->name, &mpp->size, mpp->params))
|
||||
- goto out1;
|
||||
-
|
||||
- if (dm_get_status(names->name, mpp->status))
|
||||
+ if (dm_get_map(names->name, &mpp->size, NULL))
|
||||
goto out1;
|
||||
|
||||
dm_get_uuid(names->name, mpp->wwid);
|
||||
diff --git a/libmultipath/dmparser.c b/libmultipath/dmparser.c
|
||||
index d1face5..9441b11 100644
|
||||
--- a/libmultipath/dmparser.c
|
||||
+++ b/libmultipath/dmparser.c
|
||||
@@ -47,7 +47,7 @@ merge_words (char ** dst, char * word, int space)
|
||||
* Transforms the path group vector into a proper device map string
|
||||
*/
|
||||
int
|
||||
-assemble_map (struct multipath * mp)
|
||||
+assemble_map (struct multipath * mp, char * params, int len)
|
||||
{
|
||||
int i, j;
|
||||
int shift, freechar;
|
||||
@@ -57,15 +57,15 @@ assemble_map (struct multipath * mp)
|
||||
struct path * pp;
|
||||
|
||||
minio = mp->minio;
|
||||
- p = mp->params;
|
||||
- freechar = sizeof(mp->params);
|
||||
+ p = params;
|
||||
+ freechar = len;
|
||||
|
||||
shift = snprintf(p, freechar, "%s %s %i %i",
|
||||
mp->features, mp->hwhandler,
|
||||
VECTOR_SIZE(mp->pg), mp->bestpg);
|
||||
|
||||
if (shift >= freechar) {
|
||||
- fprintf(stderr, "mp->params too small\n");
|
||||
+ condlog(0, "%s: params too small\n", mp->alias);
|
||||
return 1;
|
||||
}
|
||||
p += shift;
|
||||
@@ -76,7 +76,7 @@ assemble_map (struct multipath * mp)
|
||||
shift = snprintf(p, freechar, " %s %i 1", mp->selector,
|
||||
VECTOR_SIZE(pgp->paths));
|
||||
if (shift >= freechar) {
|
||||
- fprintf(stderr, "mp->params too small\n");
|
||||
+ condlog(0, "%s: params too small\n", mp->alias);
|
||||
return 1;
|
||||
}
|
||||
p += shift;
|
||||
@@ -88,11 +88,14 @@ assemble_map (struct multipath * mp)
|
||||
if (mp->rr_weight == RR_WEIGHT_PRIO
|
||||
&& pp->priority > 0)
|
||||
tmp_minio = minio * pp->priority;
|
||||
-
|
||||
+ if (!strlen(pp->dev_t) ) {
|
||||
+ condlog(0, "dev_t not set for '%s'\n", pp->dev);
|
||||
+ return 1;
|
||||
+ }
|
||||
shift = snprintf(p, freechar, " %s %d",
|
||||
pp->dev_t, tmp_minio);
|
||||
if (shift >= freechar) {
|
||||
- fprintf(stderr, "mp->params too small\n");
|
||||
+ condlog(0, "%s: params too small\n", mp->alias);
|
||||
return 1;
|
||||
}
|
||||
p += shift;
|
||||
@@ -100,7 +103,7 @@ assemble_map (struct multipath * mp)
|
||||
}
|
||||
}
|
||||
if (freechar < 1) {
|
||||
- fprintf(stderr, "mp->params too small\n");
|
||||
+ condlog(0, "%s: params too small\n", mp->alias);
|
||||
return 1;
|
||||
}
|
||||
snprintf(p, 1, "\n");
|
||||
diff --git a/libmultipath/dmparser.h b/libmultipath/dmparser.h
|
||||
index bf4b2c3..1b45df0 100644
|
||||
--- a/libmultipath/dmparser.h
|
||||
+++ b/libmultipath/dmparser.h
|
||||
@@ -1,3 +1,3 @@
|
||||
-int assemble_map (struct multipath *);
|
||||
+int assemble_map (struct multipath *, char *, int);
|
||||
int disassemble_map (vector, char *, struct multipath *);
|
||||
int disassemble_status (char *, struct multipath *);
|
||||
diff --git a/libmultipath/print.c b/libmultipath/print.c
|
||||
index 7467411..9dea392 100644
|
||||
--- a/libmultipath/print.c
|
||||
+++ b/libmultipath/print.c
|
||||
@@ -1276,11 +1276,11 @@ print_pathgroup (struct pathgroup * pgp, char * style)
|
||||
}
|
||||
|
||||
extern void
|
||||
-print_map (struct multipath * mpp)
|
||||
+print_map (struct multipath * mpp, char * params)
|
||||
{
|
||||
- if (mpp->size && mpp->params)
|
||||
+ if (mpp->size && params)
|
||||
printf("0 %llu %s %s\n",
|
||||
- mpp->size, TGT_MPATH, mpp->params);
|
||||
+ mpp->size, TGT_MPATH, params);
|
||||
return;
|
||||
}
|
||||
|
||||
diff --git a/libmultipath/print.h b/libmultipath/print.h
|
||||
index a8be408..5fe826b 100644
|
||||
--- a/libmultipath/print.h
|
||||
+++ b/libmultipath/print.h
|
||||
@@ -54,7 +54,7 @@ void print_multipath_topology (struct multipath * mpp, int verbosity);
|
||||
void print_path (struct path * pp, char * style);
|
||||
void print_multipath (struct multipath * mpp, char * style);
|
||||
void print_pathgroup (struct pathgroup * pgp, char * style);
|
||||
-void print_map (struct multipath * mpp);
|
||||
+void print_map (struct multipath * mpp, char * params);
|
||||
void print_all_paths (vector pathvec, int banner);
|
||||
void print_all_paths_custo (vector pathvec, int banner, char *fmt);
|
||||
void print_hwtable (vector hwtable);
|
||||
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||
index 85d5109..658d6b2 100644
|
||||
--- a/libmultipath/structs.h
|
||||
+++ b/libmultipath/structs.h
|
||||
@@ -151,8 +151,6 @@ struct multipath {
|
||||
unsigned long long size;
|
||||
vector paths;
|
||||
vector pg;
|
||||
- char params[PARAMS_SIZE];
|
||||
- char status[PARAMS_SIZE];
|
||||
struct dm_info * dmi;
|
||||
|
||||
/* configlet pointers */
|
||||
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
|
||||
index 17cafd1..e3cace9 100644
|
||||
--- a/libmultipath/structs_vec.c
|
||||
+++ b/libmultipath/structs_vec.c
|
||||
@@ -237,14 +237,20 @@ extract_hwe_from_path(struct multipath * mpp)
|
||||
static int
|
||||
update_multipath_table (struct multipath *mpp, vector pathvec)
|
||||
{
|
||||
+ char params[PARAMS_SIZE] = {0};
|
||||
+
|
||||
if (!mpp)
|
||||
return 1;
|
||||
|
||||
- if (dm_get_map(mpp->alias, &mpp->size, mpp->params))
|
||||
+ if (dm_get_map(mpp->alias, &mpp->size, params)) {
|
||||
+ condlog(3, "%s: cannot get map", mpp->alias);
|
||||
return 1;
|
||||
+ }
|
||||
|
||||
- if (disassemble_map(pathvec, mpp->params, mpp))
|
||||
+ if (disassemble_map(pathvec, params, mpp)) {
|
||||
+ condlog(3, "%s: cannot disassemble map", mpp->alias);
|
||||
return 1;
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -252,14 +258,20 @@ update_multipath_table (struct multipath *mpp, vector pathvec)
|
||||
static int
|
||||
update_multipath_status (struct multipath *mpp)
|
||||
{
|
||||
+ char status[PARAMS_SIZE] = {0};
|
||||
+
|
||||
if (!mpp)
|
||||
return 1;
|
||||
|
||||
- if(dm_get_status(mpp->alias, mpp->status))
|
||||
+ if (dm_get_status(mpp->alias, status)) {
|
||||
+ condlog(3, "%s: cannot get status", mpp->alias);
|
||||
return 1;
|
||||
+ }
|
||||
|
||||
- if (disassemble_status(mpp->status, mpp))
|
||||
+ if (disassemble_status(status, mpp)) {
|
||||
+ condlog(3, "%s: cannot disassemble status", mpp->alias);
|
||||
return 1;
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/libmultipath/waiter.c b/libmultipath/waiter.c
|
||||
index 54cd19f..530180f 100644
|
||||
--- a/libmultipath/waiter.c
|
||||
+++ b/libmultipath/waiter.c
|
||||
@@ -26,6 +26,7 @@ struct event_thread *alloc_waiter (void)
|
||||
struct event_thread *wp;
|
||||
|
||||
wp = (struct event_thread *)MALLOC(sizeof(struct event_thread));
|
||||
+ memset(wp, 0, sizeof(struct event_thread));
|
||||
|
||||
return wp;
|
||||
}
|
||||
diff --git a/multipath/main.c b/multipath/main.c
|
||||
index 60244a5..ffa6eb5 100644
|
||||
--- a/multipath/main.c
|
||||
+++ b/multipath/main.c
|
||||
@@ -158,6 +158,7 @@ get_dm_mpvec (vector curmp, vector pathvec, char * refwwid)
|
||||
{
|
||||
int i;
|
||||
struct multipath * mpp;
|
||||
+ char params[PARAMS_SIZE], status[PARAMS_SIZE];
|
||||
|
||||
if (dm_get_maps(curmp))
|
||||
return 1;
|
||||
@@ -175,10 +176,12 @@ get_dm_mpvec (vector curmp, vector pathvec, char * refwwid)
|
||||
continue;
|
||||
}
|
||||
|
||||
- condlog(3, "params = %s", mpp->params);
|
||||
- condlog(3, "status = %s", mpp->status);
|
||||
+ dm_get_map(mpp->alias, &mpp->size, params);
|
||||
+ condlog(3, "params = %s", params);
|
||||
+ dm_get_status(mpp->alias, status);
|
||||
+ condlog(3, "status = %s", status);
|
||||
|
||||
- disassemble_map(pathvec, mpp->params, mpp);
|
||||
+ disassemble_map(pathvec, params, mpp);
|
||||
|
||||
/*
|
||||
* disassemble_map() can add new paths to pathvec.
|
||||
@@ -191,7 +194,7 @@ get_dm_mpvec (vector curmp, vector pathvec, char * refwwid)
|
||||
if (conf->list > 1)
|
||||
mpp->bestpg = select_path_group(mpp);
|
||||
|
||||
- disassemble_status(mpp->status, mpp);
|
||||
+ disassemble_status(status, mpp);
|
||||
|
||||
if (conf->list)
|
||||
print_multipath_topology(mpp, conf->verbosity);
|
||||
@@ -495,6 +498,8 @@ out:
|
||||
sysfs_cleanup();
|
||||
dm_lib_release();
|
||||
dm_lib_exit();
|
||||
+ cleanup_prio();
|
||||
+ cleanup_checkers();
|
||||
|
||||
/*
|
||||
* Freeing config must be done after dm_lib_exit(), because
|
||||
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||
index f9b0da4..4f639b6 100644
|
||||
--- a/multipathd/cli_handlers.c
|
||||
+++ b/multipathd/cli_handlers.c
|
||||
@@ -463,11 +463,13 @@ out:
|
||||
int resize_map(struct multipath *mpp, unsigned long long size,
|
||||
struct vectors * vecs)
|
||||
{
|
||||
+ char params[PARAMS_SIZE] = {0};
|
||||
+
|
||||
mpp->size = size;
|
||||
update_mpp_paths(mpp, vecs->pathvec);
|
||||
- setup_map(mpp);
|
||||
+ setup_map(mpp, params, PARAMS_SIZE);
|
||||
mpp->action = ACT_RESIZE;
|
||||
- if (domap(mpp) <= 0) {
|
||||
+ if (domap(mpp, params) <= 0) {
|
||||
condlog(0, "%s: failed to resize map : %s", mpp->alias,
|
||||
strerror(errno));
|
||||
return 1;
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index bb396ec..444494e 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -158,6 +158,8 @@ sync_map_state(struct multipath *mpp)
|
||||
if (!mpp->pg)
|
||||
return;
|
||||
|
||||
+ condlog(5, "%s: sync map state", mpp->alias);
|
||||
+
|
||||
vector_foreach_slot (mpp->pg, pgp, i){
|
||||
vector_foreach_slot (pgp->paths, pp, j){
|
||||
if (pp->state == PATH_UNCHECKED ||
|
||||
@@ -355,6 +357,7 @@ ev_add_path (char * devname, struct vectors * vecs)
|
||||
struct multipath * mpp;
|
||||
struct path * pp;
|
||||
char empty_buff[WWID_SIZE] = {0};
|
||||
+ char params[PARAMS_SIZE] = {0};
|
||||
|
||||
pp = find_path_by_dev(vecs->pathvec, devname);
|
||||
|
||||
@@ -409,7 +412,7 @@ rescan:
|
||||
/*
|
||||
* push the map to the device-mapper
|
||||
*/
|
||||
- if (setup_map(mpp)) {
|
||||
+ if (setup_map(mpp, params, PARAMS_SIZE)) {
|
||||
condlog(0, "%s: failed to setup map for addition of new "
|
||||
"path %s", mpp->alias, devname);
|
||||
goto out;
|
||||
@@ -417,7 +420,7 @@ rescan:
|
||||
/*
|
||||
* reload the map for the multipath mapped device
|
||||
*/
|
||||
- if (domap(mpp) <= 0) {
|
||||
+ if (domap(mpp, params) <= 0) {
|
||||
condlog(0, "%s: failed in domap for addition of new "
|
||||
"path %s", mpp->alias, devname);
|
||||
/*
|
||||
@@ -480,6 +483,7 @@ ev_remove_path (char * devname, struct vectors * vecs)
|
||||
struct multipath * mpp;
|
||||
struct path * pp;
|
||||
int i, retval = 0;
|
||||
+ char params[PARAMS_SIZE] = {0};
|
||||
|
||||
pp = find_path_by_dev(vecs->pathvec, devname);
|
||||
|
||||
@@ -526,7 +530,7 @@ ev_remove_path (char * devname, struct vectors * vecs)
|
||||
*/
|
||||
}
|
||||
|
||||
- if (setup_map(mpp)) {
|
||||
+ if (setup_map(mpp, params, PARAMS_SIZE)) {
|
||||
condlog(0, "%s: failed to setup map for"
|
||||
" removal of path %s", mpp->alias,
|
||||
devname);
|
||||
@@ -536,7 +540,7 @@ ev_remove_path (char * devname, struct vectors * vecs)
|
||||
* reload the map
|
||||
*/
|
||||
mpp->action = ACT_RELOAD;
|
||||
- if (domap(mpp) <= 0) {
|
||||
+ if (domap(mpp, params) <= 0) {
|
||||
condlog(0, "%s: failed in domap for "
|
||||
"removal of path %s",
|
||||
mpp->alias, devname);
|
||||
@@ -1395,6 +1399,9 @@ child (void * param)
|
||||
cleanup_checkers();
|
||||
cleanup_prio();
|
||||
|
||||
+ cleanup_checkers();
|
||||
+ cleanup_prio();
|
||||
+
|
||||
condlog(2, "--------shut down-------");
|
||||
|
||||
if (logsink)
|
||||
--
|
||||
1.5.3.2
|
||||
|
529
multipath-tools-prio-weightedpath
Normal file
529
multipath-tools-prio-weightedpath
Normal file
@ -0,0 +1,529 @@
|
||||
commit 86bc28e5702babadf73a1c4395870da370efa257
|
||||
Author: Hannes Reinecke <hare@suse.de>
|
||||
Date: Fri Nov 21 14:03:38 2008 +0100
|
||||
|
||||
Static Load balancing prioritizer
|
||||
|
||||
'Weighted path' is a new path prioritizer for device mapper
|
||||
multipath, where specific paths and the corresponding priority
|
||||
values can be provided as arguments.
|
||||
This prioritizer assigns the priority value provided in the
|
||||
configuration file based on the comparison made between the
|
||||
specified paths and the path instance for which this is called.
|
||||
Paths can be specified as a regular expression of devname
|
||||
of the path or as hbtl information of the path.
|
||||
|
||||
Syntax:
|
||||
weightedpath <hbtl|devname> <regex1> <prio1> <regex2> <prio2> ...
|
||||
|
||||
Examples:
|
||||
prio "weightedpath hbtl 1:.:.:. 2 4:.:.:. 4" #All paths through SCSI 'H' as
|
||||
'1' will take prio 2 and all paths with SCSI 'H' as 4 will take prio as 4.
|
||||
|
||||
prio "weightedpath devname sda$ 10 sde$ 20" #Path sda takes prio 10 and
|
||||
path sde takes prio 20. can be provided in multipath section.
|
||||
|
||||
This prioritizer allows user to set static load balancing
|
||||
for devices. Useful when user has prior knowledge of path
|
||||
performance difference or unavailability of certain paths.
|
||||
|
||||
References: 441007
|
||||
|
||||
Signed-off-by: Vijayakumar Balasubramanian <vijaykumar@hp.com>
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
||||
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index 908156d..83da6e7 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -207,6 +207,12 @@ free_mpe (struct mpentry * mpe)
|
||||
if (mpe->alias)
|
||||
FREE(mpe->alias);
|
||||
|
||||
+ if (mpe->prio_name)
|
||||
+ FREE(mpe->prio_name);
|
||||
+
|
||||
+ if (mpe->prio_arg)
|
||||
+ FREE(mpe->prio_arg);
|
||||
+
|
||||
FREE(mpe);
|
||||
}
|
||||
|
||||
@@ -291,6 +297,7 @@ merge_hwe (struct hwentry * hwe1, struct hwentry * hwe2)
|
||||
merge_str(selector);
|
||||
merge_str(checker_name);
|
||||
merge_str(prio_name);
|
||||
+ merge_str(prio_arg);
|
||||
merge_str(bl_product);
|
||||
merge_num(pgpolicy);
|
||||
merge_num(pgfailback);
|
||||
@@ -339,6 +346,9 @@ store_hwe (vector hwtable, struct hwentry * dhwe)
|
||||
if (dhwe->prio_name && !(hwe->prio_name = set_param_str(dhwe->prio_name)))
|
||||
goto out;
|
||||
|
||||
+ if (dhwe->prio_arg && !(hwe->prio_arg = set_param_str(dhwe->prio_arg)))
|
||||
+ goto out;
|
||||
+
|
||||
hwe->pgpolicy = dhwe->pgpolicy;
|
||||
hwe->pgfailback = dhwe->pgfailback;
|
||||
hwe->rr_weight = dhwe->rr_weight;
|
||||
@@ -559,8 +569,10 @@ load_config (char * file)
|
||||
!conf->hwhandler || !conf->bindings_file)
|
||||
goto out;
|
||||
|
||||
- if (!conf->prio_name)
|
||||
+ if (!conf->prio_name) {
|
||||
conf->prio_name = set_default(DEFAULT_PRIO);
|
||||
+ conf->prio_arg = NULL;
|
||||
+ }
|
||||
|
||||
if (!conf->checker_name)
|
||||
conf->checker_name = set_default(DEFAULT_CHECKER);
|
||||
diff --git a/libmultipath/config.h b/libmultipath/config.h
|
||||
index fb917f4..fc0e22d 100644
|
||||
--- a/libmultipath/config.h
|
||||
+++ b/libmultipath/config.h
|
||||
@@ -21,6 +21,7 @@ struct hwentry {
|
||||
char * selector;
|
||||
char * checker_name;
|
||||
char * prio_name;
|
||||
+ char * prio_arg;
|
||||
|
||||
int pgpolicy;
|
||||
int pgfailback;
|
||||
@@ -37,6 +38,8 @@ struct mpentry {
|
||||
char * getuid;
|
||||
char * selector;
|
||||
|
||||
+ char * prio_name;
|
||||
+ char * prio_arg;
|
||||
int pgpolicy;
|
||||
int pgfailback;
|
||||
int rr_weight;
|
||||
@@ -75,6 +78,7 @@ struct config {
|
||||
char * hwhandler;
|
||||
char * bindings_file;
|
||||
char * prio_name;
|
||||
+ char * prio_arg;
|
||||
char * checker_name;
|
||||
|
||||
vector keywords;
|
||||
diff --git a/libmultipath/dict.c b/libmultipath/dict.c
|
||||
index 5794b11..9ba3961 100644
|
||||
--- a/libmultipath/dict.c
|
||||
+++ b/libmultipath/dict.c
|
||||
@@ -4,6 +4,7 @@
|
||||
* Copyright (c) 2005 Benjamin Marzinski, Redhat
|
||||
* Copyright (c) 2005 Kiyoshi Ueda, NEC
|
||||
*/
|
||||
+#include <string.h>
|
||||
#include "checkers.h"
|
||||
#include "vector.h"
|
||||
#include "hwtable.h"
|
||||
@@ -106,11 +107,26 @@ def_getuid_callout_handler(vector strvec)
|
||||
static int
|
||||
def_prio_handler(vector strvec)
|
||||
{
|
||||
- conf->prio_name = set_value(strvec);
|
||||
+ char *buff, *result, *temp;
|
||||
+ char split_char[] = " \t";
|
||||
|
||||
- if (!conf->prio_name)
|
||||
+ buff = set_value(strvec);
|
||||
+ if (!buff)
|
||||
return 1;
|
||||
+ temp = buff;
|
||||
+
|
||||
+ while ((result = strsep(&temp, split_char))) {
|
||||
+ if (prio_lookup(result)) {
|
||||
+ conf->prio_name = STRDUP(result);
|
||||
+ if (temp)
|
||||
+ conf->prio_arg = STRDUP(temp);
|
||||
+ else
|
||||
+ conf->prio_arg = NULL;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
+ FREE(buff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -613,15 +629,29 @@ static int
|
||||
hw_prio_handler(vector strvec)
|
||||
{
|
||||
struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
|
||||
+ char *buff, *result, *temp;
|
||||
+ char split_char[] = " \t";
|
||||
|
||||
if (!hwe)
|
||||
return 1;
|
||||
|
||||
- hwe->prio_name = set_value(strvec);
|
||||
-
|
||||
- if (!hwe->prio_name)
|
||||
+ buff = set_value(strvec);
|
||||
+ if (!buff)
|
||||
return 1;
|
||||
+ temp = buff;
|
||||
+
|
||||
+ while ((result = strsep(&temp, split_char))) {
|
||||
+ if (prio_lookup(result)) {
|
||||
+ conf->prio_name = STRDUP(result);
|
||||
+ if (temp)
|
||||
+ conf->prio_arg = STRDUP(temp);
|
||||
+ else
|
||||
+ conf->prio_arg = NULL;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
+ FREE(buff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -967,6 +997,38 @@ mp_pg_timeout_handler(vector strvec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+mp_prio_handler (vector strvec)
|
||||
+{
|
||||
+ struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
|
||||
+ char *buff, *result, *temp;
|
||||
+ char split_char[] = " \t";
|
||||
+
|
||||
+ if (!mpe)
|
||||
+ return 1;
|
||||
+
|
||||
+ buff = set_value(strvec);
|
||||
+
|
||||
+ if (!buff)
|
||||
+ return 1;
|
||||
+
|
||||
+ temp = buff;
|
||||
+
|
||||
+ while ((result = strsep(&temp, split_char))) {
|
||||
+ if (prio_lookup(result)) {
|
||||
+ mpe->prio_name = STRDUP(result);
|
||||
+ if (temp)
|
||||
+ mpe->prio_arg = STRDUP(temp);
|
||||
+ else
|
||||
+ mpe->prio_arg = NULL;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ FREE(buff);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* config file keywords printing
|
||||
*/
|
||||
@@ -1102,6 +1164,17 @@ snprint_mp_pg_timeout (char * buff, int len, void * data)
|
||||
}
|
||||
|
||||
static int
|
||||
+snprint_mp_prio(char * buff, int len, void * data)
|
||||
+{
|
||||
+ struct mpentry * mpe = (struct mpentry *)data;
|
||||
+
|
||||
+ if (!mpe->prio_name)
|
||||
+ return 0;
|
||||
+
|
||||
+ return snprintf(buff, len, "%s", mpe->prio_name);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
snprint_hw_vendor (char * buff, int len, void * data)
|
||||
{
|
||||
struct hwentry * hwe = (struct hwentry *)data;
|
||||
@@ -1672,6 +1745,7 @@ init_keywords(void)
|
||||
install_keyword("alias", &alias_handler, &snprint_mp_alias);
|
||||
install_keyword("path_grouping_policy", &mp_pgpolicy_handler, &snprint_mp_path_grouping_policy);
|
||||
install_keyword("path_selector", &mp_selector_handler, &snprint_mp_selector);
|
||||
+ install_keyword("prio", &mp_prio_handler, &snprint_mp_prio);
|
||||
install_keyword("failback", &mp_failback_handler, &snprint_mp_failback);
|
||||
install_keyword("rr_weight", &mp_weight_handler, &snprint_mp_rr_weight);
|
||||
install_keyword("no_path_retry", &mp_no_path_retry_handler, &snprint_mp_no_path_retry);
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 56186bd..c4a53ab 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -784,8 +784,11 @@ pathinfo (struct path *pp, vector hwtable, int mask)
|
||||
* been successfully obtained before.
|
||||
*/
|
||||
if (mask & DI_PRIO &&
|
||||
- (pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF))
|
||||
+ (pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF)) {
|
||||
+ if (!strlen(pp->wwid))
|
||||
+ get_uid(pp);
|
||||
get_prio(pp);
|
||||
+ }
|
||||
|
||||
if (mask & DI_WWID && !strlen(pp->wwid))
|
||||
get_uid(pp);
|
||||
diff --git a/libmultipath/prio.h b/libmultipath/prio.h
|
||||
index deef02d..1d00725 100644
|
||||
--- a/libmultipath/prio.h
|
||||
+++ b/libmultipath/prio.h
|
||||
@@ -24,6 +24,7 @@
|
||||
#define PRIO_ONTAP "ontap"
|
||||
#define PRIO_RANDOM "random"
|
||||
#define PRIO_RDAC "rdac"
|
||||
+#define PRIO_WEIGHTED_PATH "weightedpath"
|
||||
|
||||
/*
|
||||
* Value used to mark the fact prio was not defined
|
||||
diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile
|
||||
index df42145..a569321 100644
|
||||
--- a/libmultipath/prioritizers/Makefile
|
||||
+++ b/libmultipath/prioritizers/Makefile
|
||||
@@ -12,7 +12,8 @@ LIBS = \
|
||||
libpriordac.so \
|
||||
libprioalua.so \
|
||||
libprioontap.so \
|
||||
- libpriohds.so
|
||||
+ libpriohds.so \
|
||||
+ libprioweightedpath.so
|
||||
|
||||
CFLAGS += -I..
|
||||
|
||||
diff --git a/libmultipath/prioritizers/weightedpath.c b/libmultipath/prioritizers/weightedpath.c
|
||||
new file mode 100644
|
||||
index 0000000..d04d91e
|
||||
--- /dev/null
|
||||
+++ b/libmultipath/prioritizers/weightedpath.c
|
||||
@@ -0,0 +1,99 @@
|
||||
+/*
|
||||
+ *
|
||||
+ * (C) Copyright 2008 Hewlett-Packard Development Company, L.P
|
||||
+ *
|
||||
+ * This file is released under the GPL
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * Prioritizer for device mapper multipath, where specific paths and the
|
||||
+ * corresponding priority values are provided as arguments.
|
||||
+ *
|
||||
+ * This prioritizer assigns the priority value provided in the configuration
|
||||
+ * file based on the comparison made between the specified paths and the path
|
||||
+ * instance for which this is called.
|
||||
+ * Paths can be specified as a regular expression of devname of the path or
|
||||
+ * as hbtl information of the path.
|
||||
+ *
|
||||
+ * Examples:
|
||||
+ * prio "weightedpath hbtl 1:.:.:. 2 4:.:.:. 4"
|
||||
+ * prio "weightedpath devname sda 10 sde 20"
|
||||
+ *
|
||||
+ * Returns zero as the default priority.
|
||||
+ */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#include <prio.h>
|
||||
+#include "weightedpath.h"
|
||||
+#include <config.h>
|
||||
+#include <structs.h>
|
||||
+#include <memory.h>
|
||||
+#include <debug.h>
|
||||
+#include <regex.h>
|
||||
+
|
||||
+char *get_next_string(char **temp, char *split_char)
|
||||
+{
|
||||
+ char *token = NULL;
|
||||
+ token = strsep(temp, split_char);
|
||||
+ while (token != NULL && !strcmp(token, ""))
|
||||
+ token = strsep(temp, split_char);
|
||||
+ return token;
|
||||
+}
|
||||
+
|
||||
+/* main priority routine */
|
||||
+int prio_path_weight(struct path *pp)
|
||||
+{
|
||||
+ char path[FILE_NAME_SIZE];
|
||||
+ char *arg;
|
||||
+ char *temp, *regex, *prio;
|
||||
+ char split_char[] = " \t";
|
||||
+ int priority = DEFAULT_PRIORITY, path_found = 0;
|
||||
+ regex_t pathe;
|
||||
+
|
||||
+ /* Return default priority if there is no argument */
|
||||
+ if (!pp->prio_arg)
|
||||
+ return priority;
|
||||
+
|
||||
+ arg = temp = STRDUP(pp->prio_arg);
|
||||
+
|
||||
+ regex = get_next_string(&temp, split_char);
|
||||
+
|
||||
+ if (!strcmp(regex, HBTL)) {
|
||||
+ sprintf(path, "%d:%d:%d:%d", pp->sg_id.host_no,
|
||||
+ pp->sg_id.channel, pp->sg_id.scsi_id, pp->sg_id.lun);
|
||||
+ } else if (!strcmp(regex, DEV_NAME)) {
|
||||
+ strcpy(path, pp->dev);
|
||||
+ } else {
|
||||
+ condlog(0, "%s: %s - Invalid arguments", pp->dev,
|
||||
+ pp->prio->name);
|
||||
+ return priority;
|
||||
+ }
|
||||
+
|
||||
+ while (!path_found) {
|
||||
+ if (!temp)
|
||||
+ break;
|
||||
+ if (!(regex = get_next_string(&temp, split_char)))
|
||||
+ break;
|
||||
+ if (!(prio = get_next_string(&temp, split_char)))
|
||||
+ break;
|
||||
+
|
||||
+ if (!regcomp(&pathe, regex, REG_EXTENDED|REG_NOSUB)) {
|
||||
+ if (!regexec(&pathe, path, 0, NULL, 0)) {
|
||||
+ path_found = 1;
|
||||
+ priority = atoi(prio);
|
||||
+ }
|
||||
+ regfree(&pathe);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ FREE(arg);
|
||||
+ return priority;
|
||||
+}
|
||||
+
|
||||
+int getprio(struct path *pp)
|
||||
+{
|
||||
+ return prio_path_weight(pp);
|
||||
+}
|
||||
+
|
||||
diff --git a/libmultipath/prioritizers/weightedpath.h b/libmultipath/prioritizers/weightedpath.h
|
||||
new file mode 100644
|
||||
index 0000000..141cdf7
|
||||
--- /dev/null
|
||||
+++ b/libmultipath/prioritizers/weightedpath.h
|
||||
@@ -0,0 +1,11 @@
|
||||
+#ifndef _WEIGHTED_PATH_H
|
||||
+#define _WEIGHTED_PATH_H
|
||||
+
|
||||
+#define PRIO_WEIGHTED_PATH "weightedpath"
|
||||
+#define HBTL "hbtl"
|
||||
+#define DEV_NAME "devname"
|
||||
+#define DEFAULT_PRIORITY 0
|
||||
+
|
||||
+int prio_path_weight(struct path *pp);
|
||||
+
|
||||
+#endif
|
||||
diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
|
||||
index 5a16182..1fc7c40 100644
|
||||
--- a/libmultipath/propsel.c
|
||||
+++ b/libmultipath/propsel.c
|
||||
@@ -258,14 +258,28 @@ select_getuid (struct path * pp)
|
||||
extern int
|
||||
select_prio (struct path * pp)
|
||||
{
|
||||
+ struct mpentry * mpe;
|
||||
+
|
||||
+ if ((mpe = find_mpe(pp->wwid))) {
|
||||
+ if (mpe->prio_name) {
|
||||
+ pp->prio = prio_lookup(mpe->prio_name);
|
||||
+ pp->prio_arg = mpe->prio_arg;
|
||||
+ condlog(3, "%s: prio = %s (LUN setting)",
|
||||
+ pp->dev, pp->prio->name);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (pp->hwe && pp->hwe->prio_name) {
|
||||
pp->prio = prio_lookup(pp->hwe->prio_name);
|
||||
+ pp->prio_arg = pp->hwe->prio_arg;
|
||||
condlog(3, "%s: prio = %s (controller setting)",
|
||||
pp->dev, pp->hwe->prio_name);
|
||||
return 0;
|
||||
}
|
||||
if (conf->prio_name) {
|
||||
pp->prio = prio_lookup(conf->prio_name);
|
||||
+ pp->prio_arg = conf->prio_arg;
|
||||
condlog(3, "%s: prio = %s (config file default)",
|
||||
pp->dev, conf->prio_name);
|
||||
return 0;
|
||||
diff --git a/libmultipath/structs.h b/libmultipath/structs.h
|
||||
index 658d6b2..75bd379 100644
|
||||
--- a/libmultipath/structs.h
|
||||
+++ b/libmultipath/structs.h
|
||||
@@ -121,6 +121,7 @@ struct path {
|
||||
int pgindex;
|
||||
char * getuid;
|
||||
struct prio * prio;
|
||||
+ char * prio_arg;
|
||||
struct checker checker;
|
||||
struct multipath * mpp;
|
||||
int fd;
|
||||
diff --git a/multipath.conf.annotated b/multipath.conf.annotated
|
||||
index a4c7e6a..740a334 100644
|
||||
--- a/multipath.conf.annotated
|
||||
+++ b/multipath.conf.annotated
|
||||
@@ -261,6 +261,18 @@
|
||||
# # default : 1000
|
||||
# #
|
||||
# rr_min_io 100
|
||||
+#
|
||||
+# #
|
||||
+# #name : prio
|
||||
+# #scope : multipath
|
||||
+# #desc : the function to call to obtain a path weight.
|
||||
+# # Weights are summed for each path group to
|
||||
+# # determine the next PG to use case of failure.
|
||||
+# #default : no callout, all paths equals
|
||||
+# # Ex:
|
||||
+# # prio alua
|
||||
+# # prio "weightedpath devname sda 50 sde 10 sdc 50 sdf 10"
|
||||
+# prio "weightedpath hbtl 1:.:.:. 2 4:.:.:. 4"
|
||||
# }
|
||||
# multipath {
|
||||
# wwid 1DEC_____321816758474
|
||||
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
|
||||
index d3c37c8..8ac1f1c 100644
|
||||
--- a/multipath/multipath.conf.5
|
||||
+++ b/multipath/multipath.conf.5
|
||||
@@ -151,6 +151,24 @@ Generate the path priority for Hitachi HDS Modular storage arrays.
|
||||
Default value is \fBnone\fR.
|
||||
.RE
|
||||
.TP
|
||||
+.B prio
|
||||
+The default program and args to path priority routine. The specified
|
||||
+routine should return a numeric value specifying the relative priority
|
||||
+of this path. Higher number have a higher priority.
|
||||
+.RS
|
||||
+.TP 12
|
||||
+.B alua
|
||||
+Generate the path priority based on ALUA status of the path.
|
||||
+.TP 12
|
||||
+.B weightedpath <hbtl|devname> <regex1> <prio1> <regex2> <prio2> ...
|
||||
+.I hbtl
|
||||
+regex can be of SCSI H:B:T:L format Ex: 1:0:.:. , *:0:0:.
|
||||
+.I devname
|
||||
+regex can be of device name format Ex: sda , sd.e
|
||||
+Generate the path priority based on the regular expression and the
|
||||
+priority provided as argument.
|
||||
+.RE
|
||||
+.TP
|
||||
.B features
|
||||
Specify any device-mapper features to be used. Syntax is
|
||||
.I num list
|
||||
@@ -327,6 +345,8 @@ section:
|
||||
.TP
|
||||
.B path_selector
|
||||
.TP
|
||||
+.B prio
|
||||
+.TP
|
||||
.B failback
|
||||
.TP
|
||||
.B no_path_retry
|
||||
@@ -380,6 +400,8 @@ section:
|
||||
.TP
|
||||
.B path_checker
|
||||
.TP
|
||||
+.B prio
|
||||
+.TP
|
||||
.B features
|
||||
.TP
|
||||
.B prio_callout
|
449
multipath-tools-rework-sysfs-device-handling
Normal file
449
multipath-tools-rework-sysfs-device-handling
Normal file
@ -0,0 +1,449 @@
|
||||
From e8f4746fa0aec8422022f52d917d6f82915128ce Mon Sep 17 00:00:00 2001
|
||||
From: Hannes Reinecke <hare@suse.de>
|
||||
Date: Thu, 20 Nov 2008 12:14:42 +0100
|
||||
Subject: [PATCH] Rework sysfs device handling in multipathd
|
||||
|
||||
Relying on sysfs devices has the disadvantage that the device
|
||||
might already been gone by the time we look at it. And we don't
|
||||
actually need it for eg device-mapper events as we can get all
|
||||
required information via the device-mapper ioctl.
|
||||
So only access sysfs if we absolutely have to and try to get
|
||||
the information from other places if possible.
|
||||
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
||||
---
|
||||
libmultipath/devmapper.c | 25 ++++++++++++
|
||||
libmultipath/devmapper.h | 1 +
|
||||
libmultipath/uevent.c | 46 +++++++++++++++++++++-
|
||||
libmultipath/uevent.h | 8 ++++
|
||||
multipathd/cli_handlers.c | 13 +++---
|
||||
multipathd/main.c | 94 +++++++++++++++++++++++++-------------------
|
||||
multipathd/main.h | 2 +-
|
||||
7 files changed, 139 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
|
||||
index bc4f9db..cde98eb 100644
|
||||
--- a/libmultipath/devmapper.c
|
||||
+++ b/libmultipath/devmapper.c
|
||||
@@ -494,6 +494,31 @@ out:
|
||||
}
|
||||
|
||||
int
|
||||
+dm_get_major (char * mapname)
|
||||
+{
|
||||
+ int r = -1;
|
||||
+ struct dm_task *dmt;
|
||||
+ struct dm_info info;
|
||||
+
|
||||
+ if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!dm_task_set_name(dmt, mapname))
|
||||
+ goto out;
|
||||
+
|
||||
+ if (!dm_task_run(dmt))
|
||||
+ goto out;
|
||||
+
|
||||
+ if (!dm_task_get_info(dmt, &info))
|
||||
+ goto out;
|
||||
+
|
||||
+ r = info.major;
|
||||
+out:
|
||||
+ dm_task_destroy(dmt);
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
dm_get_minor (char * mapname)
|
||||
{
|
||||
int r = -1;
|
||||
diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
|
||||
index b262efa..0c7b6b6 100644
|
||||
--- a/libmultipath/devmapper.h
|
||||
+++ b/libmultipath/devmapper.h
|
||||
@@ -27,6 +27,7 @@ int dm_enablegroup(char * mapname, int index);
|
||||
int dm_disablegroup(char * mapname, int index);
|
||||
int dm_get_maps (vector mp);
|
||||
int dm_geteventnr (char *name);
|
||||
+int dm_get_major (char *name);
|
||||
int dm_get_minor (char *name);
|
||||
char * dm_mapname(int major, int minor);
|
||||
int dm_remove_partmaps (const char * mapname);
|
||||
diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c
|
||||
index 99757fe..13986da 100644
|
||||
--- a/libmultipath/uevent.c
|
||||
+++ b/libmultipath/uevent.c
|
||||
@@ -262,10 +262,13 @@ int uevent_listen(int (*uev_trigger)(struct uevent *, void * trigger_data),
|
||||
uev->envp[i] = NULL;
|
||||
|
||||
condlog(3, "uevent '%s' from '%s'", uev->action, uev->devpath);
|
||||
+ uev->kernel = strrchr(uev->devpath, '/');
|
||||
+ if (uev->kernel)
|
||||
+ uev->kernel++;
|
||||
|
||||
/* print payload environment */
|
||||
for (i = 0; uev->envp[i] != NULL; i++)
|
||||
- condlog(3, "%s", uev->envp[i]);
|
||||
+ condlog(5, "%s", uev->envp[i]);
|
||||
|
||||
/*
|
||||
* Queue uevent and poke service pthread.
|
||||
@@ -297,3 +300,44 @@ exit:
|
||||
|
||||
return 1;
|
||||
}
|
||||
+
|
||||
+extern int
|
||||
+uevent_get_major(struct uevent *uev)
|
||||
+{
|
||||
+ char *p, *q;
|
||||
+ int i, major = -1;
|
||||
+
|
||||
+ for (i = 0; uev->envp[i] != NULL; i++) {
|
||||
+ if (!strncmp(uev->envp[i], "MAJOR", 5) && strlen(uev->envp[i]) > 6) {
|
||||
+ p = uev->envp[i] + 6;
|
||||
+ major = strtoul(p, &q, 10);
|
||||
+ if (p == q) {
|
||||
+ condlog(2, "invalid major '%s'", p);
|
||||
+ major = -1;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ return major;
|
||||
+}
|
||||
+
|
||||
+extern int
|
||||
+uevent_get_minor(struct uevent *uev)
|
||||
+{
|
||||
+ char *p, *q;
|
||||
+ int i, minor = -1;
|
||||
+
|
||||
+ for (i = 0; uev->envp[i] != NULL; i++) {
|
||||
+ if (!strncmp(uev->envp[i], "MINOR", 5) && strlen(uev->envp[i]) > 6) {
|
||||
+ p = uev->envp[i] + 6;
|
||||
+ minor = strtoul(p, &q, 10);
|
||||
+ if (p == q) {
|
||||
+ condlog(2, "invalid minor '%s'", p);
|
||||
+ minor = -1;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ return minor;
|
||||
+}
|
||||
+
|
||||
diff --git a/libmultipath/uevent.h b/libmultipath/uevent.h
|
||||
index 55ce42c..43d163b 100644
|
||||
--- a/libmultipath/uevent.h
|
||||
+++ b/libmultipath/uevent.h
|
||||
@@ -1,3 +1,6 @@
|
||||
+#ifndef _UEVENT_H
|
||||
+#define _UEVENT_H
|
||||
+
|
||||
/* environment buffer, the kernel's size in lib/kobject_uevent.c should fit in */
|
||||
#define HOTPLUG_BUFFER_SIZE 1024
|
||||
#define HOTPLUG_NUM_ENVP 32
|
||||
@@ -12,8 +15,13 @@ struct uevent {
|
||||
char buffer[HOTPLUG_BUFFER_SIZE + OBJECT_SIZE];
|
||||
char *devpath;
|
||||
char *action;
|
||||
+ char *kernel;
|
||||
char *envp[HOTPLUG_NUM_ENVP];
|
||||
};
|
||||
|
||||
int uevent_listen(int (*store_uev)(struct uevent *, void * trigger_data),
|
||||
void * trigger_data);
|
||||
+int uevent_get_major(struct uevent *uev);
|
||||
+int uevent_get_minor(struct uevent *uev);
|
||||
+
|
||||
+#endif /* _UEVENT_H */
|
||||
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
||||
index fca09ed..f9b0da4 100644
|
||||
--- a/multipathd/cli_handlers.c
|
||||
+++ b/multipathd/cli_handlers.c
|
||||
@@ -372,9 +372,8 @@ cli_add_map (void * v, char ** reply, int * len, void * data)
|
||||
{
|
||||
struct vectors * vecs = (struct vectors *)data;
|
||||
char * param = get_keyparam(v, MAP);
|
||||
- int minor;
|
||||
+ int major, minor;
|
||||
char dev_path[PATH_SIZE];
|
||||
- struct sysfs_device *sysdev;
|
||||
|
||||
condlog(2, "%s: add map (operator)", param);
|
||||
|
||||
@@ -389,13 +388,13 @@ cli_add_map (void * v, char ** reply, int * len, void * data)
|
||||
condlog(2, "%s: not a device mapper table", param);
|
||||
return 0;
|
||||
}
|
||||
- sprintf(dev_path,"/block/dm-%d", minor);
|
||||
- sysdev = sysfs_device_get(dev_path);
|
||||
- if (!sysdev) {
|
||||
- condlog(2, "%s: not found in sysfs", param);
|
||||
+ major = dm_get_major(param);
|
||||
+ if (major < 0) {
|
||||
+ condlog(2, "%s: not a device mapper table", param);
|
||||
return 0;
|
||||
}
|
||||
- return ev_add_map(sysdev, vecs);
|
||||
+ sprintf(dev_path,"dm-%d", minor);
|
||||
+ return ev_add_map(dev_path, major, minor, vecs);
|
||||
}
|
||||
|
||||
int
|
||||
diff --git a/multipathd/main.c b/multipathd/main.c
|
||||
index 6908902..bb396ec 100644
|
||||
--- a/multipathd/main.c
|
||||
+++ b/multipathd/main.c
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <print.h>
|
||||
#include <configure.h>
|
||||
#include <prio.h>
|
||||
+#include <uevent.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "pidfile.h"
|
||||
@@ -212,32 +213,32 @@ flush_map(struct multipath * mpp, struct vectors * vecs)
|
||||
}
|
||||
|
||||
static int
|
||||
-uev_add_map (struct sysfs_device * dev, struct vectors * vecs)
|
||||
+uev_add_map (struct uevent * uev, struct vectors * vecs)
|
||||
{
|
||||
- condlog(2, "%s: add map (uevent)", dev->kernel);
|
||||
- return ev_add_map(dev, vecs);
|
||||
+ int major, minor;
|
||||
+
|
||||
+ condlog(2, "%s: add map (uevent)", uev->kernel);
|
||||
+ major = uevent_get_major(uev);
|
||||
+ minor = uevent_get_minor(uev);
|
||||
+ return ev_add_map(uev->kernel, major, minor, vecs);
|
||||
}
|
||||
|
||||
int
|
||||
-ev_add_map (struct sysfs_device * dev, struct vectors * vecs)
|
||||
+ev_add_map (char * dev, int major, int minor, struct vectors * vecs)
|
||||
{
|
||||
char * alias;
|
||||
- char *dev_t;
|
||||
- int major, minor;
|
||||
char * refwwid;
|
||||
struct multipath * mpp;
|
||||
int map_present;
|
||||
int r = 1;
|
||||
|
||||
- dev_t = sysfs_attr_get_value(dev->devpath, "dev");
|
||||
-
|
||||
- if (!dev_t || sscanf(dev_t, "%d:%d", &major, &minor) != 2)
|
||||
- return 1;
|
||||
-
|
||||
alias = dm_mapname(major, minor);
|
||||
|
||||
- if (!alias)
|
||||
+ if (!alias) {
|
||||
+ condlog(2, "%s: mapname not found for %d:%d",
|
||||
+ dev, major, minor);
|
||||
return 1;
|
||||
+ }
|
||||
|
||||
map_present = dm_map_present(alias);
|
||||
|
||||
@@ -254,8 +255,7 @@ ev_add_map (struct sysfs_device * dev, struct vectors * vecs)
|
||||
* if we create a multipath mapped device as a result
|
||||
* of uev_add_path
|
||||
*/
|
||||
- condlog(0, "%s: devmap already registered",
|
||||
- dev->kernel);
|
||||
+ condlog(0, "%s: devmap already registered", dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -264,10 +264,10 @@ ev_add_map (struct sysfs_device * dev, struct vectors * vecs)
|
||||
*/
|
||||
if (map_present && (mpp = add_map_without_path(vecs, minor, alias))) {
|
||||
sync_map_state(mpp);
|
||||
- condlog(2, "%s: devmap %s added", alias, dev->kernel);
|
||||
+ condlog(2, "%s: devmap %s added", alias, dev);
|
||||
return 0;
|
||||
}
|
||||
- refwwid = get_refwwid(dev->kernel, DEV_DEVMAP, vecs->pathvec);
|
||||
+ refwwid = get_refwwid(dev, DEV_DEVMAP, vecs->pathvec);
|
||||
|
||||
if (refwwid) {
|
||||
r = coalesce_paths(vecs, NULL, refwwid, 0);
|
||||
@@ -275,19 +275,19 @@ ev_add_map (struct sysfs_device * dev, struct vectors * vecs)
|
||||
}
|
||||
|
||||
if (!r)
|
||||
- condlog(2, "%s: devmap %s added", alias, dev->kernel);
|
||||
+ condlog(2, "%s: devmap %s added", alias, dev);
|
||||
else
|
||||
- condlog(0, "%s: uev_add_map %s failed", alias, dev->kernel);
|
||||
+ condlog(0, "%s: uev_add_map %s failed", alias, dev);
|
||||
|
||||
FREE(refwwid);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
-uev_remove_map (struct sysfs_device * dev, struct vectors * vecs)
|
||||
+uev_remove_map (struct uevent * uev, struct vectors * vecs)
|
||||
{
|
||||
- condlog(2, "%s: remove map (uevent)", dev->kernel);
|
||||
- return ev_remove_map(dev->kernel, vecs);
|
||||
+ condlog(2, "%s: remove map (uevent)", uev->kernel);
|
||||
+ return ev_remove_map(uev->kernel, vecs);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -308,13 +308,13 @@ ev_remove_map (char * devname, struct vectors * vecs)
|
||||
}
|
||||
|
||||
static int
|
||||
-uev_umount_map (struct sysfs_device * dev, struct vectors * vecs)
|
||||
+uev_umount_map (struct uevent * uev, struct vectors * vecs)
|
||||
{
|
||||
struct multipath * mpp;
|
||||
|
||||
- condlog(2, "%s: umount map (uevent)", dev->kernel);
|
||||
+ condlog(2, "%s: umount map (uevent)", uev->kernel);
|
||||
|
||||
- mpp = find_mp_by_str(vecs->mpvec, dev->kernel);
|
||||
+ mpp = find_mp_by_str(vecs->mpvec, uev->kernel);
|
||||
|
||||
if (!mpp)
|
||||
return 0;
|
||||
@@ -328,14 +328,21 @@ uev_umount_map (struct sysfs_device * dev, struct vectors * vecs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+
|
||||
static int
|
||||
-uev_add_path (struct sysfs_device * dev, struct vectors * vecs)
|
||||
+uev_add_path (struct uevent *uev, struct vectors * vecs)
|
||||
{
|
||||
+ struct sysfs_device * dev;
|
||||
+
|
||||
+ dev = sysfs_device_get(uev->devpath);
|
||||
+ if (!dev) {
|
||||
+ condlog(2, "%s: not found in sysfs", uev->devpath);
|
||||
+ return 1;
|
||||
+ }
|
||||
condlog(2, "%s: add path (uevent)", dev->kernel);
|
||||
return (ev_add_path(dev->kernel, vecs) != 1)? 0 : 1;
|
||||
}
|
||||
|
||||
-
|
||||
/*
|
||||
* returns:
|
||||
* 0: added
|
||||
@@ -448,12 +455,19 @@ out:
|
||||
}
|
||||
|
||||
static int
|
||||
-uev_remove_path (struct sysfs_device * dev, struct vectors * vecs)
|
||||
+uev_remove_path (struct uevent *uev, struct vectors * vecs)
|
||||
{
|
||||
+ struct sysfs_device * dev;
|
||||
int retval;
|
||||
|
||||
- condlog(2, "%s: remove path (uevent)", dev->kernel);
|
||||
- retval = ev_remove_path(dev->kernel, vecs);
|
||||
+ dev = sysfs_device_get(uev->devpath);
|
||||
+ if (!dev) {
|
||||
+ condlog(2, "%s: not found in sysfs", uev->devpath);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ condlog(2, "%s: remove path (uevent)", uev->kernel);
|
||||
+ retval = ev_remove_path(uev->kernel, vecs);
|
||||
+
|
||||
if (!retval)
|
||||
sysfs_device_put(dev);
|
||||
|
||||
@@ -625,7 +639,6 @@ int
|
||||
uev_trigger (struct uevent * uev, void * trigger_data)
|
||||
{
|
||||
int r = 0;
|
||||
- struct sysfs_device *sysdev;
|
||||
struct vectors * vecs;
|
||||
|
||||
vecs = (struct vectors *)trigger_data;
|
||||
@@ -633,10 +646,6 @@ uev_trigger (struct uevent * uev, void * trigger_data)
|
||||
if (uev_discard(uev->devpath))
|
||||
return 0;
|
||||
|
||||
- sysdev = sysfs_device_get(uev->devpath);
|
||||
- if(!sysdev)
|
||||
- return 0;
|
||||
-
|
||||
lock(vecs->lock);
|
||||
|
||||
/*
|
||||
@@ -644,17 +653,17 @@ uev_trigger (struct uevent * uev, void * trigger_data)
|
||||
* Add events are ignored here as the tables
|
||||
* are not fully initialised then.
|
||||
*/
|
||||
- if (!strncmp(sysdev->kernel, "dm-", 3)) {
|
||||
+ if (!strncmp(uev->kernel, "dm-", 3)) {
|
||||
if (!strncmp(uev->action, "change", 6)) {
|
||||
- r = uev_add_map(sysdev, vecs);
|
||||
+ r = uev_add_map(uev, vecs);
|
||||
goto out;
|
||||
}
|
||||
if (!strncmp(uev->action, "remove", 6)) {
|
||||
- r = uev_remove_map(sysdev, vecs);
|
||||
+ r = uev_remove_map(uev, vecs);
|
||||
goto out;
|
||||
}
|
||||
if (!strncmp(uev->action, "umount", 6)) {
|
||||
- r = uev_umount_map(sysdev, vecs);
|
||||
+ r = uev_umount_map(uev, vecs);
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
@@ -664,15 +673,15 @@ uev_trigger (struct uevent * uev, void * trigger_data)
|
||||
* path add/remove event
|
||||
*/
|
||||
if (filter_devnode(conf->blist_devnode, conf->elist_devnode,
|
||||
- sysdev->kernel) > 0)
|
||||
+ uev->kernel) > 0)
|
||||
goto out;
|
||||
|
||||
if (!strncmp(uev->action, "add", 3)) {
|
||||
- r = uev_add_path(sysdev, vecs);
|
||||
+ r = uev_add_path(uev, vecs);
|
||||
goto out;
|
||||
}
|
||||
if (!strncmp(uev->action, "remove", 6)) {
|
||||
- r = uev_remove_path(sysdev, vecs);
|
||||
+ r = uev_remove_path(uev, vecs);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1383,6 +1392,9 @@ child (void * param)
|
||||
FREE(vecs);
|
||||
vecs = NULL;
|
||||
|
||||
+ cleanup_checkers();
|
||||
+ cleanup_prio();
|
||||
+
|
||||
condlog(2, "--------shut down-------");
|
||||
|
||||
if (logsink)
|
||||
diff --git a/multipathd/main.h b/multipathd/main.h
|
||||
index d73cd70..5d6f1b8 100644
|
||||
--- a/multipathd/main.h
|
||||
+++ b/multipathd/main.h
|
||||
@@ -7,7 +7,7 @@
|
||||
int reconfigure (struct vectors *);
|
||||
int ev_add_path (char *, struct vectors *);
|
||||
int ev_remove_path (char *, struct vectors *);
|
||||
-int ev_add_map (struct sysfs_device *, struct vectors *);
|
||||
+int ev_add_map (char *, int, int, struct vectors *);
|
||||
int ev_remove_map (char *, struct vectors *);
|
||||
void sync_map_state (struct multipath *);
|
||||
|
||||
--
|
||||
1.5.3.2
|
||||
|
98
multipath-tools-search-for-correct-hwe
Normal file
98
multipath-tools-search-for-correct-hwe
Normal file
@ -0,0 +1,98 @@
|
||||
From 90d210e6c277d6d822ed66a47d546a91703e4fd9 Mon Sep 17 00:00:00 2001
|
||||
From: Hannes Reinecke <hare@suse.de>
|
||||
Date: Thu, 20 Nov 2008 12:33:39 +0100
|
||||
Subject: [PATCH] Search for correct hwe in update_multipath()
|
||||
|
||||
When updating the multipath structure we only should update the
|
||||
hardware entry if it doesn't exist anymore. And we should take
|
||||
care of not selecting invalid entries in the paths vector as
|
||||
the hardware entry for this is invalid, too.
|
||||
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
||||
---
|
||||
libmultipath/structs_vec.c | 52 ++++++++++++++++++++++++++++++++++++++-----
|
||||
1 files changed, 46 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/structs_vec.c b/libmultipath/structs_vec.c
|
||||
index 785a766..17cafd1 100644
|
||||
--- a/libmultipath/structs_vec.c
|
||||
+++ b/libmultipath/structs_vec.c
|
||||
@@ -27,7 +27,7 @@ update_mpp_paths(struct multipath * mpp, vector pathvec)
|
||||
struct path * pp;
|
||||
int i,j;
|
||||
|
||||
- if (!mpp->pg)
|
||||
+ if (!mpp || !mpp->pg)
|
||||
return 0;
|
||||
|
||||
if (!mpp->paths &&
|
||||
@@ -188,13 +188,48 @@ static struct hwentry *
|
||||
extract_hwe_from_path(struct multipath * mpp)
|
||||
{
|
||||
struct path * pp = NULL;
|
||||
+ int pg_num = -1, p_num = -1, i;
|
||||
struct pathgroup * pgp = NULL;
|
||||
|
||||
- if (mpp && mpp->pg)
|
||||
- pgp = VECTOR_SLOT(mpp->pg, 0);
|
||||
+ condlog(3, "%s: searching paths for valid hwe", mpp->alias);
|
||||
|
||||
- if (pgp && pgp->paths)
|
||||
- pp = VECTOR_SLOT(pgp->paths, 0);
|
||||
+ if (mpp && mpp->pg) {
|
||||
+ vector_foreach_slot(mpp->pg, pgp, i) {
|
||||
+ if (pgp->status == PGSTATE_ACTIVE ||
|
||||
+ pgp->status == PGSTATE_ENABLED) {
|
||||
+ pg_num = i;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (pg_num >= 0)
|
||||
+ pgp = VECTOR_SLOT(mpp->pg, pg_num);
|
||||
+ }
|
||||
+
|
||||
+ if (pgp && pgp->paths) {
|
||||
+ vector_foreach_slot(pgp->paths, pp, i) {
|
||||
+ if (pp->dmstate == PSTATE_FAILED)
|
||||
+ continue;
|
||||
+ if (strlen(pp->vendor_id) > 0 &&
|
||||
+ strlen(pp->product_id) > 0 &&
|
||||
+ strlen(pp->rev) > 0) {
|
||||
+ p_num = i;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (p_num >= 0)
|
||||
+ pp = VECTOR_SLOT(pgp->paths, i);
|
||||
+ }
|
||||
+
|
||||
+ if (pp) {
|
||||
+ condlog(3, "%s: vendor = %s", pp->dev, pp->vendor_id);
|
||||
+ condlog(3, "%s: product = %s", pp->dev, pp->product_id);
|
||||
+ condlog(3, "%s: rev = %s", pp->dev, pp->rev);
|
||||
+ if (!pp->hwe) {
|
||||
+ condlog(3, "searching hwtable");
|
||||
+ pp->hwe = find_hwe(conf->hwtable, pp->vendor_id,
|
||||
+ pp->product_id, pp->rev);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
return pp?pp->hwe:NULL;
|
||||
}
|
||||
@@ -316,7 +351,12 @@ retry:
|
||||
}
|
||||
|
||||
//adopt_paths(vecs->pathvec, mpp);
|
||||
- mpp->hwe = extract_hwe_from_path(mpp);
|
||||
+ if (!mpp->hwe)
|
||||
+ mpp->hwe = extract_hwe_from_path(mpp);
|
||||
+ if (!mpp->hwe) {
|
||||
+ condlog(3, "%s: no hardware entry found, using defaults",
|
||||
+ mpp->alias);
|
||||
+ }
|
||||
select_rr_weight(mpp);
|
||||
select_pgfailback(mpp);
|
||||
set_no_path_retry(mpp);
|
||||
--
|
||||
1.5.3.2
|
||||
|
@ -1316,15 +1316,6 @@
|
||||
|
||||
--- multipath-tools-0.4.8/libmultipath/hwtable.c
|
||||
+++ multipath-tools-0.4.8/libmultipath/hwtable.c
|
||||
@@ -92,7 +92,7 @@
|
||||
{
|
||||
/* MSA 1000/MSA1500 EVA 3000/5000 with old firmware */
|
||||
.vendor = "(COMPAQ|HP)",
|
||||
- .product = "(MSA|HSV)1.0.*",
|
||||
+ .product = "(MSA|HSV)1[01]0.*",
|
||||
.getuid = DEFAULT_GETUID,
|
||||
.features = "1 queue_if_no_path",
|
||||
.hwhandler = "1 hp-sw",
|
||||
@@ -172,7 +172,7 @@
|
||||
/* HP Smart Array */
|
||||
.vendor = "HP",
|
||||
|
644
multipath-tools-sles11-valgrind-fixes
Normal file
644
multipath-tools-sles11-valgrind-fixes
Normal file
@ -0,0 +1,644 @@
|
||||
diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c
|
||||
index 5132081..2640281 100644
|
||||
--- a/libmultipath/checkers.c
|
||||
+++ b/libmultipath/checkers.c
|
||||
@@ -40,6 +40,14 @@ struct checker * alloc_checker (void)
|
||||
|
||||
void free_checker (struct checker * c)
|
||||
{
|
||||
+ condlog(3, "unloading %s checker", c->name);
|
||||
+ list_del(&c->node);
|
||||
+ if (c->handle) {
|
||||
+ if (dlclose(c->handle) != 0) {
|
||||
+ condlog(0, "Cannot unload checker %s: %s",
|
||||
+ c->name, dlerror());
|
||||
+ }
|
||||
+ }
|
||||
free(c);
|
||||
}
|
||||
|
||||
@@ -49,8 +57,7 @@ void cleanup_checkers (void)
|
||||
struct checker * checker_temp;
|
||||
|
||||
list_for_each_entry_safe(checker_loop, checker_temp, &checkers, node) {
|
||||
- list_del(&checker_loop->node);
|
||||
- free(checker_loop);
|
||||
+ free_checker(checker_loop);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +75,6 @@ struct checker * checker_lookup (char * name)
|
||||
struct checker * add_checker (char * name)
|
||||
{
|
||||
char libname[LIB_CHECKER_NAMELEN];
|
||||
- void * handle;
|
||||
struct checker * c;
|
||||
char *errstr;
|
||||
|
||||
@@ -78,31 +84,31 @@ struct checker * add_checker (char * name)
|
||||
snprintf(libname, LIB_CHECKER_NAMELEN, "%s/libcheck%s.so",
|
||||
conf->multipath_dir, name);
|
||||
condlog(3, "loading %s checker", libname);
|
||||
- handle = dlopen(libname, RTLD_NOW);
|
||||
+ c->handle = dlopen(libname, RTLD_NOW);
|
||||
errstr = dlerror();
|
||||
if (errstr != NULL)
|
||||
- condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
||||
- if (!handle)
|
||||
+ condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
||||
+ if (!c->handle)
|
||||
goto out;
|
||||
|
||||
- c->check = (int (*)(struct checker *)) dlsym(handle, "libcheck_check");
|
||||
+ c->check = (int (*)(struct checker *)) dlsym(c->handle, "libcheck_check");
|
||||
errstr = dlerror();
|
||||
if (errstr != NULL)
|
||||
- condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
||||
+ condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
||||
if (!c->check)
|
||||
goto out;
|
||||
|
||||
- c->init = (int (*)(struct checker *)) dlsym(handle, "libcheck_init");
|
||||
+ c->init = (int (*)(struct checker *)) dlsym(c->handle, "libcheck_init");
|
||||
errstr = dlerror();
|
||||
if (errstr != NULL)
|
||||
- condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
||||
+ condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
||||
if (!c->init)
|
||||
goto out;
|
||||
|
||||
- c->free = (void (*)(struct checker *)) dlsym(handle, "libcheck_free");
|
||||
+ c->free = (void (*)(struct checker *)) dlsym(c->handle, "libcheck_free");
|
||||
errstr = dlerror();
|
||||
if (errstr != NULL)
|
||||
- condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
||||
+ condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
||||
if (!c->free)
|
||||
goto out;
|
||||
|
||||
@@ -199,4 +205,5 @@ void checker_get (struct checker * dst, char * name)
|
||||
dst->check = src->check;
|
||||
dst->init = src->init;
|
||||
dst->free = src->free;
|
||||
+ dst->handle = NULL;
|
||||
}
|
||||
diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h
|
||||
index e735250..da09d6c 100644
|
||||
--- a/libmultipath/checkers.h
|
||||
+++ b/libmultipath/checkers.h
|
||||
@@ -94,6 +94,7 @@ enum path_check_state {
|
||||
|
||||
struct checker {
|
||||
struct list_head node;
|
||||
+ void *handle;
|
||||
int fd;
|
||||
int sync;
|
||||
int disable;
|
||||
@@ -111,6 +112,7 @@ struct checker {
|
||||
|
||||
char * checker_state_name (int);
|
||||
int init_checkers (void);
|
||||
+void cleanup_checkers (void);
|
||||
struct checker * add_checker (char *);
|
||||
struct checker * checker_lookup (char *);
|
||||
int checker_init (struct checker *, void **);
|
||||
diff --git a/libmultipath/checkers/emc_clariion.c b/libmultipath/checkers/emc_clariion.c
|
||||
index 9eac31d..03c1354 100644
|
||||
--- a/libmultipath/checkers/emc_clariion.c
|
||||
+++ b/libmultipath/checkers/emc_clariion.c
|
||||
@@ -102,6 +102,8 @@ int libcheck_check (struct checker * c)
|
||||
int ret;
|
||||
|
||||
memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
||||
+ memset(sense_buffer, 0, 128);
|
||||
+ memset(sb, 0, SENSE_BUFF_LEN);
|
||||
io_hdr.interface_id = 'S';
|
||||
io_hdr.cmd_len = sizeof (inqCmdBlk);
|
||||
io_hdr.mx_sb_len = sizeof (sb);
|
||||
@@ -128,7 +130,7 @@ int libcheck_check (struct checker * c)
|
||||
}
|
||||
|
||||
if ( /* Effective initiator type */
|
||||
- sense_buffer[27] != 0x03
|
||||
+ sense_buffer[27] != 0x03
|
||||
/*
|
||||
* Failover mode should be set to 1 (PNR failover mode)
|
||||
* or 4 (ALUA failover mode).
|
||||
@@ -155,7 +157,7 @@ int libcheck_check (struct checker * c)
|
||||
"or LUNZ");
|
||||
return PATH_DOWN;
|
||||
}
|
||||
-
|
||||
+
|
||||
/*
|
||||
* store the LUN WWN there and compare that it indeed did not
|
||||
* change in between, to protect against the path suddenly
|
||||
@@ -171,28 +173,29 @@ int libcheck_check (struct checker * c)
|
||||
memcpy(ct->wwn, &sense_buffer[10], 16);
|
||||
ct->wwn_set = 1;
|
||||
}
|
||||
-
|
||||
+
|
||||
/*
|
||||
* Issue read on active path to determine if inactive snapshot.
|
||||
*/
|
||||
if (sense_buffer[4] == 2) {/* if active path */
|
||||
unsigned char buf[4096];
|
||||
|
||||
+ memset(buf, 0, 4096);
|
||||
ret = sg_read(c->fd, &buf[0], sbb = &sb[0]);
|
||||
if (ret == PATH_DOWN) {
|
||||
hexadecimal_to_ascii(ct->wwn, wwnstr);
|
||||
|
||||
/*
|
||||
- * Check for inactive snapshot LU this way. Must
|
||||
+ * Check for inactive snapshot LU this way. Must
|
||||
* fail these.
|
||||
- */
|
||||
+ */
|
||||
if (((sbb[2]&0xf) == 5) && (sbb[12] == 0x25) &&
|
||||
(sbb[13]==1)) {
|
||||
/*
|
||||
- * Do this so that we can fail even the
|
||||
- * passive paths which will return
|
||||
+ * Do this so that we can fail even the
|
||||
+ * passive paths which will return
|
||||
* 02/04/03 not 05/25/01 on read.
|
||||
- */
|
||||
+ */
|
||||
SET_INACTIVE_SNAP(c);
|
||||
MSG(c, "emc_clariion_checker: Active "
|
||||
"path to inactive snapshot WWN %s.",
|
||||
@@ -206,10 +209,10 @@ int libcheck_check (struct checker * c)
|
||||
MSG(c, "emc_clariion_checker: Active path is "
|
||||
"healthy.");
|
||||
/*
|
||||
- * Remove the path from the set of paths to inactive
|
||||
- * snapshot LUs if it was in this list since the
|
||||
- * snapshot is no longer inactive.
|
||||
- */
|
||||
+ * Remove the path from the set of paths to inactive
|
||||
+ * snapshot LUs if it was in this list since the
|
||||
+ * snapshot is no longer inactive.
|
||||
+ */
|
||||
CLR_INACTIVE_SNAP(c);
|
||||
}
|
||||
} else {
|
||||
@@ -221,7 +224,7 @@ int libcheck_check (struct checker * c)
|
||||
ret = PATH_DOWN;
|
||||
} else {
|
||||
MSG(c,
|
||||
- "emc_clariion_checker: Passive path is healthy.");
|
||||
+ "emc_clariion_checker: Passive path is healthy.");
|
||||
ret = PATH_UP; /* not ghost */
|
||||
}
|
||||
}
|
||||
diff --git a/libmultipath/checkers/hp_sw.c b/libmultipath/checkers/hp_sw.c
|
||||
index 7509307..3f28d85 100644
|
||||
--- a/libmultipath/checkers/hp_sw.c
|
||||
+++ b/libmultipath/checkers/hp_sw.c
|
||||
@@ -48,75 +48,76 @@ static int
|
||||
do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
|
||||
void *resp, int mx_resp_len, int noisy)
|
||||
{
|
||||
- unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
|
||||
- { INQUIRY_CMD, 0, 0, 0, 0, 0 };
|
||||
- unsigned char sense_b[SENSE_BUFF_LEN];
|
||||
- struct sg_io_hdr io_hdr;
|
||||
-
|
||||
- if (cmddt)
|
||||
- inqCmdBlk[1] |= 2;
|
||||
- if (evpd)
|
||||
- inqCmdBlk[1] |= 1;
|
||||
- inqCmdBlk[2] = (unsigned char) pg_op;
|
||||
+ unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
|
||||
+ { INQUIRY_CMD, 0, 0, 0, 0, 0 };
|
||||
+ unsigned char sense_b[SENSE_BUFF_LEN];
|
||||
+ struct sg_io_hdr io_hdr;
|
||||
+
|
||||
+ if (cmddt)
|
||||
+ inqCmdBlk[1] |= 2;
|
||||
+ if (evpd)
|
||||
+ inqCmdBlk[1] |= 1;
|
||||
+ inqCmdBlk[2] = (unsigned char) pg_op;
|
||||
inqCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff);
|
||||
inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
|
||||
- memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
||||
- io_hdr.interface_id = 'S';
|
||||
- io_hdr.cmd_len = sizeof (inqCmdBlk);
|
||||
- io_hdr.mx_sb_len = sizeof (sense_b);
|
||||
- io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
||||
- io_hdr.dxfer_len = mx_resp_len;
|
||||
- io_hdr.dxferp = resp;
|
||||
- io_hdr.cmdp = inqCmdBlk;
|
||||
- io_hdr.sbp = sense_b;
|
||||
- io_hdr.timeout = DEF_TIMEOUT;
|
||||
-
|
||||
- if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
|
||||
- return 1;
|
||||
-
|
||||
- /* treat SG_ERR here to get rid of sg_err.[ch] */
|
||||
- io_hdr.status &= 0x7e;
|
||||
- if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
|
||||
- (0 == io_hdr.driver_status))
|
||||
- return 0;
|
||||
- if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
|
||||
- (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
|
||||
- (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
|
||||
- if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
|
||||
- int sense_key;
|
||||
- unsigned char * sense_buffer = io_hdr.sbp;
|
||||
- if (sense_buffer[0] & 0x2)
|
||||
- sense_key = sense_buffer[1] & 0xf;
|
||||
- else
|
||||
- sense_key = sense_buffer[2] & 0xf;
|
||||
- if(RECOVERED_ERROR == sense_key)
|
||||
- return 0;
|
||||
- }
|
||||
- }
|
||||
- return 1;
|
||||
+ memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
||||
+ memset(sense_b, 0, SENSE_BUFF_LEN);
|
||||
+ io_hdr.interface_id = 'S';
|
||||
+ io_hdr.cmd_len = sizeof (inqCmdBlk);
|
||||
+ io_hdr.mx_sb_len = sizeof (sense_b);
|
||||
+ io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
|
||||
+ io_hdr.dxfer_len = mx_resp_len;
|
||||
+ io_hdr.dxferp = resp;
|
||||
+ io_hdr.cmdp = inqCmdBlk;
|
||||
+ io_hdr.sbp = sense_b;
|
||||
+ io_hdr.timeout = DEF_TIMEOUT;
|
||||
+
|
||||
+ if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
|
||||
+ return 1;
|
||||
+
|
||||
+ /* treat SG_ERR here to get rid of sg_err.[ch] */
|
||||
+ io_hdr.status &= 0x7e;
|
||||
+ if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
|
||||
+ (0 == io_hdr.driver_status))
|
||||
+ return 0;
|
||||
+ if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
|
||||
+ (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
|
||||
+ (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
|
||||
+ if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
|
||||
+ int sense_key;
|
||||
+ unsigned char * sense_buffer = io_hdr.sbp;
|
||||
+ if (sense_buffer[0] & 0x2)
|
||||
+ sense_key = sense_buffer[1] & 0xf;
|
||||
+ else
|
||||
+ sense_key = sense_buffer[2] & 0xf;
|
||||
+ if(RECOVERED_ERROR == sense_key)
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
do_tur (int fd)
|
||||
{
|
||||
- unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 };
|
||||
- struct sg_io_hdr io_hdr;
|
||||
- unsigned char sense_buffer[32];
|
||||
-
|
||||
- memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
||||
- io_hdr.interface_id = 'S';
|
||||
- io_hdr.cmd_len = sizeof (turCmdBlk);
|
||||
- io_hdr.mx_sb_len = sizeof (sense_buffer);
|
||||
- io_hdr.dxfer_direction = SG_DXFER_NONE;
|
||||
- io_hdr.cmdp = turCmdBlk;
|
||||
- io_hdr.sbp = sense_buffer;
|
||||
- io_hdr.timeout = DEF_TIMEOUT;
|
||||
- io_hdr.pack_id = 0;
|
||||
-
|
||||
- if (ioctl(fd, SG_IO, &io_hdr) < 0)
|
||||
+ unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 };
|
||||
+ struct sg_io_hdr io_hdr;
|
||||
+ unsigned char sense_buffer[32];
|
||||
+
|
||||
+ memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
||||
+ io_hdr.interface_id = 'S';
|
||||
+ io_hdr.cmd_len = sizeof (turCmdBlk);
|
||||
+ io_hdr.mx_sb_len = sizeof (sense_buffer);
|
||||
+ io_hdr.dxfer_direction = SG_DXFER_NONE;
|
||||
+ io_hdr.cmdp = turCmdBlk;
|
||||
+ io_hdr.sbp = sense_buffer;
|
||||
+ io_hdr.timeout = DEF_TIMEOUT;
|
||||
+ io_hdr.pack_id = 0;
|
||||
+
|
||||
+ if (ioctl(fd, SG_IO, &io_hdr) < 0)
|
||||
return 1;
|
||||
|
||||
- if (io_hdr.info & SG_INFO_OK_MASK)
|
||||
+ if (io_hdr.info & SG_INFO_OK_MASK)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
@@ -134,8 +135,8 @@ libcheck_check (struct checker * c)
|
||||
|
||||
if (do_tur(c->fd)) {
|
||||
MSG(c, MSG_HP_SW_GHOST);
|
||||
- return PATH_GHOST;
|
||||
- }
|
||||
+ return PATH_GHOST;
|
||||
+ }
|
||||
MSG(c, MSG_HP_SW_UP);
|
||||
return PATH_UP;
|
||||
}
|
||||
diff --git a/libmultipath/checkers/rdac.c b/libmultipath/checkers/rdac.c
|
||||
index 0086125..c4c7b8f 100644
|
||||
--- a/libmultipath/checkers/rdac.c
|
||||
+++ b/libmultipath/checkers/rdac.c
|
||||
@@ -52,6 +52,7 @@ do_inq(int sg_fd, unsigned int pg_op, void *resp, int mx_resp_len)
|
||||
inqCmdBlk[2] = (unsigned char) pg_op;
|
||||
inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
|
||||
memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
||||
+ memset(sense_b, 0, SENSE_BUFF_LEN);
|
||||
|
||||
io_hdr.interface_id = 'S';
|
||||
io_hdr.cmd_len = sizeof (inqCmdBlk);
|
||||
@@ -100,6 +101,7 @@ libcheck_check (struct checker * c)
|
||||
{
|
||||
struct volume_access_inq inq;
|
||||
|
||||
+ memset(&inq, 0, sizeof(struct volume_access_inq));
|
||||
if (0 != do_inq(c->fd, 0xC9, &inq, sizeof(struct volume_access_inq))) {
|
||||
MSG(c, MSG_RDAC_DOWN);
|
||||
return PATH_DOWN;
|
||||
diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c
|
||||
index 43b846d..820a2e3 100644
|
||||
--- a/libmultipath/checkers/tur.c
|
||||
+++ b/libmultipath/checkers/tur.c
|
||||
@@ -47,6 +47,7 @@ libcheck_check (struct checker * c)
|
||||
|
||||
retry:
|
||||
memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
||||
+ memset(&sense_buffer, 0, 32);
|
||||
io_hdr.interface_id = 'S';
|
||||
io_hdr.cmd_len = sizeof (turCmdBlk);
|
||||
io_hdr.mx_sb_len = sizeof (sense_buffer);
|
||||
diff --git a/libmultipath/config.c b/libmultipath/config.c
|
||||
index cf134e4..908156d 100644
|
||||
--- a/libmultipath/config.c
|
||||
+++ b/libmultipath/config.c
|
||||
@@ -150,9 +150,6 @@ free_hwe (struct hwentry * hwe)
|
||||
if (hwe->revision)
|
||||
FREE(hwe->revision);
|
||||
|
||||
- if (hwe->selector)
|
||||
- FREE(hwe->selector);
|
||||
-
|
||||
if (hwe->getuid)
|
||||
FREE(hwe->getuid);
|
||||
|
||||
@@ -162,6 +159,15 @@ free_hwe (struct hwentry * hwe)
|
||||
if (hwe->hwhandler)
|
||||
FREE(hwe->hwhandler);
|
||||
|
||||
+ if (hwe->selector)
|
||||
+ FREE(hwe->selector);
|
||||
+
|
||||
+ if (hwe->checker_name)
|
||||
+ FREE(hwe->checker_name);
|
||||
+
|
||||
+ if (hwe->prio_name)
|
||||
+ FREE(hwe->prio_name);
|
||||
+
|
||||
if (hwe->bl_product)
|
||||
FREE(hwe->bl_product);
|
||||
|
||||
@@ -409,6 +415,12 @@ free_config (struct config * conf)
|
||||
if (conf->bindings_file)
|
||||
FREE(conf->bindings_file);
|
||||
|
||||
+ if (conf->prio_name)
|
||||
+ FREE(conf->prio_name);
|
||||
+
|
||||
+ if (conf->checker_name)
|
||||
+ FREE(conf->checker_name);
|
||||
+
|
||||
free_blacklist(conf->blist_devnode);
|
||||
free_blacklist(conf->blist_wwid);
|
||||
free_blacklist_device(conf->blist_device);
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 9929e19..20d0684 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -232,6 +232,7 @@ devt2devname (char *devname, char *devt)
|
||||
char block_path[FILE_NAME_SIZE];
|
||||
struct stat statbuf;
|
||||
|
||||
+ memset(block_path, 0, FILE_NAME_SIZE);
|
||||
if (sscanf(devt, "%u:%u", &major, &minor) != 2) {
|
||||
condlog(0, "Invalid device number %s", devt);
|
||||
return 1;
|
||||
diff --git a/libmultipath/print.c b/libmultipath/print.c
|
||||
index 46ae2ec..7467411 100644
|
||||
--- a/libmultipath/print.c
|
||||
+++ b/libmultipath/print.c
|
||||
@@ -111,19 +111,22 @@ snprint_ro (char * buff, size_t len, struct multipath * mpp)
|
||||
static int
|
||||
snprint_progress (char * buff, size_t len, int cur, int total)
|
||||
{
|
||||
- int i = PROGRESS_LEN * cur / total;
|
||||
- int j = PROGRESS_LEN - i;
|
||||
char * c = buff;
|
||||
char * end = buff + len;
|
||||
|
||||
- while (i-- > 0) {
|
||||
- c += snprintf(c, len, "X");
|
||||
- if ((len = (end - c)) <= 1) goto out;
|
||||
- }
|
||||
+ if (total > 0) {
|
||||
+ int i = PROGRESS_LEN * cur / total;
|
||||
+ int j = PROGRESS_LEN - i;
|
||||
+
|
||||
+ while (i-- > 0) {
|
||||
+ c += snprintf(c, len, "X");
|
||||
+ if ((len = (end - c)) <= 1) goto out;
|
||||
+ }
|
||||
|
||||
- while (j-- > 0) {
|
||||
- c += snprintf(c, len, ".");
|
||||
- if ((len = (end - c)) <= 1) goto out;
|
||||
+ while (j-- > 0) {
|
||||
+ c += snprintf(c, len, ".");
|
||||
+ if ((len = (end - c)) <= 1) goto out;
|
||||
+ }
|
||||
}
|
||||
|
||||
c += snprintf(c, len, " %i/%i", cur, total);
|
||||
@@ -705,6 +708,7 @@ print_multipath_topology (struct multipath * mpp, int verbosity)
|
||||
{
|
||||
char buff[MAX_LINE_LEN * MAX_LINES] = {};
|
||||
|
||||
+ memset(&buff[0], 0, MAX_LINE_LEN * MAX_LINES);
|
||||
snprint_multipath_topology(&buff[0], MAX_LINE_LEN * MAX_LINES,
|
||||
mpp, verbosity);
|
||||
printf("%s", buff);
|
||||
diff --git a/libmultipath/prio.c b/libmultipath/prio.c
|
||||
index c9d2873..352e9ca 100644
|
||||
--- a/libmultipath/prio.c
|
||||
+++ b/libmultipath/prio.c
|
||||
@@ -24,6 +24,14 @@ struct prio * alloc_prio (void)
|
||||
|
||||
void free_prio (struct prio * p)
|
||||
{
|
||||
+ condlog(3, "unloading %s prioritizer", p->name);
|
||||
+ list_del(&p->node);
|
||||
+ if (p->handle) {
|
||||
+ if (dlclose(p->handle) != 0) {
|
||||
+ condlog(0, "Cannot unload prioritizer %s: %s",
|
||||
+ p->name, dlerror());
|
||||
+ }
|
||||
+ }
|
||||
free(p);
|
||||
}
|
||||
|
||||
@@ -33,8 +41,7 @@ void cleanup_prio(void)
|
||||
struct prio * prio_temp;
|
||||
|
||||
list_for_each_entry_safe(prio_loop, prio_temp, &prioritizers, node) {
|
||||
- list_del(&prio_loop->node);
|
||||
- free(prio_loop);
|
||||
+ free_prio(prio_loop);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +59,6 @@ struct prio * prio_lookup (char * name)
|
||||
struct prio * add_prio (char * name)
|
||||
{
|
||||
char libname[LIB_PRIO_NAMELEN];
|
||||
- void * handle;
|
||||
struct prio * p;
|
||||
char *errstr;
|
||||
|
||||
@@ -62,16 +68,16 @@ struct prio * add_prio (char * name)
|
||||
snprintf(libname, LIB_PRIO_NAMELEN, "%s/libprio%s.so",
|
||||
conf->multipath_dir, name);
|
||||
condlog(3, "loading %s prioritizer", libname);
|
||||
- handle = dlopen(libname, RTLD_NOW);
|
||||
+ p->handle = dlopen(libname, RTLD_NOW);
|
||||
errstr = dlerror();
|
||||
if (errstr != NULL)
|
||||
- condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
||||
- if (!handle)
|
||||
+ condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
||||
+ if (!p->handle)
|
||||
goto out;
|
||||
- p->getprio = (int (*)(struct path *)) dlsym(handle, "getprio");
|
||||
+ p->getprio = (int (*)(struct path *)) dlsym(p->handle, "getprio");
|
||||
errstr = dlerror();
|
||||
if (errstr != NULL)
|
||||
- condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
||||
+ condlog(0, "A dynamic linking error occurred: (%s)", errstr);
|
||||
if (!p->getprio)
|
||||
goto out;
|
||||
snprintf(p->name, PRIO_NAME_LEN, "%s", name);
|
||||
diff --git a/libmultipath/prio.h b/libmultipath/prio.h
|
||||
index 4eea703..deef02d 100644
|
||||
--- a/libmultipath/prio.h
|
||||
+++ b/libmultipath/prio.h
|
||||
@@ -37,12 +37,14 @@
|
||||
#define PRIO_NAME_LEN 16
|
||||
|
||||
struct prio {
|
||||
+ void *handle;
|
||||
struct list_head node;
|
||||
char name[PRIO_NAME_LEN];
|
||||
int (*getprio)(struct path *);
|
||||
};
|
||||
|
||||
int init_prio (void);
|
||||
+void cleanup_prio(void);
|
||||
struct prio * add_prio (char *);
|
||||
struct prio * prio_lookup (char *);
|
||||
int prio_getprio (struct prio *, struct path *);
|
||||
diff --git a/libmultipath/prioritizers/alua_rtpg.c b/libmultipath/prioritizers/alua_rtpg.c
|
||||
index 59df788..498de62 100644
|
||||
--- a/libmultipath/prioritizers/alua_rtpg.c
|
||||
+++ b/libmultipath/prioritizers/alua_rtpg.c
|
||||
@@ -265,8 +265,10 @@ get_asymmetric_access_state(int fd, unsigned int tpg)
|
||||
}
|
||||
memset(buf, 0, buflen);
|
||||
rc = do_rtpg(fd, buf, buflen);
|
||||
- if (rc < 0)
|
||||
+ if (rc < 0) {
|
||||
+ free(buf);
|
||||
return rc;
|
||||
+ }
|
||||
scsi_buflen = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
|
||||
if (buflen < (scsi_buflen + 4)) {
|
||||
free(buf);
|
||||
diff --git a/libmultipath/prioritizers/emc.c b/libmultipath/prioritizers/emc.c
|
||||
index 61d7a77..c3301b2 100644
|
||||
--- a/libmultipath/prioritizers/emc.c
|
||||
+++ b/libmultipath/prioritizers/emc.c
|
||||
@@ -18,8 +18,9 @@ int emc_clariion_prio(const char *dev, int fd)
|
||||
unsigned char inqCmdBlk[INQUIRY_CMDLEN] = {INQUIRY_CMD, 1, 0xC0, 0,
|
||||
sizeof(sb), 0};
|
||||
struct sg_io_hdr io_hdr;
|
||||
- int ret = 0;
|
||||
+ int ret = PRIO_UNDEF;
|
||||
|
||||
+ memset(&sense_buffer, 0, 256);
|
||||
memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
||||
io_hdr.interface_id = 'S';
|
||||
io_hdr.cmd_len = sizeof (inqCmdBlk);
|
||||
@@ -45,9 +46,9 @@ int emc_clariion_prio(const char *dev, int fd)
|
||||
pp_emc_log(0, "path unit report page in unknown format");
|
||||
goto out;
|
||||
}
|
||||
-
|
||||
+
|
||||
if ( /* Effective initiator type */
|
||||
- sense_buffer[27] != 0x03
|
||||
+ sense_buffer[27] != 0x03
|
||||
/*
|
||||
* Failover mode should be set to 1 (PNR failover mode)
|
||||
* or 4 (ALUA failover mode).
|
||||
@@ -68,7 +69,7 @@ int emc_clariion_prio(const char *dev, int fd)
|
||||
/* Note this will switch to the default priority group, even if
|
||||
* it is not the currently active one. */
|
||||
ret = (sense_buffer[5] == sense_buffer[8]) ? 1 : 0;
|
||||
-
|
||||
+
|
||||
out:
|
||||
return(ret);
|
||||
}
|
||||
diff --git a/libmultipath/prioritizers/hds.c b/libmultipath/prioritizers/hds.c
|
||||
index f3d4cb3..d56a46a 100644
|
||||
--- a/libmultipath/prioritizers/hds.c
|
||||
+++ b/libmultipath/prioritizers/hds.c
|
||||
@@ -104,6 +104,7 @@ int hds_modular_prio (const char *dev, int fd)
|
||||
}
|
||||
|
||||
memset (&io_hdr, 0, sizeof (sg_io_hdr_t));
|
||||
+ memset (inqBuff, 0, INQ_REPLY_LEN);
|
||||
io_hdr.interface_id = 'S';
|
||||
io_hdr.cmd_len = sizeof (inqCmdBlk);
|
||||
io_hdr.mx_sb_len = sizeof (sense_buffer);
|
||||
diff --git a/libmultipath/prioritizers/ontap.c b/libmultipath/prioritizers/ontap.c
|
||||
index 1200114..4d7c128 100644
|
||||
--- a/libmultipath/prioritizers/ontap.c
|
||||
+++ b/libmultipath/prioritizers/ontap.c
|
||||
@@ -79,6 +79,7 @@ static int send_gva(const char *dev, int fd, unsigned char pg,
|
||||
int ret = -1;
|
||||
|
||||
memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
||||
+ memset(results, 0, *results_size);
|
||||
io_hdr.interface_id = 'S';
|
||||
io_hdr.cmd_len = sizeof (cdb);
|
||||
io_hdr.mx_sb_len = sizeof (sb);
|
||||
diff --git a/libmultipath/prioritizers/rdac.c b/libmultipath/prioritizers/rdac.c
|
||||
index 7eafc31..b514bdd 100644
|
||||
--- a/libmultipath/prioritizers/rdac.c
|
||||
+++ b/libmultipath/prioritizers/rdac.c
|
||||
@@ -21,6 +21,7 @@ int rdac_prio(const char *dev, int fd)
|
||||
int ret = 0;
|
||||
|
||||
memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
||||
+ memset(sense_buffer, 0, 256);
|
||||
io_hdr.interface_id = 'S';
|
||||
io_hdr.cmd_len = sizeof (inqCmdBlk);
|
||||
io_hdr.mx_sb_len = sizeof (sb);
|
128
multipath-tools-update-hp-hwtable
Normal file
128
multipath-tools-update-hp-hwtable
Normal file
@ -0,0 +1,128 @@
|
||||
commit 73af31edbba5588dafce75fa8267b14f36b545b0
|
||||
Author: Hannes Reinecke <hare@suse.de>
|
||||
Date: Tue Nov 11 13:44:09 2008 +0100
|
||||
|
||||
Update hardware table for new HP arrays
|
||||
|
||||
References: 442133
|
||||
|
||||
Signed-off-by: Vijayakumar Balasubramanian <vijaykumar@hp.com>
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
||||
|
||||
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
|
||||
index fda131c..bf8c611 100644
|
||||
--- a/libmultipath/hwtable.c
|
||||
+++ b/libmultipath/hwtable.c
|
||||
@@ -122,7 +122,7 @@ static struct hwentry default_hw[] = {
|
||||
.pgfailback = FAILBACK_UNDEF,
|
||||
.rr_weight = RR_WEIGHT_NONE,
|
||||
.no_path_retry = 12,
|
||||
- .minio = DEFAULT_MINIO,
|
||||
+ .minio = 100,
|
||||
.checker_name = HP_SW,
|
||||
.prio_name = PRIO_HP_SW,
|
||||
},
|
||||
@@ -138,26 +138,11 @@ static struct hwentry default_hw[] = {
|
||||
.pgfailback = -FAILBACK_IMMEDIATE,
|
||||
.rr_weight = RR_WEIGHT_NONE,
|
||||
.no_path_retry = 12,
|
||||
- .minio = DEFAULT_MINIO,
|
||||
+ .minio = 100,
|
||||
.checker_name = TUR,
|
||||
.prio_name = PRIO_ALUA,
|
||||
},
|
||||
{
|
||||
- .vendor = "HP",
|
||||
- .product = "MSA2000s*",
|
||||
- .getuid = "/sbin/cciss_id %n",
|
||||
- .features = DEFAULT_FEATURES,
|
||||
- .hwhandler = DEFAULT_HWHANDLER,
|
||||
- .selector = DEFAULT_SELECTOR,
|
||||
- .pgpolicy = GROUP_BY_PRIO,
|
||||
- .pgfailback = -FAILBACK_IMMEDIATE,
|
||||
- .rr_weight = RR_WEIGHT_NONE,
|
||||
- .no_path_retry = 12,
|
||||
- .minio = DEFAULT_MINIO,
|
||||
- .checker_name = TUR,
|
||||
- .prio_name = DEFAULT_PRIO,
|
||||
- },
|
||||
- {
|
||||
/* EVA 3000/5000 with new firmware, EVA 4000/6000/8000 */
|
||||
.vendor = "(COMPAQ|HP)",
|
||||
.product = "HSV1[01]1|HSV2[01]0|HSV300",
|
||||
@@ -169,14 +154,14 @@ static struct hwentry default_hw[] = {
|
||||
.pgfailback = -FAILBACK_IMMEDIATE,
|
||||
.rr_weight = RR_WEIGHT_NONE,
|
||||
.no_path_retry = 12,
|
||||
- .minio = DEFAULT_MINIO,
|
||||
+ .minio = 100,
|
||||
.checker_name = TUR,
|
||||
.prio_name = PRIO_ALUA,
|
||||
},
|
||||
{
|
||||
- /* HP MSA2000 product family */
|
||||
+ /* HP MSA2000 product family with old firmware */
|
||||
.vendor = "HP",
|
||||
- .product = "MSA2[02]12*",
|
||||
+ .product = "MSA2[02]12fc|MSA2012i",
|
||||
.getuid = DEFAULT_GETUID,
|
||||
.features = DEFAULT_FEATURES,
|
||||
.hwhandler = DEFAULT_HWHANDLER,
|
||||
@@ -184,12 +169,46 @@ static struct hwentry default_hw[] = {
|
||||
.pgpolicy = MULTIBUS,
|
||||
.pgfailback = -FAILBACK_IMMEDIATE,
|
||||
.rr_weight = RR_WEIGHT_NONE,
|
||||
- .no_path_retry = 12,
|
||||
- .minio = DEFAULT_MINIO,
|
||||
+ .no_path_retry = 18,
|
||||
+ .minio = 100,
|
||||
.checker_name = TUR,
|
||||
.prio_name = DEFAULT_PRIO,
|
||||
},
|
||||
{
|
||||
+ /* HP MSA2000 product family with new firmware */
|
||||
+ .vendor = "HP",
|
||||
+ .product = "MSA2012sa|MSA23(12|24)(fc|i|sa)",
|
||||
+ .getuid = DEFAULT_GETUID,
|
||||
+ .features = DEFAULT_FEATURES,
|
||||
+ .hwhandler = DEFAULT_HWHANDLER,
|
||||
+ .selector = DEFAULT_SELECTOR,
|
||||
+ .pgpolicy = GROUP_BY_PRIO,
|
||||
+ .pgfailback = -FAILBACK_IMMEDIATE,
|
||||
+ .rr_weight = RR_WEIGHT_NONE,
|
||||
+ .no_path_retry = 18,
|
||||
+ .minio = 100,
|
||||
+ .checker_name = TUR,
|
||||
+ .prio_name = PRIO_ALUA,
|
||||
+ },
|
||||
+
|
||||
+ {
|
||||
+ /* HP SVSP */
|
||||
+ .vendor = "HP",
|
||||
+ .product = "HSVX700",
|
||||
+ .getuid = DEFAULT_GETUID,
|
||||
+ .features = DEFAULT_FEATURES,
|
||||
+ .hwhandler = "1 alua",
|
||||
+ .selector = DEFAULT_SELECTOR,
|
||||
+ .pgpolicy = GROUP_BY_PRIO,
|
||||
+ .pgfailback = -FAILBACK_IMMEDIATE,
|
||||
+ .rr_weight = RR_WEIGHT_NONE,
|
||||
+ .no_path_retry = 12,
|
||||
+ .minio = 100,
|
||||
+ .checker_name = TUR,
|
||||
+ .prio_name = PRIO_ALUA,
|
||||
+ },
|
||||
+
|
||||
+ {
|
||||
/* HP Smart Array */
|
||||
.vendor = "HP",
|
||||
.product = "LOGICAL VOLUME.*",
|
||||
@@ -294,7 +313,7 @@ static struct hwentry default_hw[] = {
|
||||
.vendor = "(HITACHI|HP)",
|
||||
.product = "OPEN-.*",
|
||||
.getuid = DEFAULT_GETUID,
|
||||
- .features = "1 queue_if_no_path",
|
||||
+ .features = DEFAULT_FEATURES,
|
||||
.hwhandler = DEFAULT_HWHANDLER,
|
||||
.selector = DEFAULT_SELECTOR,
|
||||
.pgpolicy = MULTIBUS,
|
103
multipath-tools-use-sys-dev
Normal file
103
multipath-tools-use-sys-dev
Normal file
@ -0,0 +1,103 @@
|
||||
From 734cf32be1f4bf3fa57bbdcc83147f92c4199b54 Mon Sep 17 00:00:00 2001
|
||||
From: Hannes Reinecke <hare@suse.de>
|
||||
Date: Thu, 20 Nov 2008 09:00:39 +0100
|
||||
Subject: [PATCH] Use /sys/dev for reverse lookup
|
||||
|
||||
Newer kernels provide /sys/dev for reverse lookup of major:minor
|
||||
numbers. Also some error checking is in order here.
|
||||
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
||||
---
|
||||
libmultipath/discovery.c | 35 ++++++++++++++++++++++++++++++-----
|
||||
1 files changed, 30 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
|
||||
index 20d0684..56186bd 100644
|
||||
--- a/libmultipath/discovery.c
|
||||
+++ b/libmultipath/discovery.c
|
||||
@@ -152,11 +152,11 @@ sysfs_get_dev (struct sysfs_device * dev, char * buff, size_t len)
|
||||
|
||||
attr = sysfs_attr_get_value(dev->devpath, "dev");
|
||||
if (!attr) {
|
||||
- condlog(3, "%s: no 'dev' attribute in sysfs", dev->kernel);
|
||||
+ condlog(3, "%s: no 'dev' attribute in sysfs", dev->devpath);
|
||||
return 1;
|
||||
}
|
||||
if (strlcpy(buff, attr, len) != strlen(attr)) {
|
||||
- condlog(3, "%s: overflow in 'dev' attribute", dev->kernel);
|
||||
+ condlog(3, "%s: overflow in 'dev' attribute", dev->devpath);
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
@@ -169,13 +169,18 @@ sysfs_get_size (struct sysfs_device * dev, unsigned long long * size)
|
||||
int r;
|
||||
|
||||
attr = sysfs_attr_get_value(dev->devpath, "size");
|
||||
- if (!attr)
|
||||
+ if (!attr) {
|
||||
+ condlog(3, "%s: No size attribute in sysfs", dev->devpath);
|
||||
return 1;
|
||||
+ }
|
||||
|
||||
r = sscanf(attr, "%llu\n", size);
|
||||
|
||||
- if (r != 1)
|
||||
+ if (r != 1) {
|
||||
+ condlog(3, "%s: Cannot parse size attribute '%s'",
|
||||
+ dev->devpath, attr);
|
||||
return 1;
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -232,12 +237,30 @@ devt2devname (char *devname, char *devt)
|
||||
char block_path[FILE_NAME_SIZE];
|
||||
struct stat statbuf;
|
||||
|
||||
- memset(block_path, 0, FILE_NAME_SIZE);
|
||||
if (sscanf(devt, "%u:%u", &major, &minor) != 2) {
|
||||
condlog(0, "Invalid device number %s", devt);
|
||||
return 1;
|
||||
}
|
||||
|
||||
+ sprintf(block_path,"/sys/dev/%u:%u", major, minor);
|
||||
+ if (stat(block_path, &statbuf) == 0) {
|
||||
+ /* Newer kernels have /sys/dev */
|
||||
+ if (S_ISLNK(statbuf.st_mode) &&
|
||||
+ readlink(block_path, dev, FILE_NAME_SIZE) > 0) {
|
||||
+ char *p = strrchr(dev, '/');
|
||||
+
|
||||
+ if (!p) {
|
||||
+ condlog(0, "No sysfs entry for %s\n",
|
||||
+ block_path);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ p++;
|
||||
+ strncpy(devname, p, FILE_NAME_SIZE);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ memset(block_path, 0, FILE_NAME_SIZE);
|
||||
+
|
||||
if (!(fd = fopen("/proc/partitions", "r"))) {
|
||||
condlog(0, "Cannot open /proc/partitions");
|
||||
return 1;
|
||||
@@ -271,6 +294,7 @@ devt2devname (char *devname, char *devt)
|
||||
condlog(0, "sysfs entry %s is not a directory\n", block_path);
|
||||
return 1;
|
||||
}
|
||||
+ strncpy(devname, dev, FILE_NAME_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -291,6 +315,7 @@ do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
|
||||
inqCmdBlk[3] = (unsigned char)((mx_resp_len >> 8) & 0xff);
|
||||
inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
|
||||
memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
|
||||
+ memset(sense_b, 0, SENSE_BUFF_LEN);
|
||||
io_hdr.interface_id = 'S';
|
||||
io_hdr.cmd_len = sizeof (inqCmdBlk);
|
||||
io_hdr.mx_sb_len = sizeof (sense_b);
|
||||
--
|
||||
1.5.3.2
|
||||
|
40
multipath-tools-zero-lines-in-print.c
Normal file
40
multipath-tools-zero-lines-in-print.c
Normal file
@ -0,0 +1,40 @@
|
||||
commit 8fe887aa6875dfbb5057c9b1e4e8c91445700de5
|
||||
Author: Hannes Reinecke <hare@suse.de>
|
||||
Date: Fri Nov 14 10:02:56 2008 +0100
|
||||
|
||||
libmultipath: zero out lines in print.c
|
||||
|
||||
static declaration of line within a function doesn't place them in
|
||||
the bss segment, hence they are not zeroed automatically.
|
||||
Gives funny effects occasionally.
|
||||
|
||||
Signed-off-by: Hannes Reinecke <hare@suse.de>
|
||||
|
||||
diff --git a/libmultipath/print.c b/libmultipath/print.c
|
||||
index 6d80248..46ae2ec 100644
|
||||
--- a/libmultipath/print.c
|
||||
+++ b/libmultipath/print.c
|
||||
@@ -1246,6 +1246,7 @@ print_path (struct path * pp, char * style)
|
||||
{
|
||||
char line[MAX_LINE_LEN];
|
||||
|
||||
+ memset(&line[0], 0, MAX_LINE_LEN);
|
||||
snprint_path(&line[0], MAX_LINE_LEN, style, pp);
|
||||
printf("%s", line);
|
||||
}
|
||||
@@ -1255,6 +1256,7 @@ print_multipath (struct multipath * mpp, char * style)
|
||||
{
|
||||
char line[MAX_LINE_LEN];
|
||||
|
||||
+ memset(&line[0], 0, MAX_LINE_LEN);
|
||||
snprint_multipath(&line[0], MAX_LINE_LEN, style, mpp);
|
||||
printf("%s", line);
|
||||
}
|
||||
@@ -1264,6 +1266,7 @@ print_pathgroup (struct pathgroup * pgp, char * style)
|
||||
{
|
||||
char line[MAX_LINE_LEN];
|
||||
|
||||
+ memset(&line[0], 0, MAX_LINE_LEN);
|
||||
snprint_pathgroup(&line[0], MAX_LINE_LEN, style, pgp);
|
||||
printf("%s", line);
|
||||
}
|
@ -1,3 +1,29 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Nov 21 14:07:56 CET 2008 - hare@suse.de
|
||||
|
||||
- Add 'Weighted Paths' prioritizer (bnc#441007)
|
||||
- Fix crashes in update_multipath
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Nov 20 16:10:48 CET 2008 - hare@suse.de
|
||||
|
||||
- Valgrind fixes
|
||||
* Add missing initialisation
|
||||
* Always allocate memory for alias
|
||||
* Check return value of basename
|
||||
- Adapt to new sysfs layout (bnc#435215, bnc#445041)
|
||||
- Use /sys/dev to speedup reverse lookups
|
||||
- Rework sysfs device handling (bnc#435215, bnc#438031)
|
||||
- Search for correct hardware entry during reconfigure (bnc#435688)
|
||||
- Use local variables for device mapper params
|
||||
- Allow zero paths for multipath maps
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Nov 17 12:42:34 CET 2008 - hare@suse.de
|
||||
|
||||
- Update HP hardware table (bnc#442133)
|
||||
- Zero out lines in print.c (bnc#445023)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Nov 10 08:51:26 CET 2008 - hare@suse.de
|
||||
|
||||
|
@ -27,7 +27,7 @@ Requires: device-mapper kpartx
|
||||
PreReq: %insserv_prereq %fillup_prereq coreutils grep diffutils
|
||||
AutoReqProv: on
|
||||
Version: 0.4.8
|
||||
Release: 25
|
||||
Release: 26
|
||||
Summary: Tools to Manage Multipathed Devices with the device-mapper
|
||||
Source: multipath-tools-%{version}.tar.bz2
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
@ -56,6 +56,19 @@ Patch21: %{name}-link-directio-against-libaio
|
||||
Patch22: %{name}-check-for-empty-mpvecs
|
||||
Patch23: %{name}-dmraid-uuid-in-uppercase
|
||||
Patch24: %{name}-handle-arguments-from-init-file
|
||||
Patch25: %{name}-update-hp-hwtable
|
||||
Patch26: %{name}-zero-lines-in-print.c
|
||||
Patch27: %{name}-sles11-valgrind-fixes
|
||||
Patch28: %{name}-adapt-to-new-sysfs-layout
|
||||
Patch29: %{name}-basename-return-value
|
||||
Patch30: %{name}-always-allocate-alias
|
||||
Patch31: %{name}-use-sys-dev
|
||||
Patch32: %{name}-rework-sysfs-device-handling
|
||||
Patch33: %{name}-search-for-correct-hwe
|
||||
Patch34: %{name}-make-params-local
|
||||
Patch35: %{name}-allow-zero-paths
|
||||
Patch36: %{name}-prio-weightedpath
|
||||
Patch37: %{name}-crash-in-update-multipath
|
||||
|
||||
%description
|
||||
This package provides the tools to manage multipathed devices by
|
||||
@ -121,6 +134,19 @@ Authors:
|
||||
%patch22 -p1
|
||||
%patch23 -p1
|
||||
%patch24 -p1
|
||||
%patch25 -p1
|
||||
%patch26 -p1
|
||||
%patch27 -p1
|
||||
%patch28 -p1
|
||||
%patch29 -p1
|
||||
%patch30 -p1
|
||||
%patch31 -p1
|
||||
%patch32 -p1
|
||||
%patch33 -p1
|
||||
%patch34 -p1
|
||||
%patch35 -p1
|
||||
%patch36 -p1
|
||||
%patch37 -p1
|
||||
|
||||
%build
|
||||
make OPTFLAGS="$RPM_OPT_FLAGS"
|
||||
@ -182,6 +208,23 @@ exit 0
|
||||
%{_mandir}/man8/kpartx.8*
|
||||
|
||||
%changelog
|
||||
* Fri Nov 21 2008 hare@suse.de
|
||||
- Add 'Weighted Paths' prioritizer (bnc#441007)
|
||||
- Fix crashes in update_multipath
|
||||
* Thu Nov 20 2008 hare@suse.de
|
||||
- Valgrind fixes
|
||||
* Add missing initialisation
|
||||
* Always allocate memory for alias
|
||||
* Check return value of basename
|
||||
- Adapt to new sysfs layout (bnc#435215, bnc#445041)
|
||||
- Use /sys/dev to speedup reverse lookups
|
||||
- Rework sysfs device handling (bnc#435215, bnc#438031)
|
||||
- Search for correct hardware entry during reconfigure (bnc#435688)
|
||||
- Use local variables for device mapper params
|
||||
- Allow zero paths for multipath maps
|
||||
* Mon Nov 17 2008 hare@suse.de
|
||||
- Update HP hardware table (bnc#442133)
|
||||
- Zero out lines in print.c (bnc#445023)
|
||||
* Mon Nov 10 2008 hare@suse.de
|
||||
- Check for empty mpvecs in mpvec_garbage_collector() (bnc#437245)
|
||||
- dmraid uuid starts with 'DMRAID' (bnc#439439)
|
||||
|
Loading…
Reference in New Issue
Block a user