OBS User unknown 2008-11-21 14:37:31 +00:00 committed by Git OBS Bridge
parent a03d4e1ef9
commit 631b272723
16 changed files with 2932 additions and 10 deletions

View 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

View 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

View 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

View 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

View 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);

View 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

View 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

View 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

View 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

View File

@ -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",

View 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);

View 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
View 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

View 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);
}

View File

@ -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

View File

@ -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)