Updated to latest upstream 0.4.9 code : multipath-tools-120123.tgz

(git commit id: 63704387009443bdb37d9deaaafa9ab121d45bfb)
Add 0001-RH-fix-async-tur.patch
Add 0002-RH-dont_start_with_no_config.patch
Add 0003-RH-multipath.rules.patch
Add 0004-RH-update-init-script.patch
Add 0005-RH-cciss_id.patch
Add 0006-RH-Make-build-system-RH-Fedora-friendly.patch
Add 0007-RH-multipathd-blacklist-all-by-default.patch
Add 0008-RH-add-mpathconf.patch
Add 0009-RH-add-find-multipaths.patch
Add 0010-RH-check-if-multipath-owns-path.patch
Add 0011-RH-add-hp_tur-checker.patch
This commit is contained in:
Benjamin Marzinski 2012-01-24 10:35:54 -06:00
parent 8d4103df73
commit a1478bc1bc
114 changed files with 1334 additions and 10768 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
multipath-tools-091027.tar.gz multipath-tools-091027.tar.gz
/multipath-tools-120123.tgz

242
0001-RH-fix-async-tur.patch Normal file
View File

@ -0,0 +1,242 @@
---
libmultipath/checkers/tur.c | 85 +++++++++++++++++++++++++++++++++-----------
libmultipath/discovery.c | 1
2 files changed, 65 insertions(+), 21 deletions(-)
Index: multipath-tools-120123/libmultipath/checkers/tur.c
===================================================================
--- multipath-tools-120123.orig/libmultipath/checkers/tur.c
+++ multipath-tools-120123/libmultipath/checkers/tur.c
@@ -35,10 +35,15 @@ struct tur_checker_context {
dev_t devt;
int state;
int running;
- time_t timeout;
+ int fd;
+ unsigned int timeout;
+ time_t time;
pthread_t thread;
pthread_mutex_t lock;
pthread_cond_t active;
+ pthread_spinlock_t hldr_lock;
+ int holders;
+ char message[CHECKER_MSG_LEN];
};
#define TUR_DEVT(c) major((c)->devt), minor((c)->devt)
@@ -53,28 +58,49 @@ int libcheck_init (struct checker * c)
memset(ct, 0, sizeof(struct tur_checker_context));
ct->state = PATH_UNCHECKED;
+ ct->fd = -1;
+ ct->holders = 1;
pthread_cond_init(&ct->active, NULL);
pthread_mutex_init(&ct->lock, NULL);
+ pthread_spin_init(&ct->hldr_lock, PTHREAD_PROCESS_PRIVATE);
c->context = ct;
return 0;
}
+void cleanup_context(struct tur_checker_context *ct)
+{
+ pthread_mutex_destroy(&ct->lock);
+ pthread_cond_destroy(&ct->active);
+ pthread_spin_destroy(&ct->hldr_lock);
+ free(ct);
+}
+
void libcheck_free (struct checker * c)
{
if (c->context) {
struct tur_checker_context *ct = c->context;
+ int holders;
+ pthread_t thread;
- pthread_mutex_destroy(&ct->lock);
- pthread_cond_destroy(&ct->active);
- free(c->context);
+ pthread_spin_lock(&ct->hldr_lock);
+ ct->holders--;
+ holders = ct->holders;
+ thread = ct->thread;
+ pthread_spin_unlock(&ct->hldr_lock);
+ if (holders)
+ pthread_cancel(thread);
+ else
+ cleanup_context(ct);
c->context = NULL;
}
return;
}
+#define TUR_MSG(msg, fmt, args...) snprintf(msg, CHECKER_MSG_LEN, fmt, ##args);
+
int
-tur_check (struct checker * c)
+tur_check(int fd, unsigned int timeout, char *msg)
{
struct sg_io_hdr io_hdr;
unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 };
@@ -90,10 +116,10 @@ tur_check (struct checker * c)
io_hdr.dxfer_direction = SG_DXFER_NONE;
io_hdr.cmdp = turCmdBlk;
io_hdr.sbp = sense_buffer;
- io_hdr.timeout = c->timeout;
+ io_hdr.timeout = timeout;
io_hdr.pack_id = 0;
- if (ioctl(c->fd, SG_IO, &io_hdr) < 0) {
- MSG(c, MSG_TUR_DOWN);
+ if (ioctl(fd, SG_IO, &io_hdr) < 0) {
+ TUR_MSG(msg, MSG_TUR_DOWN);
return PATH_DOWN;
}
if ((io_hdr.status & 0x7e) == 0x18) {
@@ -101,7 +127,7 @@ tur_check (struct checker * c)
* SCSI-3 arrays might return
* reservation conflict on TUR
*/
- MSG(c, MSG_TUR_UP);
+ TUR_MSG(msg, MSG_TUR_UP);
return PATH_UP;
}
if (io_hdr.info & SG_INFO_OK_MASK) {
@@ -146,14 +172,14 @@ tur_check (struct checker * c)
* LOGICAL UNIT NOT ACCESSIBLE,
* TARGET PORT IN STANDBY STATE
*/
- MSG(c, MSG_TUR_GHOST);
+ TUR_MSG(msg, MSG_TUR_GHOST);
return PATH_GHOST;
}
}
- MSG(c, MSG_TUR_DOWN);
+ TUR_MSG(msg, MSG_TUR_DOWN);
return PATH_DOWN;
}
- MSG(c, MSG_TUR_UP);
+ TUR_MSG(msg, MSG_TUR_UP);
return PATH_UP;
}
@@ -162,18 +188,25 @@ tur_check (struct checker * c)
void cleanup_func(void *data)
{
+ int holders;
struct tur_checker_context *ct = data;
+ pthread_spin_lock(&ct->hldr_lock);
+ ct->holders--;
+ holders = ct->holders;
ct->thread = 0;
+ pthread_spin_unlock(&ct->hldr_lock);
+ if (!holders)
+ cleanup_context(ct);
}
void *tur_thread(void *ctx)
{
- struct checker *c = ctx;
- struct tur_checker_context *ct = c->context;
+ struct tur_checker_context *ct = ctx;
int state;
condlog(3, "%d:%d: tur checker starting up", TUR_DEVT(ct));
+ ct->message[0] = '\0';
/* This thread can be canceled, so setup clean up */
tur_thread_cleanup_push(ct)
@@ -182,7 +215,7 @@ void *tur_thread(void *ctx)
ct->state = PATH_PENDING;
pthread_mutex_unlock(&ct->lock);
- state = tur_check(c);
+ state = tur_check(ct->fd, ct->timeout, ct->message);
/* TUR checker done */
pthread_mutex_lock(&ct->lock);
@@ -213,7 +246,7 @@ void tur_set_async_timeout(struct checke
struct timeval now;
gettimeofday(&now, NULL);
- ct->timeout = now.tv_sec + c->timeout;
+ ct->time = now.tv_sec + c->timeout;
}
int tur_check_async_timeout(struct checker *c)
@@ -222,7 +255,7 @@ int tur_check_async_timeout(struct check
struct timeval now;
gettimeofday(&now, NULL);
- return (now.tv_sec > ct->timeout);
+ return (now.tv_sec > ct->time);
}
extern int
@@ -242,7 +275,7 @@ libcheck_check (struct checker * c)
ct->devt = sb.st_rdev;
if (c->sync)
- return tur_check(c);
+ return tur_check(c->fd, c->timeout, c->message);
/*
* Async mode
@@ -276,6 +309,8 @@ libcheck_check (struct checker * c)
/* TUR checker done */
ct->running = 0;
tur_status = ct->state;
+ strncpy(c->message, ct->message, CHECKER_MSG_LEN);
+ c->message[CHECKER_MSG_LEN - 1] = '\0';
}
pthread_mutex_unlock(&ct->lock);
} else {
@@ -284,24 +319,32 @@ libcheck_check (struct checker * c)
pthread_mutex_unlock(&ct->lock);
condlog(3, "%d:%d: tur thread not responding, "
"using sync mode", TUR_DEVT(ct));
- return tur_check(c);
+ return tur_check(c->fd, c->timeout, c->message);
}
/* Start new TUR checker */
ct->state = PATH_UNCHECKED;
+ ct->fd = c->fd;
+ ct->timeout = c->timeout;
+ pthread_spin_lock(&ct->hldr_lock);
+ ct->holders++;
+ pthread_spin_unlock(&ct->hldr_lock);
tur_set_async_timeout(c);
setup_thread_attr(&attr, 32 * 1024, 1);
- r = pthread_create(&ct->thread, &attr, tur_thread, c);
+ r = pthread_create(&ct->thread, &attr, tur_thread, ct);
if (r) {
pthread_mutex_unlock(&ct->lock);
ct->thread = 0;
+ ct->holders--;
condlog(3, "%d:%d: failed to start tur thread, using"
" sync mode", TUR_DEVT(ct));
- return tur_check(c);
+ return tur_check(c->fd, c->timeout, c->message);
}
pthread_attr_destroy(&attr);
tur_timeout(&tsp);
r = pthread_cond_timedwait(&ct->active, &ct->lock, &tsp);
tur_status = ct->state;
+ strncpy(c->message, ct->message,CHECKER_MSG_LEN);
+ c->message[CHECKER_MSG_LEN -1] = '\0';
pthread_mutex_unlock(&ct->lock);
if (ct->thread &&
(tur_status == PATH_PENDING || tur_status == PATH_UNCHECKED)) {
Index: multipath-tools-120123/libmultipath/discovery.c
===================================================================
--- multipath-tools-120123.orig/libmultipath/discovery.c
+++ multipath-tools-120123/libmultipath/discovery.c
@@ -842,6 +842,7 @@ get_state (struct path * pp, int daemon)
}
checker_set_fd(c, pp->fd);
if (checker_init(c, pp->mpp?&pp->mpp->mpcontext:NULL)) {
+ memset(c, 0x0, sizeof(struct checker));
condlog(3, "%s: checker init failed", pp->dev);
return PATH_UNCHECKED;
}

View File

@ -1,165 +0,0 @@
From 8191fb07d8212e29ad44370abb60e174e1c34bb5 Mon Sep 17 00:00:00 2001
From: Fabio M. Di Nitto <fdinitto@redhat.com>
Date: Tue, 13 Oct 2009 08:15:15 +0200
Subject: [PATCH 01/12] RH: queue without daemon
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
---
:100644 100644 50a728c... 86b1320... M libmultipath/config.h
:100644 100644 ee4de68... 7888e8e... M libmultipath/dict.c
:100644 100644 afd1246... 2e7a0d1... M libmultipath/structs.h
:100644 100644 c222da4... 9afa615... M multipath.conf.annotated
:100644 100644 3e0fd6e... 44d1329... M multipath.conf.synthetic
:100644 100644 41a9bd0... 90de6df... M multipathd/main.c
libmultipath/config.h | 1 +
libmultipath/dict.c | 35 +++++++++++++++++++++++++++++++++++
libmultipath/structs.h | 6 ++++++
multipath.conf.annotated | 9 +++++++++
multipath.conf.synthetic | 1 +
multipathd/main.c | 5 +++++
6 files changed, 57 insertions(+), 0 deletions(-)
Index: multipath-tools/libmultipath/config.h
===================================================================
--- multipath-tools.orig/libmultipath/config.h
+++ multipath-tools/libmultipath/config.h
@@ -74,6 +74,7 @@ struct config {
int pg_timeout;
int max_fds;
int force_reload;
+ int queue_without_daemon;
int daemon;
int flush_on_last_del;
int attribute_flags;
Index: multipath-tools/libmultipath/dict.c
===================================================================
--- multipath-tools.orig/libmultipath/dict.c
+++ multipath-tools/libmultipath/dict.c
@@ -362,6 +362,28 @@ def_no_path_retry_handler(vector strvec)
}
static int
+def_queue_without_daemon(vector strvec)
+{
+ char * buff;
+
+ buff = set_value(strvec);
+ if (!buff)
+ return 1;
+
+ if (!strncmp(buff, "off", 3) || !strncmp(buff, "no", 2) ||
+ !strncmp(buff, "0", 1))
+ conf->queue_without_daemon = QUE_NO_DAEMON_OFF;
+ else if (!strncmp(buff, "on", 2) || !strncmp(buff, "yes", 3) ||
+ !strncmp(buff, "1", 1))
+ conf->queue_without_daemon = QUE_NO_DAEMON_ON;
+ else
+ conf->queue_without_daemon = QUE_NO_DAEMON_UNDEF;
+
+ free(buff);
+ return 0;
+}
+
+static int
def_pg_timeout_handler(vector strvec)
{
int pg_timeout;
@@ -1944,6 +1966,18 @@ snprint_def_no_path_retry (char * buff,
}
static int
+snprint_def_queue_without_daemon (char * buff, int len, void * data)
+{
+ switch (conf->queue_without_daemon) {
+ case QUE_NO_DAEMON_OFF:
+ return snprintf(buff, len, "no");
+ case QUE_NO_DAEMON_ON:
+ return snprintf(buff, len, "yes");
+ }
+ return 0;
+}
+
+static int
snprint_def_pg_timeout (char * buff, int len, void * data)
{
if (conf->pg_timeout == DEFAULT_PGTIMEOUT)
@@ -2029,6 +2063,7 @@ init_keywords(void)
install_keyword("max_fds", &max_fds_handler, &snprint_max_fds);
install_keyword("rr_weight", &def_weight_handler, &snprint_def_rr_weight);
install_keyword("no_path_retry", &def_no_path_retry_handler, &snprint_def_no_path_retry);
+ install_keyword("queue_without_daemon", &def_queue_without_daemon, &snprint_def_queue_without_daemon);
install_keyword("pg_timeout", &def_pg_timeout_handler, &snprint_def_pg_timeout);
install_keyword("flush_on_last_del", &def_flush_on_last_del_handler, &snprint_def_flush_on_last_del);
install_keyword("user_friendly_names", &names_handler, &snprint_def_user_friendly_names);
Index: multipath-tools/libmultipath/structs.h
===================================================================
--- multipath-tools.orig/libmultipath/structs.h
+++ multipath-tools/libmultipath/structs.h
@@ -63,6 +63,12 @@ enum pgstates {
PGSTATE_ACTIVE
};
+enum queue_without_daemon_states {
+ QUE_NO_DAEMON_UNDEF,
+ QUE_NO_DAEMON_OFF,
+ QUE_NO_DAEMON_ON,
+};
+
enum pgtimeouts {
PGTIMEOUT_UNDEF,
PGTIMEOUT_NONE
Index: multipath-tools/multipath.conf.annotated
===================================================================
--- multipath-tools.orig/multipath.conf.annotated
+++ multipath-tools/multipath.conf.annotated
@@ -153,6 +153,15 @@
# no_path_retry queue
#
# #
+# # name : queue_without_daemon
+# # scope : multipathd
+# # desc : If set to "no", multipathd will disable queueing for all
+# # devices when it is shut down.
+# # values : yes|no
+# # default : yes
+# queue_without_daemon no
+#
+# #
# # name : user_friendly_names
# # scope : multipath
# # desc : If set to "yes", using the bindings file
Index: multipath-tools/multipath.conf.synthetic
===================================================================
--- multipath-tools.orig/multipath.conf.synthetic
+++ multipath-tools/multipath.conf.synthetic
@@ -16,6 +16,7 @@
# rr_weight priorities
# failback immediate
# no_path_retry fail
+# queue_without_daemon no
# user_friendly_names no
# mode 644
# uid 0
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -1334,6 +1334,8 @@ child (void * param)
pthread_t check_thr, uevent_thr, uxlsnr_thr;
pthread_attr_t log_attr, misc_attr;
struct vectors * vecs;
+ struct multipath * mpp;
+ int i;
mlockall(MCL_CURRENT | MCL_FUTURE);
@@ -1422,6 +1424,9 @@ child (void * param)
*/
block_signal(SIGHUP, NULL);
lock(vecs->lock);
+ if (conf->queue_without_daemon == QUE_NO_DAEMON_OFF)
+ vector_foreach_slot(vecs->mpvec, mpp, i)
+ dm_queue_if_no_path(mpp->alias, 0);
remove_maps_and_stop_waiters(vecs);
free_pathvec(vecs->pathvec, FREE_PATHS);

View File

@ -1,123 +0,0 @@
From faf6bfc96b98562626e0ea12aecb582032ff4cab Mon Sep 17 00:00:00 2001
From: Fabio M. Di Nitto <fdinitto@redhat.com>
Date: Mon, 19 Oct 2009 07:02:02 +0200
Subject: [PATCH 1/1] for-upstream: add tpg_pref prioritizer
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
---
:100644 100644 fc9277f... 1f40859... M libmultipath/prio.h
:100644 100644 949a60a... 5021c04... M libmultipath/prioritizers/Makefile
:100644 100644 0048a44... 22513ab... M libmultipath/prioritizers/alua.c
:100644 100644 0531052... cd9c29d... M libmultipath/prioritizers/alua_rtpg.c
:100644 100644 bddbbdd... daf95a6... M libmultipath/prioritizers/alua_spc3.h
libmultipath/prio.h | 1 +
libmultipath/prioritizers/Makefile | 10 ++++++++++
libmultipath/prioritizers/alua.c | 7 +++++++
libmultipath/prioritizers/alua_rtpg.c | 4 ++++
libmultipath/prioritizers/alua_spc3.h | 6 ++++++
5 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/libmultipath/prio.h b/libmultipath/prio.h
index fc9277f..1f40859 100644
--- a/libmultipath/prio.h
+++ b/libmultipath/prio.h
@@ -16,6 +16,7 @@
* Known prioritizers for use in hwtable.c
*/
#define PRIO_ALUA "alua"
+#define PRIO_TPG_PREF "tpg_pref"
#define PRIO_CONST "const"
#define PRIO_EMC "emc"
#define PRIO_HDS "hds"
diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile
index 949a60a..5021c04 100644
--- a/libmultipath/prioritizers/Makefile
+++ b/libmultipath/prioritizers/Makefile
@@ -11,6 +11,7 @@ LIBS = \
libprioemc.so \
libpriordac.so \
libprioalua.so \
+ libpriotpg_pref.so \
libprionetapp.so \
libpriohds.so
@@ -21,9 +22,18 @@ all: $(LIBS)
libprioalua.so: alua.o alua_rtpg.o
$(CC) $(SHARED_FLAGS) -o $@ $^
+libpriotpg_pref.so: pref.o pref_rtpg.o
+ $(CC) $(SHARED_FLAGS) -o $@ $^
+
libprio%.so: %.o
$(CC) $(SHARED_FLAGS) -o $@ $^
+pref.o: alua.c
+ $(CC) $(CFLAGS) -DTPG_PREF -c -o $@ $<
+
+pref_rtpg.o: alua_rtpg.c
+ $(CC) $(CFLAGS) -DTPG_PREF -c -o $@ $<
+
install: $(LIBS)
$(INSTALL_PROGRAM) -m 755 libprio*.so $(DESTDIR)$(libdir)
diff --git a/libmultipath/prioritizers/alua.c b/libmultipath/prioritizers/alua.c
index 0048a44..22513ab 100644
--- a/libmultipath/prioritizers/alua.c
+++ b/libmultipath/prioritizers/alua.c
@@ -28,6 +28,12 @@
int
get_alua_info(int fd)
{
+#ifdef TPG_PREF
+ char * aas_string[] = {
+ [AAS_OPTIMIZED] = "preferred",
+ [AAS_STANDBY] = "non-preferred",
+ };
+#else
char * aas_string[] = {
[AAS_OPTIMIZED] = "active/optimized",
[AAS_NON_OPTIMIZED] = "active/non-optimized",
@@ -35,6 +41,7 @@ get_alua_info(int fd)
[AAS_UNAVAILABLE] = "unavailable",
[AAS_TRANSITIONING] = "transitioning between states",
};
+#endif
int rc;
int tpg;
diff --git a/libmultipath/prioritizers/alua_rtpg.c b/libmultipath/prioritizers/alua_rtpg.c
index 0531052..cd9c29d 100644
--- a/libmultipath/prioritizers/alua_rtpg.c
+++ b/libmultipath/prioritizers/alua_rtpg.c
@@ -293,7 +293,11 @@ get_asymmetric_access_state(int fd, unsigned int tpg)
"group.\n");
} else {
PRINT_DEBUG("pref=%i\n", dscr->b0);
+#ifdef TPG_PREF
+ rc = rtpg_tpg_dscr_get_pref(dscr);
+#else
rc = rtpg_tpg_dscr_get_aas(dscr);
+#endif
}
}
}
diff --git a/libmultipath/prioritizers/alua_spc3.h b/libmultipath/prioritizers/alua_spc3.h
index bddbbdd..daf95a6 100644
--- a/libmultipath/prioritizers/alua_spc3.h
+++ b/libmultipath/prioritizers/alua_spc3.h
@@ -302,6 +302,12 @@ rtpg_tpg_dscr_get_aas(struct rtpg_tpg_dscr *d)
return (d->b0 & 0x0f);
}
+static inline int
+rtpg_tpg_dscr_get_pref(struct rtpg_tpg_dscr *d)
+{
+ return ((d->b0 & 0x80)?AAS_OPTIMIZED:AAS_STANDBY);
+}
+
struct rtpg_data {
unsigned char length[4]; /* size-4 */
struct rtpg_tpg_dscr data[0];
--
1.6.5.1

View File

@ -0,0 +1,16 @@
---
multipathd/multipathd.service | 1 +
1 file changed, 1 insertion(+)
Index: multipath-tools-110916/multipathd/multipathd.service
===================================================================
--- multipath-tools-110916.orig/multipathd/multipathd.service
+++ multipath-tools-110916/multipathd/multipathd.service
@@ -2,6 +2,7 @@
Description=Device-Mapper Multipath Device Controller
Before=iscsi.service iscsid.service
After=syslog.target
+ConditionPathExists=/etc/multipath.conf
[Service]
Type=forking

View File

@ -1,198 +0,0 @@
From f9ddbc18b7580f75c15bf6f3e10f08d6f016caca Mon Sep 17 00:00:00 2001
From: Fabio M. Di Nitto <fdinitto@redhat.com>
Date: Tue, 13 Oct 2009 08:18:00 +0200
Subject: [PATCH 02/12] RH: path checker
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
---
:100644 100644 e06dc52... 47107a2... M libmultipath/checkers/tur.c
:100644 100644 98d1618... 00aa5ea... M libmultipath/discovery.c
:100644 100644 7283f36... 17cd4af... M libmultipath/discovery.h
:100644 100644 90de6df... 5d3625a... M multipathd/main.c
libmultipath/checkers/tur.c | 1 -
libmultipath/discovery.c | 62 +++++++++++++++++++++++++++++++++---------
libmultipath/discovery.h | 2 +
multipathd/main.c | 21 +-------------
4 files changed, 52 insertions(+), 34 deletions(-)
Index: multipath-tools/libmultipath/checkers/tur.c
===================================================================
--- multipath-tools.orig/libmultipath/checkers/tur.c
+++ multipath-tools/libmultipath/checkers/tur.c
@@ -69,7 +69,6 @@ libcheck_check (struct checker * c)
case DID_NO_CONNECT:
case DID_BAD_TARGET:
case DID_ABORT:
- case DID_TRANSPORT_DISRUPTED:
case DID_TRANSPORT_FAILFAST:
break;
default:
Index: multipath-tools/libmultipath/discovery.c
===================================================================
--- multipath-tools.orig/libmultipath/discovery.c
+++ multipath-tools/libmultipath/discovery.c
@@ -616,10 +616,9 @@ struct sysfs_device *sysfs_device_from_p
}
int
-path_offline (struct path * pp)
+path_state (struct path * pp, char * buff)
{
struct sysfs_device * parent;
- char buff[SCSI_STATE_SIZE];
pp->sysdev = sysfs_device_from_path(pp);
if (!pp->sysdev) {
@@ -641,6 +640,16 @@ path_offline (struct path * pp)
return 1;
condlog(3, "%s: state = %s", pp->dev, buff);
+ return 0;
+}
+
+int
+path_offline (struct path * pp)
+{
+ char buff[SCSI_STATE_SIZE];
+
+ if (path_state(pp, buff))
+ return 1;
if (!strncmp(buff, "offline", 7)) {
pp->offline = 1;
@@ -650,6 +659,21 @@ path_offline (struct path * pp)
return 0;
}
+int
+path_blocked (struct path * pp)
+{
+ char buff[SCSI_STATE_SIZE];
+
+ if (pp->bus != SYSFS_BUS_SCSI)
+ return 0;
+ if (path_state(pp, buff))
+ return 0;
+ if (!strncmp(buff, "blocked", 7)) {
+ return 1;
+ }
+ return 0;
+}
+
extern int
sysfs_pathinfo(struct path * pp)
{
@@ -736,36 +760,43 @@ cciss_ioctl_pathinfo (struct path * pp,
return 0;
}
-static int
-get_state (struct path * pp)
+int
+get_state (struct path * pp, int daemon)
{
struct checker * c = &pp->checker;
+ int state;
condlog(3, "%s: get_state", pp->dev);
if (!checker_selected(c)) {
+ if (daemon)
+ pathinfo(pp, conf->hwtable, DI_SYSFS);
select_checker(pp);
if (!checker_selected(c)) {
condlog(3, "%s: No checker selected", pp->dev);
- return 1;
+ return PATH_UNCHECKED;
}
checker_set_fd(c, pp->fd);
if (checker_init(c, pp->mpp?&pp->mpp->mpcontext:NULL)) {
condlog(3, "%s: checker init failed", pp->dev);
- return 1;
+ return PATH_UNCHECKED;
}
}
if (path_offline(pp)) {
condlog(3, "%s: path offline", pp->dev);
- pp->state = PATH_DOWN;
- return 0;
+ return PATH_DOWN;
}
- pp->state = checker_check(c);
- condlog(3, "%s: state = %i", pp->dev, pp->state);
- if (pp->state == PATH_DOWN && strlen(checker_message(c)))
+ if (daemon) {
+ if (path_blocked(pp))
+ return PATH_PENDING;
+ checker_set_async(c);
+ }
+ state = checker_check(c);
+ condlog(3, "%s: state = %i", pp->dev, state);
+ if (state == PATH_DOWN && strlen(checker_message(c)))
condlog(3, "%s: checker msg is \"%s\"",
pp->dev, checker_message(c));
- return 0;
+ return state;
}
static int
@@ -850,8 +881,11 @@ pathinfo (struct path *pp, vector hwtabl
cciss_ioctl_pathinfo(pp, mask))
goto blank;
- if (mask & DI_CHECKER && get_state(pp))
- goto blank;
+ if (mask & DI_CHECKER) {
+ pp->state = get_state(pp, 0);
+ if (pp->state == PATH_UNCHECKED || pp->state == PATH_WILD)
+ goto blank;
+ }
/*
* Retrieve path priority, even for PATH_DOWN paths if it has never
Index: multipath-tools/libmultipath/discovery.h
===================================================================
--- multipath-tools.orig/libmultipath/discovery.h
+++ multipath-tools/libmultipath/discovery.h
@@ -30,6 +30,8 @@ int path_discovery (vector pathvec, stru
int do_tur (char *);
int devt2devname (char *, char *);
int path_offline (struct path *);
+int get_state (struct path * pp, int daemon);
+int path_blocked (struct path *);
int pathinfo (struct path *, vector hwtable, int mask);
struct path * store_pathinfo (vector pathvec, vector hwtable,
char * devname, int flag);
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -908,26 +908,9 @@ check_path (struct vectors * vecs, struc
*/
pp->tick = conf->checkint;
- if (!checker_selected(&pp->checker)) {
- pathinfo(pp, conf->hwtable, DI_SYSFS);
- select_checker(pp);
- }
- if (!checker_selected(&pp->checker)) {
- condlog(0, "%s: checker is not set", pp->dev);
- return;
- }
- /*
- * Set checker in async mode.
- * Honored only by checker implementing the said mode.
- */
- checker_set_async(&pp->checker);
-
- if (path_offline(pp))
- newstate = PATH_DOWN;
- else
- newstate = checker_check(&pp->checker);
+ newstate = get_state(pp, 1);
- if (newstate < 0) {
+ if (newstate == PATH_WILD || newstate == PATH_UNCHECKED) {
condlog(2, "%s: unusable path", pp->dev);
pathinfo(pp, conf->hwtable, 0);
return;

View File

@ -1,511 +0,0 @@
---
libmultipath/config.h | 4 +
libmultipath/configure.c | 3 +
libmultipath/dict.c | 102 +++++++++++++++++++++++++++++++++++++++++++++
libmultipath/discovery.c | 37 ++++++++++++++++
libmultipath/discovery.h | 1
libmultipath/propsel.c | 42 ++++++++++++++++++
libmultipath/propsel.h | 2
libmultipath/structs.h | 2
libmultipath/sysfs.c | 56 ++++++++++++++++++++++++
libmultipath/sysfs.h | 3 -
multipath.conf.annotated | 38 ++++++++++++++++
multipath/multipath.conf.5 | 15 ++++++
12 files changed, 303 insertions(+), 2 deletions(-)
Index: multipath-tools-091020/multipath.conf.annotated
===================================================================
--- multipath-tools-091020.orig/multipath.conf.annotated
+++ multipath-tools-091020/multipath.conf.annotated
@@ -191,6 +191,25 @@
# # default : determined by the process
# gid disk
#
+# #
+# # name : fast_io_fail_tmo
+# # scope : multipath & multipathd
+# # desc : The number of seconds the scsi layer will wait after a
+# # problem has been detected on a FC remote port before failing
+# # IO to devices on that remote port.
+# # values : off | n >= 0 (smaller than dev_loss_tmo)
+# # default : determined by the OS
+# fast_io_fail_tmo 5
+#
+# #
+# # name : dev_loss_tmo
+# # scope : multipath & multipathd
+# # desc : The number of seconds the scsi layer will wait after a
+# # problem has been detected on a FC remote port before
+# # removing it from the system.
+# # values : n > 0
+# # default : determined by the OS
+# dev_loss_tmo 600
#}
#
##
@@ -504,7 +523,6 @@
# # desc : If set to "yes", multipathd will disable queueing
# # when the last path to a device has been deleted.
# # values : yes|no
-# # default : no
# #
# flush_on_last_del yes
#
@@ -514,6 +532,24 @@
# # desc : product strings to blacklist for this vendor
# #
# product_blacklist LUN_Z
+#
+# #
+# # name : fast_io_fail_tmo
+# # scope : multipath & multipathd
+# # desc : The number of seconds the scsi layer will wait after
+# # a problem has been detected on a FC remote port
+# # before failing IO to devices on that remote port.
+# # values : off | n >= 0 (smaller than dev_loss_tmo)
+# fast_io_fail_tmo 5
+#
+# #
+# # name : dev_loss_tmo
+# # scope : multipath & multipathd
+# # desc : The number of seconds the scsi layer will wait after
+# # a problem has been detected on a FC remote port
+# # before removing it from the system.
+# # values : n > 0
+# dev_loss_tmo 600
# }
# device {
# vendor "COMPAQ "
Index: multipath-tools-091020/multipath/multipath.conf.5
===================================================================
--- multipath-tools-091020.orig/multipath/multipath.conf.5
+++ multipath-tools-091020/multipath/multipath.conf.5
@@ -240,6 +240,17 @@ this to the system limit from /proc/sys/
maximum number of open fds is taken from the calling process. It is usually
1024. To be safe, this should be set to the maximum number of paths plus 32,
if that number is greated than 1024.
+.TP
+.B fast_io_fail_tmo
+Specify the number of seconds the scsi layer will wait after a problem has been
+detected on a FC remote port before failing IO to devices on that remote port.
+This should be smaller than dev_loss_tmo. Setting this to
+.I off
+will disable the timeout.
+.TP
+.B dev_loss_tmo
+Specify the number of seconds the scsi layer will wait after a problem has
+been detected on a FC remote port before removing it from the system.
.
.SH "blacklist section"
The
@@ -384,6 +395,10 @@ section:
.B no_path_retry
.TP
.B rr_min_io
+.TP
+.B fast_io_fail_tmo
+.TP
+.B dev_loss_tmo
.RE
.PD
.LP
Index: multipath-tools-091020/libmultipath/dict.c
===================================================================
--- multipath-tools-091020.orig/libmultipath/dict.c
+++ multipath-tools-091020/libmultipath/dict.c
@@ -37,6 +37,35 @@ polling_interval_handler(vector strvec)
}
static int
+def_fast_io_fail_handler(vector strvec)
+{
+ char * buff;
+
+ buff = set_value(strvec);
+ if (strlen(buff) == 3 && !strcmp(buff, "off"))
+ conf->fast_io_fail = -1;
+ else if (sscanf(buff, "%d", &conf->fast_io_fail) != 1 ||
+ conf->fast_io_fail < -1)
+ conf->fast_io_fail = 0;
+
+ FREE(buff);
+ return 0;
+}
+
+static int
+def_dev_loss_handler(vector strvec)
+{
+ char * buff;
+
+ buff = set_value(strvec);
+ if (sscanf(buff, "%u", &conf->dev_loss) != 1)
+ conf->dev_loss = 0;
+
+ FREE(buff);
+ return 0;
+}
+
+static int
verbosity_handler(vector strvec)
{
char * buff;
@@ -628,6 +657,37 @@ bl_product_handler(vector strvec)
}
static int
+hw_fast_io_fail_handler(vector strvec)
+{
+ char * buff;
+ struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
+
+ buff = set_value(strvec);
+ if (strlen(buff) == 3 && !strcmp(buff, "off"))
+ hwe->fast_io_fail = -1;
+ else if (sscanf(buff, "%d", &hwe->fast_io_fail) != 1 ||
+ hwe->fast_io_fail < -1)
+ hwe->fast_io_fail = 0;
+
+ FREE(buff);
+ return 0;
+}
+
+static int
+hw_dev_loss_handler(vector strvec)
+{
+ char * buff;
+ struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
+
+ buff = set_value(strvec);
+ if (sscanf(buff, "%u", &hwe->dev_loss) != 1)
+ hwe->dev_loss = 0;
+
+ FREE(buff);
+ return 0;
+}
+
+static int
hw_pgpolicy_handler(vector strvec)
{
char * buff;
@@ -1390,6 +1450,26 @@ snprint_mp_flush_on_last_del (char * buf
}
static int
+snprint_hw_fast_io_fail(char * buff, int len, void * data)
+{
+ struct hwentry * hwe = (struct hwentry *)data;
+ if (!hwe->fast_io_fail)
+ return 0;
+ if (hwe->fast_io_fail == -1)
+ return snprintf(buff, len, "off");
+ return snprintf(buff, len, "%d", hwe->fast_io_fail);
+}
+
+static int
+snprint_hw_dev_loss(char * buff, int len, void * data)
+{
+ struct hwentry * hwe = (struct hwentry *)data;
+ if (!hwe->dev_loss)
+ return 0;
+ return snprintf(buff, len, "%u", hwe->dev_loss);
+}
+
+static int
snprint_hw_vendor (char * buff, int len, void * data)
{
struct hwentry * hwe = (struct hwentry *)data;
@@ -1640,6 +1720,24 @@ snprint_def_polling_interval (char * buf
}
static int
+snprint_def_fast_io_fail(char * buff, int len, void * data)
+{
+ if (!conf->fast_io_fail)
+ return 0;
+ if (conf->fast_io_fail == -1)
+ return snprintf(buff, len, "off");
+ return snprintf(buff, len, "%d", conf->fast_io_fail);
+}
+
+static int
+snprint_def_dev_loss(char * buff, int len, void * data)
+{
+ if (!conf->dev_loss)
+ return 0;
+ return snprintf(buff, len, "%u", conf->dev_loss);
+}
+
+static int
snprint_def_verbosity (char * buff, int len, void * data)
{
if (conf->checkint == DEFAULT_VERBOSITY)
@@ -1937,6 +2035,8 @@ init_keywords(void)
install_keyword("mode", &def_mode_handler, &snprint_def_mode);
install_keyword("uid", &def_uid_handler, &snprint_def_uid);
install_keyword("gid", &def_gid_handler, &snprint_def_gid);
+ install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail);
+ install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss);
__deprecated install_keyword("default_selector", &def_selector_handler, NULL);
__deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
__deprecated install_keyword("default_getuid_callout", &def_getuid_callout_handler, NULL);
@@ -1991,6 +2091,8 @@ init_keywords(void)
install_keyword("rr_min_io", &hw_minio_handler, &snprint_hw_rr_min_io);
install_keyword("pg_timeout", &hw_pg_timeout_handler, &snprint_hw_pg_timeout);
install_keyword("flush_on_last_del", &hw_flush_on_last_del_handler, &snprint_hw_flush_on_last_del);
+ install_keyword("fast_io_fail_tmo", &hw_fast_io_fail_handler, &snprint_hw_fast_io_fail);
+ install_keyword("dev_loss_tmo", &hw_dev_loss_handler, &snprint_hw_dev_loss);
install_sublevel_end();
install_keyword_root("multipaths", &multipaths_handler);
Index: multipath-tools-091020/libmultipath/config.h
===================================================================
--- multipath-tools-091020.orig/libmultipath/config.h
+++ multipath-tools-091020/libmultipath/config.h
@@ -31,6 +31,8 @@ struct hwentry {
int minio;
int pg_timeout;
int flush_on_last_del;
+ int fast_io_fail;
+ unsigned int dev_loss;
char * bl_product;
};
@@ -75,6 +77,8 @@ struct config {
int daemon;
int flush_on_last_del;
int attribute_flags;
+ int fast_io_fail;
+ unsigned int dev_loss;
uid_t uid;
gid_t gid;
mode_t mode;
Index: multipath-tools-091020/libmultipath/propsel.c
===================================================================
--- multipath-tools-091020.orig/libmultipath/propsel.c
+++ multipath-tools-091020/libmultipath/propsel.c
@@ -428,6 +428,48 @@ select_pg_timeout(struct multipath *mp)
}
extern int
+select_fast_io_fail(struct multipath *mp)
+{
+ if (mp->hwe && mp->hwe->fast_io_fail) {
+ mp->fast_io_fail = mp->hwe->fast_io_fail;
+ if (mp->fast_io_fail == -1)
+ condlog(3, "%s: fast_io_fail_tmo = off (controller default)", mp->alias);
+ else
+ condlog(3, "%s: fast_io_fail_tmo = %d (controller default)", mp->alias, mp->fast_io_fail);
+ return 0;
+ }
+ if (conf->fast_io_fail) {
+ mp->fast_io_fail = conf->fast_io_fail;
+ if (mp->fast_io_fail == -1)
+ condlog(3, "%s: fast_io_fail_tmo = off (config file default)", mp->alias);
+ else
+ condlog(3, "%s: fast_io_fail_tmo = %d (config file default)", mp->alias, mp->fast_io_fail);
+ return 0;
+ }
+ mp->fast_io_fail = 0;
+ return 0;
+}
+
+extern int
+select_dev_loss(struct multipath *mp)
+{
+ if (mp->hwe && mp->hwe->dev_loss) {
+ mp->dev_loss = mp->hwe->dev_loss;
+ condlog(3, "%s: dev_loss_tmo = %u (controller default)",
+ mp->alias, mp->dev_loss);
+ return 0;
+ }
+ if (conf->dev_loss) {
+ mp->dev_loss = conf->dev_loss;
+ condlog(3, "%s: dev_loss_tmo = %u (config file default)",
+ mp->alias, mp->dev_loss);
+ return 0;
+ }
+ mp->dev_loss = 0;
+ return 0;
+}
+
+extern int
select_flush_on_last_del(struct multipath *mp)
{
if (mp->flush_on_last_del == FLUSH_IN_PROGRESS)
Index: multipath-tools-091020/libmultipath/structs.h
===================================================================
--- multipath-tools-091020.orig/libmultipath/structs.h
+++ multipath-tools-091020/libmultipath/structs.h
@@ -166,6 +166,8 @@ struct multipath {
int pg_timeout;
int flush_on_last_del;
int attribute_flags;
+ int fast_io_fail;
+ unsigned int dev_loss;
uid_t uid;
gid_t gid;
mode_t mode;
Index: multipath-tools-091020/libmultipath/configure.c
===================================================================
--- multipath-tools-091020.orig/libmultipath/configure.c
+++ multipath-tools-091020/libmultipath/configure.c
@@ -70,7 +70,10 @@ setup_map (struct multipath * mpp)
select_mode(mpp);
select_uid(mpp);
select_gid(mpp);
+ select_fast_io_fail(mpp);
+ select_dev_loss(mpp);
+ sysfs_set_scsi_tmo(mpp);
/*
* assign paths to path groups -- start with no groups and all paths
* in mpp->paths
Index: multipath-tools-091020/libmultipath/discovery.c
===================================================================
--- multipath-tools-091020.orig/libmultipath/discovery.c
+++ multipath-tools-091020/libmultipath/discovery.c
@@ -204,6 +204,43 @@ sysfs_get_fc_nodename (struct sysfs_devi
return 1;
}
+int
+sysfs_set_scsi_tmo (struct multipath *mpp)
+{
+ char attr_path[SYSFS_PATH_SIZE];
+ struct path *pp;
+ int i;
+ char value[11];
+
+ if (!mpp->dev_loss && !mpp->fast_io_fail)
+ return 0;
+ vector_foreach_slot(mpp->paths, pp, i) {
+ if (safe_snprintf(attr_path, SYSFS_PATH_SIZE,
+ "/class/fc_remote_ports/rport-%d:%d-%d",
+ pp->sg_id.host_no, pp->sg_id.channel,
+ pp->sg_id.scsi_id)) {
+ condlog(0, "attr_path '/class/fc_remote_ports/rport-%d:%d-%d' too large", pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.scsi_id);
+ return 1;
+ }
+ if (mpp->dev_loss){
+ snprintf(value, 11, "%u", mpp->dev_loss);
+ if (sysfs_attr_set_value(attr_path, "dev_loss_tmo",
+ value))
+ return 1;
+ }
+ if (mpp->fast_io_fail){
+ if (mpp->fast_io_fail == -1)
+ sprintf(value, "off");
+ else
+ snprintf(value, 11, "%u", mpp->fast_io_fail);
+ if (sysfs_attr_set_value(attr_path, "fast_io_fail",
+ value))
+ return 1;
+ }
+ }
+ return 0;
+}
+
static int
opennode (char * dev, int mode)
{
Index: multipath-tools-091020/libmultipath/propsel.h
===================================================================
--- multipath-tools-091020.orig/libmultipath/propsel.h
+++ multipath-tools-091020/libmultipath/propsel.h
@@ -15,3 +15,5 @@ int select_minio(struct multipath *mp);
int select_mode(struct multipath *mp);
int select_uid(struct multipath *mp);
int select_gid(struct multipath *mp);
+int select_fast_io_fail(struct multipath *mp);
+int select_dev_loss(struct multipath *mp);
Index: multipath-tools-091020/libmultipath/discovery.h
===================================================================
--- multipath-tools-091020.orig/libmultipath/discovery.h
+++ multipath-tools-091020/libmultipath/discovery.h
@@ -33,6 +33,7 @@ int path_offline (struct path *);
int pathinfo (struct path *, vector hwtable, int mask);
struct path * store_pathinfo (vector pathvec, vector hwtable,
char * devname, int flag);
+int sysfs_set_scsi_tmo (struct multipath *mpp);
/*
* discovery bitmask
Index: multipath-tools-091020/libmultipath/sysfs.c
===================================================================
--- multipath-tools-091020.orig/libmultipath/sysfs.c
+++ multipath-tools-091020/libmultipath/sysfs.c
@@ -356,6 +356,62 @@ void sysfs_device_put(struct sysfs_devic
return;
}
+int
+sysfs_attr_set_value(const char *devpath, const char *attr_name,
+ const char *value)
+{
+ char path_full[PATH_SIZE];
+ int sysfs_len;
+ struct stat statbuf;
+ int fd, value_len, ret = -1;
+
+ dbg("open '%s'/'%s'", devpath, attr_name);
+ sysfs_len = snprintf(path_full, PATH_SIZE, "%s%s/%s", sysfs_path,
+ devpath, attr_name);
+ if (sysfs_len >= PATH_SIZE || sysfs_len < 0) {
+ if (sysfs_len < 0)
+ dbg("cannot copy sysfs path %s%s/%s : %s", sysfs_path,
+ devpath, attr_name, strerror(errno));
+ else
+ dbg("sysfs_path %s%s/%s too large", sysfs_path,
+ devpath, attr_name);
+ goto out;
+ }
+
+ if (stat(path_full, &statbuf) != 0) {
+ dbg("stat '%s' failed: %s" path_full, strerror(errno));
+ goto out;
+ }
+
+ /* skip directories */
+ if (S_ISDIR(statbuf.st_mode))
+ goto out;
+
+ if ((statbuf.st_mode & S_IWUSR) == 0)
+ goto out;
+
+ fd = open(path_full, O_WRONLY);
+ if (fd < 0) {
+ dbg("attribute '%s' can not be opened: %s",
+ path_full, strerror(errno));
+ goto out;
+ }
+ value_len = strlen(value) + 1;
+ ret = write(fd, value, value_len);
+ if (ret == value_len)
+ ret = 0;
+ else if (ret < 0)
+ dbg("write to %s failed: %s", path_full, strerror(errno));
+ else {
+ dbg("tried to write %d to %s. Wrote %d\n", value_len,
+ path_full, ret);
+ ret = -1;
+ }
+out:
+ return ret;
+}
+
+
char *sysfs_attr_get_value(const char *devpath, const char *attr_name)
{
char path_full[PATH_SIZE];
Index: multipath-tools-091020/libmultipath/sysfs.h
===================================================================
--- multipath-tools-091020.orig/libmultipath/sysfs.h
+++ multipath-tools-091020/libmultipath/sysfs.h
@@ -22,5 +22,6 @@ void sysfs_device_put(struct sysfs_devic
char *sysfs_attr_get_value(const char *devpath, const char *attr_name);
int sysfs_resolve_link(char *path, size_t size);
int sysfs_get_size (struct sysfs_device * dev, unsigned long long * size);
-
+int sysfs_attr_set_value(const char *devpath, const char *attr_name,
+ const char *value);
#endif

View File

@ -1,42 +1,47 @@
From 5a43356b54c2672441ce67cd9602904a5df04117 Mon Sep 17 00:00:00 2001
From: Fabio M. Di Nitto <fdinitto@redhat.com>
Date: Mon, 19 Oct 2009 07:07:01 +0200
Subject: [PATCH 10/12] RH: multipath rules + udev changes
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
--- ---
:100644 100644 ac97749... 064196d... M multipath/multipath.rules
multipath/Makefile | 6 +++--- multipath/Makefile | 6 +++---
multipath/multipath.rules | 18 +++++++++++------- multipath/multipath.rules | 29 +++++++++++++++++++++++------
2 files changed, 14 insertions(+), 10 deletions(-) 2 files changed, 26 insertions(+), 9 deletions(-)
Index: multipath-tools/multipath/multipath.rules Index: multipath-tools-111219/multipath/multipath.rules
=================================================================== ===================================================================
--- multipath-tools.orig/multipath/multipath.rules --- multipath-tools-111219.orig/multipath/multipath.rules
+++ multipath-tools/multipath/multipath.rules +++ multipath-tools-111219/multipath/multipath.rules
@@ -1,7 +1,11 @@ @@ -1,7 +1,24 @@
-# -#
-# udev rules for multipathing. -# udev rules for multipathing.
-# The persistent symlinks are created with the kpartx rules -# The persistent symlinks are created with the kpartx rules
-# -#
-
-# socket for uevents
-SUBSYSTEM=="block", RUN+="socket:/org/kernel/dm/multipath_event"
+# multipath wants the devmaps presented as meaninglful device names +# multipath wants the devmaps presented as meaninglful device names
+# so name them after their devmap name +# so name them after their devmap name
+SUBSYSTEM!="block", GOTO="end_mpath" +SUBSYSTEM!="block", GOTO="end_mpath"
-# socket for uevents
-SUBSYSTEM=="block", RUN+="socket:/org/kernel/dm/multipath_event"
+ENV{MPATH_SBIN_PATH}="/sbin"
+TEST!="$env{MPATH_SBIN_PATH}/multipath", ENV{MPATH_SBIN_PATH}="/usr/sbin"
+
+ACTION=="add", ENV{DEVTYPE}!="partition", \
+ ENV{DM_MULTIPATH_DEVICE_PATH}!="1", \
+ PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -c $tempnode", \
+ ENV{DM_MULTIPATH_DEVICE_PATH}="1"
+
+ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{DEVTYPE}!="partition", \
+ RUN+="/sbin/partx -d --nr 1-1024 $env{DEVNAME}"
+
+RUN+="socket:/org/kernel/dm/multipath_event" +RUN+="socket:/org/kernel/dm/multipath_event"
+KERNEL!="dm-*", GOTO="end_mpath" +KERNEL!="dm-*", GOTO="end_mpath"
+ACTION!="change", GOTO="end_mpath" +ACTION!="change", GOTO="end_mpath"
+ENV{DM_SUSPENDED}=="1", GOTO="end_mpath" +ENV{DM_UUID}=="mpath-?*|part[0-9]*-mpath-?*", OPTIONS+="link_priority=10"
+ENV{DM_UUID}!="mpath-?*", GOTO="end_mpath" +ENV{DM_UUID}!="mpath-?*", GOTO="end_mpath"
+ENV{DM_SUSPENDED}=="1", GOTO="end_mpath"
+ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath" +ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath"
+RUN+="$env{DM_SBIN_PATH}/kpartx -a -p p $tempnode" +RUN+="$env{MPATH_SBIN_PATH}/kpartx -a -p p $tempnode"
+LABEL="end_mpath" +LABEL="end_mpath"
Index: multipath-tools/multipath/Makefile Index: multipath-tools-111219/multipath/Makefile
=================================================================== ===================================================================
--- multipath-tools.orig/multipath/Makefile --- multipath-tools-111219.orig/multipath/Makefile
+++ multipath-tools/multipath/Makefile +++ multipath-tools-111219/multipath/Makefile
@@ -21,15 +21,15 @@ $(EXEC): $(OBJS) @@ -21,15 +21,15 @@ $(EXEC): $(OBJS)
install: install:
$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
@ -52,7 +57,7 @@ Index: multipath-tools/multipath/Makefile
uninstall: uninstall:
- rm $(DESTDIR)/etc/udev/rules.d/multipath.rules - rm $(DESTDIR)/etc/udev/rules.d/multipath.rules
+ rm $(DESTDIR)/lib/udev/rules.d/multipath.rules + rm $(DESTDIR)/lib/udev/rules.d/40-multipath.rules
rm $(DESTDIR)$(bindir)/$(EXEC) rm $(DESTDIR)$(bindir)/$(EXEC)
rm $(DESTDIR)$(mandir)/$(EXEC).8.gz rm $(DESTDIR)$(mandir)/$(EXEC).8.gz
rm $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz rm $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz

View File

@ -1,84 +0,0 @@
From e6a23cc9de85a66d774567515592bdbdba7b2ca4 Mon Sep 17 00:00:00 2001
From: Fabio M. Di Nitto <fdinitto@redhat.com>
Date: Tue, 13 Oct 2009 08:19:01 +0200
Subject: [PATCH 03/12] RH: root init script
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
---
:100644 100644 ee776f0... e46b1b8... M multipathd/multipathd.init.redhat
multipathd/multipathd.init.redhat | 38 ++++++++++++++++++++++++++++++++++++-
1 files changed, 37 insertions(+), 1 deletions(-)
diff --git a/multipathd/multipathd.init.redhat b/multipathd/multipathd.init.redhat
index ee776f0..e46b1b8 100644
--- a/multipathd/multipathd.init.redhat
+++ b/multipathd/multipathd.init.redhat
@@ -2,7 +2,7 @@
#
# multipathd Starts the multipath daemon
#
-# chkconfig: - 13 87
+# chkconfig: - 06 87
# description: Manages device-mapper multipath devices
### BEGIN INIT INFO
@@ -17,6 +17,7 @@ prog=`basename $DAEMON`
initdir=/etc/rc.d/init.d
lockdir=/var/lock/subsys
sysconfig=/etc/sysconfig
+syspath=/sys/block
. $initdir/functions
@@ -25,6 +26,36 @@ test -r $sysconfig/$prog && . $sysconfig/$prog
RETVAL=0
+teardown_slaves()
+{
+pushd $1 > /dev/null
+if [ -d "slaves" ]; then
+for slave in slaves/*;
+do
+ if [ "$slave" = "slaves/*" ]; then
+ read dev < $1/dev
+ tablename=`dmsetup table --target multipath | sed -n "s/\(.*\): .* $dev .*/\1/p"`
+ if ! [ -z $tablename ]; then
+ echo "Root is on a multipathed device, multipathd can not be stopped"
+ exit 1
+ fi
+ else
+ local_slave=`readlink -f $slave`;
+ teardown_slaves $local_slave;
+ fi
+ done
+
+else
+ read dev < $1/dev
+ tablename=`dmsetup table --target multipath | sed -n "s/\(.*\): .* $dev .*/\1/p"`
+ if ! [ -z $tablename ]; then
+ echo "Root is on a multipathed device, multipathd can not be stopped"
+ exit 1
+ fi
+fi
+popd > /dev/null
+}
+
#
# See how we were called.
#
@@ -39,6 +70,11 @@ start() {
}
stop() {
+ root_dev=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $1; }}' /etc/mtab)
+ dm_num=`dmsetup info -c --noheadings -o minor $root_dev`
+ root_dm_device="dm-$dm_num"
+ [ -d $syspath/$root_dm_device ] && teardown_slaves $syspath/$root_dm_device
+
echo -n $"Stopping $prog daemon: "
killproc $DAEMON
RETVAL=$?
--
1.6.5.1

View File

@ -1,56 +0,0 @@
Index: multipath-tools/libmultipath/hwtable.c
===================================================================
--- multipath-tools.orig/libmultipath/hwtable.c
+++ multipath-tools/libmultipath/hwtable.c
@@ -425,6 +425,21 @@ static struct hwentry default_hw[] = {
.prio_name = PRIO_RDAC,
},
{
+ .vendor = "IBM",
+ .product = "1745|1746",
+ .getuid = DEFAULT_GETUID,
+ .features = "2 pg_init_retries 50",
+ .hwhandler = "1 rdac",
+ .selector = DEFAULT_SELECTOR,
+ .pgpolicy = GROUP_BY_PRIO,
+ .pgfailback = -FAILBACK_IMMEDIATE,
+ .rr_weight = RR_WEIGHT_NONE,
+ .no_path_retry = 15,
+ .minio = DEFAULT_MINIO,
+ .checker_name = RDAC,
+ .prio_name = PRIO_RDAC,
+ },
+ {
/* IBM DS4700 */
.vendor = "IBM",
.product = "1814",
@@ -661,12 +676,13 @@ static struct hwentry default_hw[] = {
.vendor = "DELL",
.product = "MD3000",
.getuid = DEFAULT_GETUID,
- .features = "1 queue_if_no_path",
+ .features = "2 pg_init_retries 50",
.hwhandler = "1 rdac",
.selector = DEFAULT_SELECTOR,
.pgpolicy = GROUP_BY_PRIO,
.pgfailback = -FAILBACK_IMMEDIATE,
.rr_weight = RR_WEIGHT_NONE,
+ .no_path_retry = 15,
.minio = DEFAULT_MINIO,
.checker_name = RDAC,
.prio_name = PRIO_RDAC,
@@ -676,12 +692,13 @@ static struct hwentry default_hw[] = {
.vendor = "DELL",
.product = "MD3000i",
.getuid = DEFAULT_GETUID,
- .features = "1 queue_if_no_path",
+ .features = "2 pg_init_retries 50",
.hwhandler = "1 rdac",
.selector = DEFAULT_SELECTOR,
.pgpolicy = GROUP_BY_PRIO,
.pgfailback = -FAILBACK_IMMEDIATE,
.rr_weight = RR_WEIGHT_NONE,
+ .no_path_retry = 15,
.minio = DEFAULT_MINIO,
.checker_name = RDAC,
.prio_name = PRIO_RDAC,

View File

@ -1,48 +0,0 @@
From 8d443fe2c58e22166426438e6f6d5757934f7b31 Mon Sep 17 00:00:00 2001
From: Fabio M. Di Nitto <fdinitto@redhat.com>
Date: Tue, 13 Oct 2009 08:23:42 +0200
Subject: [PATCH 04/12] RH: fix kpartx
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
---
:100644 100644 b61a81f... 103ed0a... M kpartx/kpartx.c
kpartx/kpartx.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/kpartx/kpartx.c b/kpartx/kpartx.c
index b61a81f..103ed0a 100644
--- a/kpartx/kpartx.c
+++ b/kpartx/kpartx.c
@@ -488,6 +488,7 @@ main(int argc, char **argv){
d = c;
while (c) {
for (j = 0; j < n; j++) {
+ uint64_t start;
int k = slices[j].container - 1;
if (slices[j].size == 0)
@@ -498,7 +499,7 @@ main(int argc, char **argv){
continue;
/* Skip all simple slices */
- if (k < 0)
+ if (slices[j].container == 0)
continue;
/* Check container slice */
@@ -513,10 +514,11 @@ main(int argc, char **argv){
}
strip_slash(partname);
+ start = slices[j].start - slices[k].start;
if (safe_sprintf(params, "%d:%d %" PRIu64,
slices[k].major,
slices[k].minor,
- slices[j].start)) {
+ start)) {
fprintf(stderr, "params too small\n");
exit(1);
}
--
1.6.5.1

View File

@ -0,0 +1,76 @@
---
multipathd/multipathd.init.redhat | 27 ++++++---------------------
1 file changed, 6 insertions(+), 21 deletions(-)
Index: multipath-tools-111219/multipathd/multipathd.init.redhat
===================================================================
--- multipath-tools-111219.orig/multipathd/multipathd.init.redhat
+++ multipath-tools-111219/multipathd/multipathd.init.redhat
@@ -73,14 +73,6 @@ start() {
echo
}
-force_stop() {
- echo -n $"Stopping $prog daemon: "
- killproc $DAEMON
- RETVAL=$?
- [ $RETVAL -eq 0 ] && rm -f $lockdir/$prog
- echo
-}
-
stop() {
root_dev=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $1; }}' /etc/mtab)
dm_num=`dmsetup info -c --noheadings -o minor $root_dev 2> /dev/null`
@@ -89,7 +81,11 @@ stop() {
[ -d $syspath/$root_dm_device ] && teardown_slaves $syspath/$root_dm_device
fi
- force_stop
+ echo -n $"Stopping $prog daemon: "
+ killproc $DAEMON
+ RETVAL=$?
+ [ $RETVAL -eq 0 ] && rm -f $lockdir/$prog
+ echo
}
restart() {
@@ -97,11 +93,6 @@ restart() {
start
}
-force_restart() {
- force_stop
- start
-}
-
reload() {
echo -n "Reloading $prog: "
trap "" SIGHUP
@@ -117,18 +108,12 @@ start)
stop)
stop
;;
-force-stop)
- force_stop
- ;;
force-reload|reload)
reload
;;
restart)
restart
;;
-force-restart)
- force_restart
- ;;
condrestart|try-restart)
if [ -f $lockdir/$prog ]; then
restart
@@ -139,7 +124,7 @@ status)
RETVAL=$?
;;
*)
- echo $"Usage: $0 {start|stop|force-stop|status|restart|force-restart|condrestart|reload}"
+ echo $"Usage: $0 {start|stop|status|restart|condrestart|reload}"
RETVAL=2
esac

View File

@ -10,13 +10,14 @@ Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
:100644 100644 32d9ef5... 25e1483... M multipathd/Makefile :100644 100644 32d9ef5... 25e1483... M multipathd/Makefile
Makefile.inc | 2 +- Makefile.inc | 2 +-
kpartx/Makefile | 8 ++++---- kpartx/Makefile | 8 ++++----
libmultipath/Makefile | 2 ++
multipathd/Makefile | 1 + multipathd/Makefile | 1 +
3 files changed, 6 insertions(+), 5 deletions(-) 4 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/Makefile.inc b/Makefile.inc Index: multipath-tools-120123/Makefile.inc
index 7ec25d5..06fb625 100644 ===================================================================
--- a/Makefile.inc --- multipath-tools-120123.orig/Makefile.inc
+++ b/Makefile.inc +++ multipath-tools-120123/Makefile.inc
@@ -28,7 +28,7 @@ libudevdir = ${prefix}/lib/udev @@ -28,7 +28,7 @@ libudevdir = ${prefix}/lib/udev
multipathdir = $(TOPDIR)/libmultipath multipathdir = $(TOPDIR)/libmultipath
mandir = $(prefix)/usr/share/man/man8 mandir = $(prefix)/usr/share/man/man8
@ -25,12 +26,12 @@ index 7ec25d5..06fb625 100644
+rcdir = $(prefix)/etc/rc.d/init.d +rcdir = $(prefix)/etc/rc.d/init.d
syslibdir = $(prefix)/$(LIB) syslibdir = $(prefix)/$(LIB)
libdir = $(prefix)/$(LIB)/multipath libdir = $(prefix)/$(LIB)/multipath
unitdir = $(prefix)/lib/systemd/system
diff --git a/kpartx/Makefile b/kpartx/Makefile Index: multipath-tools-120123/kpartx/Makefile
index 21e4ad4..06d79c0 100644 ===================================================================
--- a/kpartx/Makefile --- multipath-tools-120123.orig/kpartx/Makefile
+++ b/kpartx/Makefile +++ multipath-tools-120123/kpartx/Makefile
@@ -20,10 +20,10 @@ $(EXEC): $(OBJS) @@ -26,10 +26,10 @@ $(EXEC): $(OBJS)
install: $(EXEC) $(EXEC).8 install: $(EXEC) $(EXEC).8
$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)
@ -45,18 +46,31 @@ index 21e4ad4..06d79c0 100644
$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir) $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
$(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir) $(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
diff --git a/multipathd/Makefile b/multipathd/Makefile Index: multipath-tools-120123/multipathd/Makefile
index 32d9ef5..25e1483 100644 ===================================================================
--- a/multipathd/Makefile --- multipath-tools-120123.orig/multipathd/Makefile
+++ b/multipathd/Makefile +++ multipath-tools-120123/multipathd/Makefile
@@ -35,6 +35,7 @@ install: @@ -35,6 +35,7 @@ install:
$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir) $(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir) $(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)
$(INSTALL_PROGRAM) -d $(DESTDIR)$(rcdir) $(INSTALL_PROGRAM) -d $(DESTDIR)$(rcdir)
+ $(INSTALL_PROGRAM) -m 755 multipathd.init.redhat $(DESTDIR)$(rcdir)/$(EXEC) + $(INSTALL_PROGRAM) -m 755 multipathd.init.redhat $(DESTDIR)$(rcdir)/$(EXEC)
$(INSTALL_PROGRAM) -d $(DESTDIR)$(unitdir)
$(INSTALL_PROGRAM) -m 644 $(EXEC).service $(DESTDIR)$(unitdir)
$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir) $(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
$(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir) Index: multipath-tools-120123/libmultipath/Makefile
===================================================================
--- multipath-tools-120123.orig/libmultipath/Makefile
+++ multipath-tools-120123/libmultipath/Makefile
@@ -39,9 +39,11 @@ install:
$(INSTALL_PROGRAM) -d $(DESTDIR)$(syslibdir)
$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(syslibdir)/$(LIBS)
$(INSTALL_PROGRAM) -m 755 -d $(DESTDIR)$(libdir)
+ ln -sf $(LIBS) $(DESTDIR)$(syslibdir)/$(DEVLIB)
-- uninstall:
1.6.5.1 rm -f $(DESTDIR)$(syslibdir)/$(LIBS)
+ rm -f $(DESTDIR)$(syslibdir)/$(DEVLIB)
clean:
rm -f core *.a *.o *.gz *.so *.so.*

View File

@ -1,56 +0,0 @@
From ff4c0c9ccbf8abe4a67c2a6cceef07bda9d38d7d Mon Sep 17 00:00:00 2001
From: Fabio M. Di Nitto <fdinitto@redhat.com>
Date: Tue, 13 Oct 2009 09:26:25 +0200
Subject: [PATCH 06/12] RH: move bindings
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
---
:100644 100644 84e5d6b... 5a38d25... M libmultipath/defaults.h
:100644 100644 9afa615... 7b6453f... M multipath.conf.annotated
:100644 100644 a165e4e... 4340e51... M multipath/multipath.conf.5
libmultipath/defaults.h | 2 +-
multipath.conf.annotated | 2 +-
multipath/multipath.conf.5 | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
index 84e5d6b..5a38d25 100644
--- a/libmultipath/defaults.h
+++ b/libmultipath/defaults.h
@@ -19,6 +19,6 @@
#define DEFAULT_PIDFILE "/var/run/multipathd.pid"
#define DEFAULT_SOCKET "/var/run/multipathd.sock"
#define DEFAULT_CONFIGFILE "/etc/multipath.conf"
-#define DEFAULT_BINDINGS_FILE "/var/lib/multipath/bindings"
+#define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings"
char * set_default (char * str);
diff --git a/multipath.conf.annotated b/multipath.conf.annotated
index 9afa615..7b6453f 100644
--- a/multipath.conf.annotated
+++ b/multipath.conf.annotated
@@ -165,7 +165,7 @@
# # name : user_friendly_names
# # scope : multipath
# # desc : If set to "yes", using the bindings file
-# # /var/lib/multipath/bindings to assign a persistent and
+# # /etc/multipath/bindings to assign a persistent and
# # unique alias to the multipath, in the form of mpath<n>.
# # If set to "no" use the WWID as the alias. In either case
# # this be will be overriden by any specific aliases in this
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
index a165e4e..4340e51 100644
--- a/multipath/multipath.conf.5
+++ b/multipath/multipath.conf.5
@@ -224,7 +224,7 @@ for never stop queueing. Default is 0.
If set to
.I yes
, using the bindings file
-.I /var/lib/multipath/bindings
+.I /etc/multipath/bindings
to assign a persistent and unique alias to the multipath, in the form of mpath<n>.
If set to
.I no
--
1.6.5.1

View File

@ -1,39 +0,0 @@
From b3519ef2eda768672d47c61f0acf8c87d74db427 Mon Sep 17 00:00:00 2001
From: Fabio M. Di Nitto <fdinitto@redhat.com>
Date: Tue, 13 Oct 2009 09:33:59 +0200
Subject: [PATCH 07/12] RH: do not remove
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
---
:100644 100644 5d3625a... 244b8d5... M multipathd/main.c
multipathd/main.c | 13 ++++++++++++-
1 files changed, 12 insertions(+), 1 deletions(-)
diff --git a/multipathd/main.c b/multipathd/main.c
index 5d3625a..244b8d5 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -290,8 +290,19 @@ ev_add_map (struct sysfs_device * dev, struct vectors * vecs)
static int
uev_remove_map (struct sysfs_device * dev, struct vectors * vecs)
{
+ struct multipath * mpp;
+
condlog(2, "%s: remove map (uevent)", dev->kernel);
- return ev_remove_map(dev->kernel, vecs);
+
+ mpp = find_mp_by_str(vecs->mpvec, dev->kernel);
+ if (!mpp) {
+ condlog(2, "%s: devmap not registered, can't remove",
+ dev->kernel);
+ return 0;
+ }
+ orphan_paths(vecs->pathvec, mpp);
+ remove_map_and_stop_waiter(mpp, vecs, 1);
+ return 0;
}
int
--
1.6.5.1

View File

@ -12,52 +12,49 @@ Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
--- ---
:100644 100644 e7e962e... 5aa1ab0... M libmultipath/config.c :100644 100644 e7e962e... 5aa1ab0... M libmultipath/config.c
:100644 100644 86b1320... 7e90e75... M libmultipath/config.h :100644 100644 86b1320... 7e90e75... M libmultipath/config.h
libmultipath/config.c | 18 +++++++++++++++++- libmultipath/config.c | 16 ++++++++++++++++
libmultipath/config.h | 1 + libmultipath/config.h | 1 +
2 files changed, 18 insertions(+), 1 deletions(-) 2 files changed, 17 insertions(+)
diff --git a/libmultipath/config.c b/libmultipath/config.c Index: multipath-tools-111219/libmultipath/config.c
index e7e962e..5aa1ab0 100644 ===================================================================
--- a/libmultipath/config.c --- multipath-tools-111219.orig/libmultipath/config.c
+++ b/libmultipath/config.c +++ multipath-tools-111219/libmultipath/config.c
@@ -19,6 +19,7 @@ @@ -20,6 +20,7 @@
#include "blacklist.h"
#include "defaults.h" #include "defaults.h"
#include "prio.h" #include "prio.h"
#include "devmapper.h"
+#include "version.h" +#include "version.h"
static int static int
hwe_strmatch (struct hwentry *hwe1, struct hwentry *hwe2) hwe_strmatch (struct hwentry *hwe1, struct hwentry *hwe2)
@@ -463,8 +464,23 @@ load_config (char * file) @@ -539,6 +540,21 @@ load_config (char * file)
condlog(0, "error parsing config file");
goto out; } else {
} init_keywords();
+ } else {
+ condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices."); + condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
+ condlog(0, "A default multipath.conf file is located at"); + condlog(0, "A default multipath.conf file is located at");
+ condlog(0, + condlog(0, "/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf", MULTIPATH_VERSION(VERSION_CODE));
+"/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf", + if (conf->blist_devnode == NULL) {
+ MULTIPATH_VERSION(VERSION_CODE));
+ conf->blist_devnode = vector_alloc(); + conf->blist_devnode = vector_alloc();
+ if (!conf->blist_devnode) { + if (!conf->blist_devnode) {
+ condlog(0, "cannot allocate blacklist\n"); + condlog(0, "cannot allocate blacklist\n");
+ goto out; + goto out;
+ } + }
+ }
+ if (store_ble(conf->blist_devnode, strdup(".*"), + if (store_ble(conf->blist_devnode, strdup(".*"),
+ ORIGIN_NO_CONFIG)) { + ORIGIN_NO_CONFIG)) {
+ condlog(0, "cannot store default no-config blacklist\n"); + condlog(0, "cannot store default no-config blacklist\n");
+ goto out; + goto out;
+ } + }
} }
-
/* /*
* remove duplica in hwtable. config file takes precedence Index: multipath-tools-111219/libmultipath/config.h
* over build-in hwtable ===================================================================
diff --git a/libmultipath/config.h b/libmultipath/config.h --- multipath-tools-111219.orig/libmultipath/config.h
index 86b1320..7e90e75 100644 +++ multipath-tools-111219/libmultipath/config.h
--- a/libmultipath/config.h @@ -6,6 +6,7 @@
+++ b/libmultipath/config.h
@@ -5,6 +5,7 @@
#define ORIGIN_DEFAULT 0 #define ORIGIN_DEFAULT 0
#define ORIGIN_CONFIG 1 #define ORIGIN_CONFIG 1
@ -65,6 +62,3 @@ index 86b1320..7e90e75 100644
enum devtypes { enum devtypes {
DEV_NONE, DEV_NONE,
--
1.6.5.1

546
0008-RH-add-mpathconf.patch Normal file
View File

@ -0,0 +1,546 @@
---
libmultipath/config.c | 1
multipath/Makefile | 5
multipath/main.c | 4
multipath/mpathconf | 351 ++++++++++++++++++++++++++++++++++++++++++++++++++
multipath/mpathconf.8 | 116 ++++++++++++++++
5 files changed, 475 insertions(+), 2 deletions(-)
Index: multipath-tools-111219/libmultipath/config.c
===================================================================
--- multipath-tools-111219.orig/libmultipath/config.c
+++ multipath-tools-111219/libmultipath/config.c
@@ -543,6 +543,7 @@ load_config (char * file)
condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
condlog(0, "A default multipath.conf file is located at");
condlog(0, "/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf", MULTIPATH_VERSION(VERSION_CODE));
+ condlog(0, "You can run /sbin/mpathconf to create or modify /etc/multipath.conf");
if (conf->blist_devnode == NULL) {
conf->blist_devnode = vector_alloc();
if (!conf->blist_devnode) {
Index: multipath-tools-111219/multipath/Makefile
===================================================================
--- multipath-tools-111219.orig/multipath/Makefile
+++ multipath-tools-111219/multipath/Makefile
@@ -17,22 +17,27 @@ $(EXEC): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS)
$(GZIP) $(EXEC).8 > $(EXEC).8.gz
$(GZIP) $(EXEC).conf.5 > $(EXEC).conf.5.gz
+ $(GZIP) mpathconf.8 > mpathconf.8.gz
install:
$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
+ $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/
$(INSTALL_PROGRAM) -d $(DESTDIR)/lib/udev/rules.d
$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/lib/udev/rules.d/40-multipath.rules
$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
$(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
$(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir)
+ $(INSTALL_PROGRAM) -m 644 mpathconf.8.gz $(DESTDIR)$(mandir)
uninstall:
rm $(DESTDIR)/lib/udev/rules.d/40-multipath.rules
rm $(DESTDIR)$(bindir)/$(EXEC)
+ rm $(DESTDIR)$(bindir)/mpathconf
rm $(DESTDIR)$(mandir)/$(EXEC).8.gz
rm $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
+ rm $(DESTDIR)$(mandir)/mpathconf.8.gz
clean:
rm -f core *.o $(EXEC) *.gz
Index: multipath-tools-111219/multipath/main.c
===================================================================
--- multipath-tools-111219.orig/multipath/main.c
+++ multipath-tools-111219/multipath/main.c
@@ -406,10 +406,10 @@ main (int argc, char *argv[])
exit(1);
}
- if (dm_prereq())
+ if (load_config(DEFAULT_CONFIGFILE))
exit(1);
- if (load_config(DEFAULT_CONFIGFILE))
+ if (dm_prereq())
exit(1);
if (sysfs_init(conf->sysfs_dir, FILE_NAME_SIZE)) {
Index: multipath-tools-111219/multipath/mpathconf
===================================================================
--- /dev/null
+++ multipath-tools-111219/multipath/mpathconf
@@ -0,0 +1,351 @@
+#!/bin/sh
+#
+# Copyright (C) 2010 Red Hat, Inc. All rights reserved.
+#
+# This file is part of the device-mapper-multipath package.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#
+# Simple editting of /etc/multipath.conf
+# This program was largely ripped off from lvmconf
+#
+
+unset ENABLE FIND FRIENDLY MODULE MULTIPATHD CHKCONFIG HAVE_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_DEFAULTS HAVE_FRIENDLY HAVE_MULTIPATHD HAVE_CHKCONFIG HAVE_MODULE SHOW_STATUS CHANGED_CONFIG
+
+DEFAULT_CONFIGFILE="/usr/share/doc/device-mapper-multipath-0.4.9/multipath.conf"
+CONFIGFILE="/etc/multipath.conf"
+MULTIPATHDIR="/etc/multipath"
+TMPFILE=/etc/multipath/.multipath.conf.tmp
+
+function usage
+{
+ echo "usage: $0 <command>"
+ echo ""
+ echo "Commands:"
+ echo "Enable: --enable "
+ echo "Disable: --disable"
+ echo "Set user_friendly_names (Default n): --user_friendly_names <y|n>"
+ echo "Set find_multipaths (Default n): --find_multipaths <y|n>"
+ echo "Load the dm-multipath modules on enable (Default y): --with_module <y|n>"
+ echo "start/stop/reload multipathd (Default n): --with_multipathd <y|n>"
+ echo "chkconfig on/off multipathd (Default y): --with_chkconfig <y|n>"
+ echo ""
+}
+
+function parse_args
+{
+ while [ -n "$1" ]; do
+ case $1 in
+ --enable)
+ ENABLE=1
+ shift
+ ;;
+ --disable)
+ ENABLE=0
+ shift
+ ;;
+ --user_friendly_names)
+ if [ -n "$2" ]; then
+ FRIENDLY=$2
+ shift 2
+ else
+ usage
+ exit 1
+ fi
+ ;;
+ --find_multipaths)
+ if [ -n "$2" ]; then
+ FIND=$2
+ shift 2
+ else
+ usage
+ exit 1
+ fi
+ ;;
+ --with_module)
+ if [ -n "$2" ]; then
+ MODULE=$2
+ shift 2
+ else
+ usage
+ exit 1
+ fi
+ ;;
+ --with_multipathd)
+ if [ -n "$2" ]; then
+ MULTIPATHD=$2
+ shift 2
+ else
+ usage
+ exit 1
+ fi
+ ;;
+ --with_chkconfig)
+ if [ -n "$2" ]; then
+ CHKCONFIG=$2
+ shift 2
+ else
+ usage
+ exit 1
+ fi
+ ;;
+ *)
+ usage
+ exit
+ esac
+ done
+}
+
+function validate_args
+{
+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$MODULE" ]; then
+ echo "ignoring extra parameters on disable"
+ FRIENDLY=""
+ FIND=""
+ MODULE=""
+ fi
+ if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then
+ echo "--user_friendly_names must be either 'y' or 'n'"
+ exit 1
+ fi
+ if [ -n "$FIND" ] && [ "$FIND" != "y" -a "$FIND" != "n" ]; then
+ echo "--find_multipaths must be either 'y' or 'n'"
+ exit 1
+ fi
+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" ]; then
+ SHOW_STATUS=1
+ fi
+ if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then
+ echo "--with_module must be either 'y' or 'n'"
+ exit 1
+ fi
+ if [ -n "$MULTIPATHD" ] && [ "$MULTIPATHD" != "y" -a "$MULTIPATHD" != "n" ]; then
+ echo "--with_multipathd must be either 'y' or 'n'"
+ exit 1
+ fi
+ if [ -n "$CHKCONFIG" ] && [ "$CHKCONFIG" != "y" -a "$CHKCONFIG" != "n" ]; then
+ echo "--with_chkconfig must be either 'y' or 'n'"
+ exit 1
+ fi
+}
+
+umask 0077
+
+parse_args "$@"
+
+validate_args
+
+if [ ! -d "$MULTIPATHDIR" ]; then
+ echo "/etc/multipath/ does not exist. failing"
+ exit 1
+fi
+
+rm $TMPFILE 2> /dev/null
+if [ -f "$CONFIGFILE" ]; then
+ cp $CONFIGFILE $TMPFILE
+elif [ -f "$DEFAULT_CONFIGFILE" ]; then
+ cp $DEFAULT_CONFIGFILE $TMPFILE
+else
+ touch $TMPFILE
+fi
+
+if grep -q "^blacklist[[:space:]]*{" $TMPFILE ; then
+ HAVE_BLACKLIST=1
+fi
+
+if grep -q "^defaults[[:space:]]*{" $TMPFILE ; then
+ HAVE_DEFAULTS=1
+fi
+
+if [ -z "$MODULE" -o "$MODULE" = "y" ]; then
+ if lsmod | grep -q "dm_multipath" ; then
+ HAVE_MODULE=1
+ else
+ HAVE_MODULE=0
+ fi
+fi
+
+if [ "$MULTIPATHD" = "y" ]; then
+ if service multipathd status > /dev/null ; then
+ HAVE_MULTIPATHD=1
+ else
+ HAVE_MULTIPATHD=0
+ fi
+fi
+
+if [ -z "$CHKCONFIG" -o "$CHKCONFIG" = "y" ]; then
+ chkconfig --list multipathd > /dev/null 2>&1
+ if [ $? != 0 ]; then
+ chkconfig --add multipathd
+ fi
+ if chkconfig --list multipathd | grep -q "on" ; then
+ HAVE_CHKCONFIG=1
+ else
+ HAVE_CHKCONFIG=0
+ fi
+fi
+
+if [ "$HAVE_BLACKLIST" = "1" ]; then
+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode \"\.\?\*\"" ; then
+ HAVE_DISABLE=1
+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[#[:space:]]*devnode \"\.\?\*\"" ; then
+ HAVE_DISABLE=0
+ fi
+fi
+
+if [ "$HAVE_DEFAULTS" = "1" ]; then
+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)" ; then
+ HAVE_FIND=1
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)" ; then
+ HAVE_FIND=0
+ fi
+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)" ; then
+ HAVE_FRIENDLY=1
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)" ; then
+ HAVE_FRIENDLY=0
+ fi
+fi
+
+if [ -n "$SHOW_STATUS" ]; then
+ if [ -z "$HAVE_DISABLE" -o "$HAVE_DISABLE" = 0 ]; then
+ echo "multipath is enabled"
+ else
+ echo "multipath is disabled"
+ fi
+ if [ -z "$HAVE_FIND" -o "$HAVE_FIND" = 0 ]; then
+ echo "find_multipaths is disabled"
+ else
+ echo "find_multipaths is enabled"
+ fi
+ if [ -z "$HAVE_FRIENDLY" -o "$HAVE_FRIENDLY" = 0 ]; then
+ echo "user_friendly_names is disabled"
+ else
+ echo "user_friendly_names is enabled"
+ fi
+ if [ -n "$HAVE_MODULE" ]; then
+ if [ "$HAVE_MODULE" = 1 ]; then
+ echo "dm_multipath module is loaded"
+ else
+ echo "dm_multipath module is not loaded"
+ fi
+ fi
+ if [ -n "$HAVE_MULTIPATHD" ]; then
+ service multipathd status
+ fi
+ if [ -n "$HAVE_CHKCONFIG" ]; then
+ if [ "$HAVE_CHKCONFIG" = 1 ]; then
+ echo "multipathd is chkconfiged on"
+ else
+ echo "multipathd is chkconfiged off"
+ fi
+ fi
+ exit 0
+fi
+
+if [ -z "$HAVE_BLACKLIST" ]; then
+ cat >> $TMPFILE <<- _EOF_
+
+blacklist {
+}
+_EOF_
+fi
+
+if [ -z "$HAVE_DEFAULTS" ]; then
+ cat >> $TMPFILE <<- _EOF_
+
+defaults {
+}
+_EOF_
+fi
+
+if [ "$ENABLE" = 1 ]; then
+ if [ "$HAVE_DISABLE" = 1 ]; then
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE
+ fi
+elif [ "$ENABLE" = 0 ]; then
+ if [ -z "$HAVE_DISABLE" ]; then
+ sed -i '/^blacklist[[:space:]]*{/ a\
+ devnode "*"
+' $TMPFILE
+ elif [ "$HAVE_DISABLE" = 0 ]; then
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[#[:space:]]*devnode \"\.\?\*\"/ devnode ".*"/' $TMPFILE
+ fi
+fi
+
+if [ "$FIND" = "n" ]; then
+ if [ "$HAVE_FIND" = 1 ]; then
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)/ find_multipaths no/' $TMPFILE
+ CHANGED_CONFIG=1
+ fi
+elif [ "$FIND" = "y" ]; then
+ if [ -z "$HAVE_FIND" ]; then
+ sed -i '/^defaults[[:space:]]*{/ a\
+ find_multipaths yes
+' $TMPFILE
+ CHANGED_CONFIG=1
+ elif [ "$HAVE_FIND" = 0 ]; then
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)/ find_multipaths yes/' $TMPFILE
+ CHANGED_CONFIG=1
+ fi
+fi
+
+if [ "$FRIENDLY" = "n" ]; then
+ if [ "$HAVE_FRIENDLY" = 1 ]; then
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE
+ CHANGED_CONFIG=1
+ fi
+elif [ "$FRIENDLY" = "y" ]; then
+ if [ -z "$HAVE_FRIENDLY" ]; then
+ sed -i '/^defaults[[:space:]]*{/ a\
+ user_friendly_names yes
+' $TMPFILE
+ CHANGED_CONFIG=1
+ elif [ "$HAVE_FRIENDLY" = 0 ]; then
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE
+ CHANGED_CONFIG=1
+ fi
+fi
+
+if [ -f "$CONFIGFILE" ]; then
+ cp $CONFIGFILE $CONFIGFILE.old
+ if [ $? != 0 ]; then
+ echo "failed to backup old config file, $CONFIGFILE not updated"
+ exit 1
+ fi
+fi
+
+cp $TMPFILE $CONFIGFILE
+if [ $? != 0 ]; then
+ echo "failed to copy new config file into place, check $CONFIGFILE is still OK"
+ exit 1
+fi
+
+rm -f $TMPFILE
+
+if [ "$ENABLE" = 1 ]; then
+ if [ "$HAVE_MODULE" = 0 ]; then
+ modprobe dm_multipath
+ fi
+ if [ "$HAVE_MULTIPATHD" = 0 ]; then
+ service multipathd start
+ fi
+ if [ "$HAVE_CHKCONFIG" = 0 ]; then
+ chkconfig multipathd on
+ fi
+elif [ "$ENABLE" = 0 ]; then
+ if [ "$HAVE_MULTIPATHD" = 1 ]; then
+ service multipathd stop
+ fi
+ if [ "$HAVE_CHKCONFIG" = 1 ]; then
+ chkconfig multipathd off
+ fi
+elif [ -n "$CHANGED_CONFIG" -a "$HAVE_MULTIPATHD" = 1 ]; then
+ service multipathd reload
+fi
Index: multipath-tools-111219/multipath/mpathconf.8
===================================================================
--- /dev/null
+++ multipath-tools-111219/multipath/mpathconf.8
@@ -0,0 +1,116 @@
+.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual"
+.SH NAME
+mpathconf - A tool for configuring device-mapper-multipath
+.SH SYNOPSIS
+.B mpathconf
+.RB [\| commands \|]
+.RB [\| options \|]
+.SH DESCRIPTION
+.B mpathconf
+is a utility that creates or modifies
+.B /etc/multipath.conf.
+It can enable or disable multipathing and configure some common options.
+.B mpathconf
+can also load the
+.B dm_multipath
+module, start and stop the
+.B multipathd
+daemon, and configure the
+.B multipathd
+service to start automatically or not. If
+.B mpathconf
+is called with no commands, it will display the current configuration.
+
+The default options for mpathconf are
+.B --with_module
+and
+.B --with_chkconfig.
+The
+.B --with_multipathd
+option is not set by default. Enabling multipathing will load the
+.B dm_multipath
+module and chkconfig
+.B multipathd
+to start on the next boot, but it will not immediately start it. This is so
+that users can manually edit their config file if necessary, before starting
+.B multipathd.
+
+If
+.B /etc/multipath.conf
+already exists, mpathconf will edit it. If it does not exist, mpathconf will
+use
+.B /usr/share/doc/device-mapper-multipath-0.4.9/multipath.conf
+as the starting file. This file has
+.B user_friendly_names
+set. If this file does not exist, mpathconf will create
+.B /etc/multipath.conf
+from scratch. For most users, this means that
+.B user_friendly_names
+will be set by default, unless they use the
+.B --user_friendly_names n
+command.
+.SH COMMANDS
+.TP
+.B --enable
+Removes any line that blacklists all device nodes from the
+.B /etc/multipath.conf
+blacklist section.
+.TP
+.B --disable
+Adds a line that blacklists all device nodes to the
+.B /etc/multipath.conf
+blacklist section. If no blacklist section exists, it will create one.
+.TP
+.B --user_friendly_name \fP { \fBy\fP | \fBn\fP }
+If set to \fBy\fP, this adds the line
+.B user_friendly_names yes
+to the
+.B /etc/multipath.conf
+defaults section. If set to \fBn\fP, this removes the line, if present. This
+command can be used along with any other command.
+.TP
+.B --find_multipaths\fP { \fBy\fP | \fBn\fP }
+If set to \fBy\fP, this adds the line
+.B find_multipaths yes
+to the
+.B /etc/multipath.conf
+defaults section. If set to \fBn\fP, this removes the line, if present. This
+command can be used aldong with any other command.
+.SH OPTIONS
+.TP
+.B --with_module\fP { \fBy\fP | \fBn\fP }
+If set to \fBy\fP, this runs
+.B modprobe dm_multipath
+to install the multipath modules. This option only works with the
+.B --enable
+command. This option is set to \fBy\fP by default.
+.TP
+.B --with_multipathd { \fBy\fP | \fBn\fP }
+If set to \fBy\fP, this runs
+.B service multipathd start
+to start the multipathd daemon on \fB--enable\fP,
+.B service multipathd stop
+to start the multipathd daemon on \fB--disable\fP, and
+.B service multipathd reload
+to reconfigure multipathd on \fB--user_frindly_names\fP and
+\fB--find_multipaths\fP.
+This option is set to \fBn\fP by default.
+.TP
+.B --with_chkconfig { \fBy\fP | \fBn\fP }
+If set to \fBy\fP, this runs
+.B chkconfig multipathd on
+to set multipathd to start automatically on \fB--enable\fP and
+.B chkconfig multipathd off
+to stop multipathd for starting automatically on \fB--disable\fP.
+This option is set to \fBy\fP by default.
+.SH FILES
+.BR /etc/multipath.conf
+.SH "SEE ALSO"
+.BR multipath.conf (5),
+.BR chkconfig (8),
+.BR modprobe (8),
+.BR multipath (8),
+.BR multipathd (8),
+.BR service (8),
+.SH AUTHOR
+Benjamin Marzinski <bmarzins@redhat.com>

View File

@ -1,26 +1,24 @@
--- ---
libmultipath/Makefile | 2 libmultipath/Makefile | 2
libmultipath/alias.c | 152 ------------------------------ libmultipath/alias.c | 151 ---------------------------------------
libmultipath/alias.h | 1 libmultipath/alias.h | 1
libmultipath/config.c | 5 - libmultipath/config.c | 1
libmultipath/config.h | 1 libmultipath/config.h | 1
libmultipath/configure.c | 22 ++++ libmultipath/configure.c | 14 +++
libmultipath/defaults.h | 2 libmultipath/defaults.h | 2
libmultipath/dict.c | 34 ++++++ libmultipath/dict.c | 34 ++++++++
libmultipath/file.c | 178 +++++++++++++++++++++++++++++++++++ libmultipath/file.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++
libmultipath/file.h | 11 ++ libmultipath/file.h | 11 ++
libmultipath/finder.c | 165 +++++++++++++++++++++++++++++++++ libmultipath/finder.c | 165 +++++++++++++++++++++++++++++++++++++++++++
libmultipath/finder.h | 18 +++ libmultipath/finder.h | 18 ++++
multipath/Makefile | 2 multipath/main.c | 4 -
multipath/main.c | 2 multipathd/main.c | 6 +
multipath/mpathconf | 234 +++++++++++++++++++++++++++++++++++++++++++++++ 14 files changed, 437 insertions(+), 151 deletions(-)
multipathd/main.c | 24 +++-
16 files changed, 690 insertions(+), 163 deletions(-)
Index: multipath-tools/libmultipath/alias.c Index: multipath-tools-111219/libmultipath/alias.c
=================================================================== ===================================================================
--- multipath-tools.orig/libmultipath/alias.c --- multipath-tools-111219.orig/libmultipath/alias.c
+++ multipath-tools/libmultipath/alias.c +++ multipath-tools-111219/libmultipath/alias.c
@@ -3,19 +3,16 @@ @@ -3,19 +3,16 @@
* Copyright (c) 2005 Benjamin Marzinski, Redhat * Copyright (c) 2005 Benjamin Marzinski, Redhat
*/ */
@ -42,10 +40,11 @@ Index: multipath-tools/libmultipath/alias.c
/* /*
@@ -37,149 +34,6 @@ @@ -36,148 +33,6 @@
* See the file COPYING included with this distribution for more details.
*/ */
static int -static int
-ensure_directories_exist(char *str, mode_t dir_mode) -ensure_directories_exist(char *str, mode_t dir_mode)
-{ -{
- char *pathname; - char *pathname;
@ -187,12 +186,10 @@ Index: multipath-tools/libmultipath/alias.c
- close(fd); - close(fd);
- return -1; - return -1;
-} -}
-
-static int static int
format_devname(char *name, int id, int len) format_devname(char *name, int id, int len, char *prefix)
{ @@ -366,7 +221,7 @@ get_user_friendly_alias(char *wwid, char
int pos;
@@ -364,7 +218,7 @@ get_user_friendly_alias(char *wwid, char
return NULL; return NULL;
} }
@ -201,7 +198,7 @@ Index: multipath-tools/libmultipath/alias.c
if (fd < 0) if (fd < 0)
return NULL; return NULL;
@@ -414,7 +268,7 @@ get_user_friendly_wwid(char *alias, char @@ -416,7 +271,7 @@ get_user_friendly_wwid(char *alias, char
return NULL; return NULL;
} }
@ -210,66 +207,40 @@ Index: multipath-tools/libmultipath/alias.c
if (fd < 0) if (fd < 0)
return NULL; return NULL;
Index: multipath-tools/libmultipath/alias.h Index: multipath-tools-111219/libmultipath/alias.h
=================================================================== ===================================================================
--- multipath-tools.orig/libmultipath/alias.h --- multipath-tools-111219.orig/libmultipath/alias.h
+++ multipath-tools/libmultipath/alias.h +++ multipath-tools-111219/libmultipath/alias.h
@@ -1,4 +1,3 @@ @@ -1,4 +1,3 @@
-#define BINDINGS_FILE_TIMEOUT 30 -#define BINDINGS_FILE_TIMEOUT 30
#define BINDINGS_FILE_HEADER \ #define BINDINGS_FILE_HEADER \
"# Multipath bindings, Version : 1.0\n" \ "# Multipath bindings, Version : 1.0\n" \
"# NOTE: this file is automatically maintained by the multipath program.\n" \ "# NOTE: this file is automatically maintained by the multipath program.\n" \
Index: multipath-tools/libmultipath/config.c Index: multipath-tools-111219/libmultipath/config.c
=================================================================== ===================================================================
--- multipath-tools.orig/libmultipath/config.c --- multipath-tools-111219.orig/libmultipath/config.c
+++ multipath-tools/libmultipath/config.c +++ multipath-tools-111219/libmultipath/config.c
@@ -452,6 +452,7 @@ load_config (char * file) @@ -504,6 +504,7 @@ load_config (char * file)
conf->multipath_dir = set_default(DEFAULT_MULTIPATHDIR); conf->reassign_maps = DEFAULT_REASSIGN_MAPS;
conf->flush_on_last_del = 0; conf->checkint = DEFAULT_CHECKINT;
conf->attribute_flags = 0; conf->max_checkint = MAX_CHECKINT(conf->checkint);
+ conf->find_multipaths = DEFAULT_FIND_MULTIPATHS; + conf->find_multipaths = DEFAULT_FIND_MULTIPATHS;
/* /*
* preload default hwtable * preload default hwtable
@@ -476,10 +477,12 @@ load_config (char * file) Index: multipath-tools-111219/libmultipath/configure.c
}
} else {
condlog(0, "/etc/multipath.conf does not exist, blacklisting all devices.");
- condlog(0, "A default multipath.conf file is located at");
+ condlog(0, "A sample multipath.conf file is located at");
condlog(0,
"/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf",
MULTIPATH_VERSION(VERSION_CODE));
+ condlog(0,
+"You can run /sbin/mpathconf to create or modify /etc/multipath.conf");
conf->blist_devnode = vector_alloc();
if (!conf->blist_devnode) {
condlog(0, "cannot allocate blacklist\n");
Index: multipath-tools/libmultipath/config.h
=================================================================== ===================================================================
--- multipath-tools.orig/libmultipath/config.h --- multipath-tools-111219.orig/libmultipath/configure.c
+++ multipath-tools/libmultipath/config.h +++ multipath-tools-111219/libmultipath/configure.c
@@ -85,6 +85,7 @@ struct config { @@ -36,6 +36,7 @@
int attribute_flags;
int fast_io_fail;
unsigned int dev_loss;
+ int find_multipaths;
uid_t uid;
gid_t gid;
mode_t mode;
Index: multipath-tools/libmultipath/configure.c
===================================================================
--- multipath-tools.orig/libmultipath/configure.c
+++ multipath-tools/libmultipath/configure.c
@@ -35,6 +35,7 @@
#include "alias.h"
#include "prio.h" #include "prio.h"
#include "util.h" #include "util.h"
#include "uxsock.h"
+#include "finder.h" +#include "finder.h"
extern int extern int
setup_map (struct multipath * mpp) setup_map (struct multipath * mpp, char * params, int params_size)
@@ -403,6 +404,8 @@ domap (struct multipath * mpp) @@ -405,6 +406,8 @@ domap (struct multipath * mpp, char * pa
* DM_DEVICE_CREATE, DM_DEVICE_RENAME, or DM_DEVICE_RELOAD * DM_DEVICE_CREATE, DM_DEVICE_RENAME, or DM_DEVICE_RELOAD
* succeeded * succeeded
*/ */
@ -278,7 +249,7 @@ Index: multipath-tools/libmultipath/configure.c
if (!conf->daemon) { if (!conf->daemon) {
/* multipath client mode */ /* multipath client mode */
dm_switchgroup(mpp->alias, mpp->bestpg); dm_switchgroup(mpp->alias, mpp->bestpg);
@@ -462,6 +465,10 @@ coalesce_paths (struct vectors * vecs, v @@ -492,6 +495,10 @@ coalesce_paths (struct vectors * vecs, v
memset(empty_buff, 0, WWID_SIZE); memset(empty_buff, 0, WWID_SIZE);
@ -289,28 +260,7 @@ Index: multipath-tools/libmultipath/configure.c
if (force_reload) { if (force_reload) {
vector_foreach_slot (pathvec, pp1, k) { vector_foreach_slot (pathvec, pp1, k) {
pp1->mpp = NULL; pp1->mpp = NULL;
@@ -472,21 +479,32 @@ coalesce_paths (struct vectors * vecs, v @@ -521,6 +528,13 @@ coalesce_paths (struct vectors * vecs, v
/* 1. if path has no unique id or wwid blacklisted */
if (memcmp(empty_buff, pp1->wwid, WWID_SIZE) == 0 ||
- filter_path(conf, pp1) > 0)
+ filter_path(conf, pp1) > 0) {
+ orphan_path(pp1);
continue;
+ }
/* 2. if path already coalesced */
if (pp1->mpp)
continue;
/* 3. if path has disappeared */
- if (!pp1->size)
+ if (!pp1->size) {
+ orphan_path(pp1);
continue;
+ }
/* 4. path is out of scope */
if (refwwid && strncmp(pp1->wwid, refwwid, WWID_SIZE)) if (refwwid && strncmp(pp1->wwid, refwwid, WWID_SIZE))
continue; continue;
@ -324,30 +274,30 @@ Index: multipath-tools/libmultipath/configure.c
/* /*
* at this point, we know we really got a new mp * at this point, we know we really got a new mp
*/ */
Index: multipath-tools/libmultipath/defaults.h Index: multipath-tools-111219/libmultipath/defaults.h
=================================================================== ===================================================================
--- multipath-tools.orig/libmultipath/defaults.h --- multipath-tools-111219.orig/libmultipath/defaults.h
+++ multipath-tools/libmultipath/defaults.h +++ multipath-tools-111219/libmultipath/defaults.h
@@ -12,6 +12,7 @@ @@ -15,6 +15,7 @@
#define DEFAULT_PGTIMEOUT -PGTIMEOUT_NONE
#define DEFAULT_USER_FRIENDLY_NAMES 0 #define DEFAULT_USER_FRIENDLY_NAMES 0
#define DEFAULT_VERBOSITY 2 #define DEFAULT_VERBOSITY 2
#define DEFAULT_REASSIGN_MAPS 1
+#define DEFAULT_FIND_MULTIPATHS 0 +#define DEFAULT_FIND_MULTIPATHS 0
#define DEFAULT_CHECKINT 5 #define DEFAULT_CHECKINT 5
#define MAX_CHECKINT(a) (a << 2) #define MAX_CHECKINT(a) (a << 2)
@@ -20,5 +21,6 @@ @@ -24,5 +25,6 @@
#define DEFAULT_SOCKET "/var/run/multipathd.sock" #define DEFAULT_SOCKET "/var/run/multipathd.sock"
#define DEFAULT_CONFIGFILE "/etc/multipath.conf" #define DEFAULT_CONFIGFILE "/etc/multipath.conf"
#define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings" #define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings"
+#define DEFAULT_WWIDS_FILE "/etc/multipath/wwids" +#define DEFAULT_WWIDS_FILE "/etc/multipath/wwids"
char * set_default (char * str); char * set_default (char * str);
Index: multipath-tools/libmultipath/dict.c Index: multipath-tools-111219/libmultipath/dict.c
=================================================================== ===================================================================
--- multipath-tools.orig/libmultipath/dict.c --- multipath-tools-111219.orig/libmultipath/dict.c
+++ multipath-tools/libmultipath/dict.c +++ multipath-tools-111219/libmultipath/dict.c
@@ -444,6 +444,27 @@ def_flush_on_last_del_handler(vector str @@ -544,6 +544,27 @@ def_log_checker_err_handler(vector strve
} }
static int static int
@ -375,7 +325,7 @@ Index: multipath-tools/libmultipath/dict.c
names_handler(vector strvec) names_handler(vector strvec)
{ {
char * buff; char * buff;
@@ -2076,6 +2097,18 @@ snprint_def_flush_on_last_del (char * bu @@ -2365,6 +2386,18 @@ snprint_def_log_checker_err (char * buff
} }
static int static int
@ -393,19 +343,19 @@ Index: multipath-tools/libmultipath/dict.c
+static int +static int
snprint_def_user_friendly_names (char * buff, int len, void * data) snprint_def_user_friendly_names (char * buff, int len, void * data)
{ {
if (conf->user_friendly_names == DEFAULT_USER_FRIENDLY_NAMES) if (!conf->user_friendly_names)
@@ -2141,6 +2174,7 @@ init_keywords(void) @@ -2456,6 +2489,7 @@ init_keywords(void)
install_keyword("gid", &def_gid_handler, &snprint_def_gid);
install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail);
install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss); install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss);
install_keyword("bindings_file", &bindings_file_handler, &snprint_def_bindings_file);
install_keyword("log_checker_err", &def_log_checker_err_handler, &snprint_def_log_checker_err);
+ install_keyword("find_multipaths", &def_find_multipaths_handler, &snprint_def_find_multipaths); + install_keyword("find_multipaths", &def_find_multipaths_handler, &snprint_def_find_multipaths);
__deprecated install_keyword("default_selector", &def_selector_handler, NULL); __deprecated install_keyword("default_selector", &def_selector_handler, NULL);
__deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL); __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
__deprecated install_keyword("default_getuid_callout", &def_getuid_callout_handler, NULL); __deprecated install_keyword("default_getuid_callout", &def_getuid_callout_handler, NULL);
Index: multipath-tools/libmultipath/file.c Index: multipath-tools-111219/libmultipath/file.c
=================================================================== ===================================================================
--- /dev/null --- /dev/null
+++ multipath-tools/libmultipath/file.c +++ multipath-tools-111219/libmultipath/file.c
@@ -0,0 +1,178 @@ @@ -0,0 +1,178 @@
+/* +/*
+ * Copyright (c) 2005 Christophe Varoqui + * Copyright (c) 2005 Christophe Varoqui
@ -585,10 +535,10 @@ Index: multipath-tools/libmultipath/file.c
+ close(fd); + close(fd);
+ return -1; + return -1;
+} +}
Index: multipath-tools/libmultipath/file.h Index: multipath-tools-111219/libmultipath/file.h
=================================================================== ===================================================================
--- /dev/null --- /dev/null
+++ multipath-tools/libmultipath/file.h +++ multipath-tools-111219/libmultipath/file.h
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
+/* +/*
+ * Copyright (c) 2010 Benjamin Marzinski, Redhat + * Copyright (c) 2010 Benjamin Marzinski, Redhat
@ -601,10 +551,10 @@ Index: multipath-tools/libmultipath/file.h
+int open_file(char *file, int *can_write, char *header); +int open_file(char *file, int *can_write, char *header);
+ +
+#endif /* _FILE_H */ +#endif /* _FILE_H */
Index: multipath-tools/libmultipath/finder.c Index: multipath-tools-111219/libmultipath/finder.c
=================================================================== ===================================================================
--- /dev/null --- /dev/null
+++ multipath-tools/libmultipath/finder.c +++ multipath-tools-111219/libmultipath/finder.c
@@ -0,0 +1,165 @@ @@ -0,0 +1,165 @@
+#include <stdlib.h> +#include <stdlib.h>
+#include <errno.h> +#include <errno.h>
@ -771,10 +721,10 @@ Index: multipath-tools/libmultipath/finder.c
+ condlog(4, "wwid %s already in wwids file", wwid); + condlog(4, "wwid %s already in wwids file", wwid);
+ return 0; + return 0;
+} +}
Index: multipath-tools/libmultipath/finder.h Index: multipath-tools-111219/libmultipath/finder.h
=================================================================== ===================================================================
--- /dev/null --- /dev/null
+++ multipath-tools/libmultipath/finder.h +++ multipath-tools-111219/libmultipath/finder.h
@@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
+/* +/*
+ * Copyright (c) 2010 Benjamin Marzinski, Redhat + * Copyright (c) 2010 Benjamin Marzinski, Redhat
@ -794,11 +744,27 @@ Index: multipath-tools/libmultipath/finder.h
+int remember_wwid(char *wwid); +int remember_wwid(char *wwid);
+ +
+#endif /* _FINDER_H */ +#endif /* _FINDER_H */
Index: multipath-tools/multipath/main.c Index: multipath-tools-111219/multipath/main.c
=================================================================== ===================================================================
--- multipath-tools.orig/multipath/main.c --- multipath-tools-111219.orig/multipath/main.c
+++ multipath-tools/multipath/main.c +++ multipath-tools-111219/multipath/main.c
@@ -307,7 +307,7 @@ configure (void) @@ -53,6 +53,7 @@
#include <errno.h>
#include <sys/time.h>
#include <sys/resource.h>
+#include <finder.h>
#include "dev_t.h"
int logsink;
@@ -209,6 +210,7 @@ get_dm_mpvec (vector curmp, vector pathv
if (!conf->dry_run)
reinstate_paths(mpp);
+ remember_wwid(mpp->wwid);
}
return 0;
}
@@ -316,7 +318,7 @@ configure (void)
/* /*
* core logic entry point * core logic entry point
*/ */
@ -807,365 +773,52 @@ Index: multipath-tools/multipath/main.c
out: out:
if (refwwid) if (refwwid)
Index: multipath-tools/multipathd/main.c Index: multipath-tools-111219/multipathd/main.c
=================================================================== ===================================================================
--- multipath-tools.orig/multipathd/main.c --- multipath-tools-111219.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c +++ multipath-tools-111219/multipathd/main.c
@@ -47,6 +47,7 @@ @@ -48,6 +48,7 @@
#include <print.h> #include <print.h>
#include <configure.h> #include <configure.h>
#include <prio.h> #include <prio.h>
+#include <finder.h> +#include <finder.h>
#include <pgpolicies.h>
#include <uevent.h>
#include "main.h" @@ -471,6 +472,11 @@ rescan:
#include "pidfile.h" return 1;
@@ -397,7 +398,7 @@ ev_add_path (char * devname, struct vect
*/
if (memcmp(empty_buff, pp->wwid, WWID_SIZE) == 0) {
condlog(0, "%s: failed to get path uid", devname);
- return 1; /* leave path added to pathvec */
+ goto fail; /* leave path added to pathvec */
} }
if (filter_path(conf, pp) > 0){
int i = find_slot(vecs->pathvec, (void *)pp);
@@ -412,18 +413,23 @@ rescan:
condlog(4,"%s: adopting all paths for path %s",
mpp->alias, pp->dev);
if (adopt_paths(vecs->pathvec, mpp))
- return 1; /* leave path added to pathvec */
+ goto fail; /* leave path added to pathvec */
verify_paths(mpp, vecs, NULL);
mpp->flush_on_last_del = FLUSH_UNDEF;
mpp->action = ACT_RELOAD;
}
else {
+ if (conf->find_multipaths && + if (conf->find_multipaths &&
+ !should_multipath(pp, vecs->pathvec)) { + !should_multipath(pp, vecs->pathvec)) {
+ orphan_path(pp); + orphan_path(pp);
+ return 0; + return 0;
+ } + }
condlog(4,"%s: creating new map", pp->dev); condlog(4,"%s: creating new map", pp->dev);
if ((mpp = add_map_with_path(vecs, pp, 1))) if ((mpp = add_map_with_path(vecs, pp, 1))) {
mpp->action = ACT_CREATE; mpp->action = ACT_CREATE;
else Index: multipath-tools-111219/libmultipath/Makefile
- return 1; /* leave path added to pathvec */
+ goto fail; /* leave path added to pathvec */
}
/*
@@ -432,7 +438,7 @@ rescan:
if (setup_map(mpp)) {
condlog(0, "%s: failed to setup map for addition of new "
"path %s", mpp->alias, devname);
- goto out;
+ goto fail_map;
}
/*
* reload the map for the multipath mapped device
@@ -450,7 +456,7 @@ rescan:
goto rescan;
}
else
- goto out;
+ goto fail_map;
}
dm_lib_release();
@@ -458,19 +464,21 @@ rescan:
* update our state from kernel regardless of create or reload
*/
if (setup_multipath(vecs, mpp))
- goto out;
+ goto fail_map;
sync_map_state(mpp);
if (mpp->action == ACT_CREATE &&
start_waiter_thread(mpp, vecs))
- goto out;
+ goto fail_map;
condlog(2, "%s path added to devmap %s", devname, mpp->alias);
return 0;
-out:
+fail_map:
remove_map(mpp, vecs, 1);
+fail:
+ orphan_path(pp);
return 1;
}
Index: multipath-tools/libmultipath/Makefile
=================================================================== ===================================================================
--- multipath-tools.orig/libmultipath/Makefile --- multipath-tools-111219.orig/libmultipath/Makefile
+++ multipath-tools/libmultipath/Makefile +++ multipath-tools-111219/libmultipath/Makefile
@@ -12,7 +12,7 @@ OBJS = memory.o parser.o vector.o devmap @@ -15,7 +15,7 @@ OBJS = memory.o parser.o vector.o devmap
pgpolicies.o debug.o regex.o defaults.o uevent.o \ pgpolicies.o debug.o regex.o defaults.o uevent.o \
switchgroup.o uxsock.o print.o alias.o log_pthread.o \ switchgroup.o uxsock.o print.o alias.o log_pthread.o \
log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \ log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \
- lock.o waiter.o - lock.o waiter.o
+ lock.o waiter.o file.o finder.o + lock.o waiter.o file.o finder.o
LIBDM_API_FLUSH = $(shell if test -d /lib64 ; then objdump -T /lib64/libdevmapper.so* ; else objdump -T /lib/libdevmapper.so.* ; fi | grep -c dm_task_no_flush) LIBDM_API_FLUSH = $(shell grep -Ecs '^[a-z]*[[:space:]]+dm_task_no_flush' /usr/include/libdevmapper.h)
Index: multipath-tools/multipath/mpathconf Index: multipath-tools-111219/libmultipath/config.h
=================================================================== ===================================================================
--- /dev/null --- multipath-tools-111219.orig/libmultipath/config.h
+++ multipath-tools/multipath/mpathconf +++ multipath-tools-111219/libmultipath/config.h
@@ -0,0 +1,234 @@ @@ -95,6 +95,7 @@ struct config {
+#!/bin/sh unsigned int dev_loss;
+# int log_checker_err;
+# Copyright (C) 2010 Red Hat, Inc. All rights reserved. int allow_queueing;
+# + int find_multipaths;
+# This file is part of the device-mapper-multipath package. uid_t uid;
+# gid_t gid;
+# This copyrighted material is made available to anyone wishing to use, mode_t mode;
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+#
+# Simple editting of /etc/multipath.conf
+# This program was largely ripped off from lvmconf
+#
+
+DEFAULT_CONFIGFILE="/usr/share/doc/device-mapper-multipath-0.4.9/multipath.conf"
+CONFIGFILE="/etc/multipath.conf"
+MULTIPATHDIR="/etc/multipath"
+TMPFILE=/etc/multipath/.multipath.conf.tmp
+
+function usage
+{
+ echo "usage: $0 <command>"
+ echo ""
+ echo "Commands:"
+ echo "Enable: --enable [--user_friendly_names <y|n>] [--find_multipaths <y|n>"
+ echo "Disable: --disable"
+ echo "Set user_friendly_names: --user_friendly_names <y|n>"
+ echo "Set find_multipaths: --find_multipaths <y|n>"
+ echo ""
+}
+
+function parse_args
+{
+ while [ -n "$1" ]; do
+ case $1 in
+ --enable)
+ ENABLE=1
+ shift
+ ;;
+ --disable)
+ ENABLE=0
+ shift
+ ;;
+ --user_friendly_names)
+ if [ -n "$2" ]; then
+ FRIENDLY=$2
+ shift 2
+ else
+ usage
+ exit 1
+ fi
+ ;;
+ --find_multipaths)
+ if [ -n "$2" ]; then
+ FIND=$2
+ shift 2
+ else
+ usage
+ exit 1
+ fi
+ ;;
+ *)
+ usage
+ exit
+ esac
+ done
+}
+
+function validate_args
+{
+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" ]; then
+ echo "ignoring extra parameters on disable"
+ FRIENDLY=""
+ FIND=""
+ fi
+ if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then
+ echo "--user_friendly_names must be either 'y' or 'n'"
+ exit 1
+ fi
+ if [ -n "$FIND" ] && [ "$FIND" != "y" -a "$FIND" != "n" ]; then
+ echo "--find_multipaths must be either 'y' or 'n'"
+ exit 1
+ fi
+ if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" ]; then
+ DISPLAY=1
+ fi
+}
+
+umask 0077
+
+parse_args "$@"
+
+validate_args
+
+if [ ! -d "$MULTIPATHDIR" ]; then
+ echo "/etc/multipath/ does not exist. failing"
+ exit 1
+fi
+
+rm $TMPFILE 2> /dev/null
+if [ -f "$CONFIGFILE" ]; then
+ cp $CONFIGFILE $TMPFILE
+elif [ -f "$DEFAULT_CONFIGFILE" ]; then
+ cp $DEFAULT_CONFIGFILE $TMPFILE
+else
+ touch $TMPFILE
+fi
+
+if grep -q "^blacklist[[:space:]]*{" $TMPFILE ; then
+ HAVE_BLACKLIST=1
+fi
+
+if grep -q "^defaults[[:space:]]*{" $TMPFILE ; then
+ HAVE_DEFAULTS=1
+fi
+
+if [ "$HAVE_BLACKLIST" = "1" ]; then
+ if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode \"\.\?\*\"" ; then
+ HAVE_DISABLE=1
+ elif sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*#[#[:space:]]*devnode \"\.\?\*\"" ; then
+ HAVE_DISABLE=0
+ fi
+fi
+
+if [ "$HAVE_DEFAULTS" = "1" ]; then
+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)" ; then
+ HAVE_FIND=1
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)" ; then
+ HAVE_FIND=0
+ fi
+ if sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)" ; then
+ HAVE_FRIENDLY=1
+ elif sed -n '/^defaults[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)" ; then
+ HAVE_FRIENDLY=0
+ fi
+fi
+
+if [ -n "$DISPLAY" ]; then
+ if [ -z "$HAVE_DISABLE" -o "$HAVE_DISABLE" = 0 ]; then
+ echo "multipath is enabled"
+ else
+ echo "multipath is disabled"
+ fi
+ if [ -z "$HAVE_FIND" -o "$HAVE_FIND" = 0 ]; then
+ echo "find_multipaths is disabled"
+ else
+ echo "find_multipaths is enabled"
+ fi
+ if [ -z "$HAVE_FRIENDLY" -o "$HAVE_FRIENDLY" = 0 ]; then
+ echo "user_friendly_names is disabled"
+ else
+ echo "user_friendly_names is enabled"
+ fi
+ exit 0
+fi
+
+if [ -z "$HAVE_BLACKLIST" ]; then
+ cat >> $TMPFILE <<- _EOF_
+
+blacklist {
+}
+_EOF_
+fi
+
+if [ -z "$HAVE_DEFAULTS" ]; then
+ cat >> $TMPFILE <<- _EOF_
+
+defaults {
+}
+_EOF_
+fi
+
+if [ "$ENABLE" = 1 ]; then
+ if [ "$HAVE_DISABLE" = 1 ]; then
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*devnode \"\.\?\*\"/# devnode ".*"/' $TMPFILE
+ fi
+elif [ "$ENABLE" = 0 ]; then
+ if [ -z "$HAVE_DISABLE" ]; then
+ sed -i '/^blacklist[[:space:]]*{/ a\
+ devnode "*"
+' $TMPFILE
+ elif [ "$HAVE_DISABLE" = 0 ]; then
+ sed -i '/^blacklist[[:space:]]*{/,/^}/ s/^[[:space:]]*#[#[:space:]]*devnode \"\.\?\*\"/ devnode ".*"/' $TMPFILE
+ fi
+fi
+
+if [ "$FIND" = "n" ]; then
+ if [ "$HAVE_FIND" = 1 ]; then
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)/ find_multipaths no/' $TMPFILE
+ fi
+elif [ "$FIND" = "y" ]; then
+ if [ -z "$HAVE_FIND" ]; then
+ sed -i '/^defaults[[:space:]]*{/ a\
+ find_multipaths yes
+' $TMPFILE
+ elif [ "$HAVE_FIND" = 0 ]; then
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)/ find_multipaths yes/' $TMPFILE
+ fi
+fi
+
+if [ "$FRIENDLY" = "n" ]; then
+ if [ "$HAVE_FRIENDLY" = 1 ]; then
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE
+ fi
+elif [ "$FRIENDLY" = "y" ]; then
+ if [ -z "$HAVE_FRIENDLY" ]; then
+ sed -i '/^defaults[[:space:]]*{/ a\
+ user_friendly_names yes
+' $TMPFILE
+ elif [ "$HAVE_FRIENDLY" = 0 ]; then
+ sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE
+ fi
+fi
+
+if [ -f "$CONFIGFILE" ]; then
+ cp $CONFIGFILE $CONFIGFILE.old
+ if [ $? != 0 ]; then
+ echo "failed to backup old config file, $CONFIGFILE not updated"
+ exit 1
+ fi
+fi
+
+cp $TMPFILE $CONFIGFILE
+if [ $? != 0 ]; then
+ echo "failed to copy new config file into place, check $CONFIGFILE is still OK"
+ exit 1
+fi
+
+rm -f $TMPFILE
Index: multipath-tools/multipath/Makefile
===================================================================
--- multipath-tools.orig/multipath/Makefile
+++ multipath-tools/multipath/Makefile
@@ -21,6 +21,7 @@ $(EXEC): $(OBJS)
install:
$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)/
+ $(INSTALL_PROGRAM) -m 755 mpathconf $(DESTDIR)$(bindir)/
$(INSTALL_PROGRAM) -d $(DESTDIR)/lib/udev/rules.d
$(INSTALL_PROGRAM) -m 644 multipath.rules $(DESTDIR)/lib/udev/rules.d/40-multipath.rules
$(INSTALL_PROGRAM) -d $(DESTDIR)$(mandir)
@@ -31,6 +32,7 @@ install:
uninstall:
rm $(DESTDIR)/lib/udev/rules.d/multipath.rules
rm $(DESTDIR)$(bindir)/$(EXEC)
+ rm $(DESTDIR)$(bindir)/mpathconf
rm $(DESTDIR)$(mandir)/$(EXEC).8.gz
rm $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz

View File

@ -0,0 +1,119 @@
---
libmultipath/finder.c | 2 +-
libmultipath/finder.h | 1 +
multipath/main.c | 35 +++++++++++++++++++++++++++++------
3 files changed, 31 insertions(+), 7 deletions(-)
Index: multipath-tools-111219/libmultipath/finder.c
===================================================================
--- multipath-tools-111219.orig/libmultipath/finder.c
+++ multipath-tools-111219/libmultipath/finder.c
@@ -78,7 +78,7 @@ write_out_wwid(int fd, char *wwid) {
return 1;
}
-static int
+int
check_wwids_file(char *wwid, int write_wwid)
{
int scan_fd, fd, can_write, found, ret;
Index: multipath-tools-111219/libmultipath/finder.h
===================================================================
--- multipath-tools-111219.orig/libmultipath/finder.h
+++ multipath-tools-111219/libmultipath/finder.h
@@ -14,5 +14,6 @@
int should_multipath(struct path *pp, vector pathvec);
int remember_wwid(char *wwid);
+int check_wwids_file(char *wwid, int write_wwid);
#endif /* _FINDER_H */
Index: multipath-tools-111219/multipath/main.c
===================================================================
--- multipath-tools-111219.orig/multipath/main.c
+++ multipath-tools-111219/multipath/main.c
@@ -83,7 +83,7 @@ usage (char * progname)
{
fprintf (stderr, VERSION_STRING);
fprintf (stderr, "Usage:\n");
- fprintf (stderr, " %s [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
+ fprintf (stderr, " %s [-c] [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [dev]\n", progname);
fprintf (stderr, " %s -F [-v lvl]\n", progname);
fprintf (stderr, " %s -t\n", progname);
@@ -96,6 +96,7 @@ usage (char * progname)
" -ll show multipath topology (maximum info)\n" \
" -f flush a multipath device map\n" \
" -F flush all multipath device maps\n" \
+ " -c check if a device should be a path in a multipath device\n" \
" -q allow queue_if_no_path when multipathd is not running\n"\
" -d dry run, do not create or update devmaps\n" \
" -t dump internal hardware table\n" \
@@ -261,9 +262,13 @@ configure (void)
* if we have a blacklisted device parameter, exit early
*/
if (dev &&
- (filter_devnode(conf->blist_devnode, conf->elist_devnode, dev) > 0))
- goto out;
-
+ (filter_devnode(conf->blist_devnode,
+ conf->elist_devnode, dev) > 0)) {
+ if (conf->dry_run == 2)
+ printf("%s is not a valid multipath device path\n",
+ conf->dev);
+ goto out;
+ }
/*
* scope limiting must be translated into a wwid
* failing the translation is fatal (by policy)
@@ -279,6 +284,15 @@ configure (void)
if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
refwwid) > 0)
goto out;
+ if (conf->dry_run == 2) {
+ if (check_wwids_file(refwwid, 0) == 0){
+ printf("%s is a valid multipath device path\n", conf->dev);
+ r = 0;
+ }
+ else
+ printf("%s is not a valid multipath device path\n", conf->dev);
+ goto out;
+ }
}
/*
@@ -418,7 +432,7 @@ main (int argc, char *argv[])
condlog(0, "multipath tools need sysfs mounted");
exit(1);
}
- while ((arg = getopt(argc, argv, ":dhl::FfM:v:p:b:Brtq")) != EOF ) {
+ while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:Brtq")) != EOF ) {
switch(arg) {
case 1: printf("optarg : %s\n",optarg);
break;
@@ -440,8 +454,12 @@ main (int argc, char *argv[])
case 'q':
conf->allow_queueing = 1;
break;
+ case 'c':
+ conf->dry_run = 2;
+ break;
case 'd':
- conf->dry_run = 1;
+ if (!conf->dry_run)
+ conf->dry_run = 1;
break;
case 'f':
conf->remove = FLUSH_ONE;
@@ -523,6 +541,11 @@ main (int argc, char *argv[])
}
dm_init();
+ if (conf->dry_run == 2 &&
+ (!conf->dev || conf->dev_type == DEV_DEVMAP)) {
+ condlog(0, "the -c option requires a path to check");
+ goto out;
+ }
if (conf->remove == FLUSH_ONE) {
if (conf->dev_type == DEV_DEVMAP)
r = dm_flush_map(conf->dev);

View File

@ -1,14 +1,14 @@
--- ---
libmultipath/checkers.h | 3 + libmultipath/checkers.h | 3 +
libmultipath/checkers/Makefile | 4 + libmultipath/checkers/Makefile | 4 +
libmultipath/checkers/tur.c | 111 +++++++++++++++++++++++++++++++++++++++++ libmultipath/checkers/tur.c | 123 +++++++++++++++++++++++++++++++++++++++--
multipath.conf.annotated | 5 + multipath.conf.annotated | 5 +
4 files changed, 121 insertions(+), 2 deletions(-) 4 files changed, 128 insertions(+), 7 deletions(-)
Index: multipath-tools/libmultipath/checkers.h Index: multipath-tools-111219/libmultipath/checkers.h
=================================================================== ===================================================================
--- multipath-tools.orig/libmultipath/checkers.h --- multipath-tools-111219.orig/libmultipath/checkers.h
+++ multipath-tools/libmultipath/checkers.h +++ multipath-tools-111219/libmultipath/checkers.h
@@ -60,6 +60,7 @@ enum path_check_state { @@ -60,6 +60,7 @@ enum path_check_state {
#define DIRECTIO "directio" #define DIRECTIO "directio"
@ -17,7 +17,7 @@ Index: multipath-tools/libmultipath/checkers.h
#define HP_SW "hp_sw" #define HP_SW "hp_sw"
#define RDAC "rdac" #define RDAC "rdac"
#define EMC_CLARIION "emc_clariion" #define EMC_CLARIION "emc_clariion"
@@ -91,6 +92,7 @@ enum path_check_state { @@ -77,6 +78,7 @@ enum path_check_state {
#define CHECKER_MSG_LEN 256 #define CHECKER_MSG_LEN 256
#define CHECKER_DEV_LEN 256 #define CHECKER_DEV_LEN 256
#define LIB_CHECKER_NAMELEN 256 #define LIB_CHECKER_NAMELEN 256
@ -25,7 +25,7 @@ Index: multipath-tools/libmultipath/checkers.h
struct checker { struct checker {
struct list_head node; struct list_head node;
@@ -99,6 +101,7 @@ struct checker { @@ -88,6 +90,7 @@ struct checker {
int disable; int disable;
char name[CHECKER_NAME_LEN]; char name[CHECKER_NAME_LEN];
char message[CHECKER_MSG_LEN]; /* comm with callers */ char message[CHECKER_MSG_LEN]; /* comm with callers */
@ -33,10 +33,10 @@ Index: multipath-tools/libmultipath/checkers.h
void * context; /* store for persistent data */ void * context; /* store for persistent data */
void ** mpcontext; /* store for persistent data shared void ** mpcontext; /* store for persistent data shared
multipath-wide. Use MALLOC if multipath-wide. Use MALLOC if
Index: multipath-tools/libmultipath/checkers/Makefile Index: multipath-tools-111219/libmultipath/checkers/Makefile
=================================================================== ===================================================================
--- multipath-tools.orig/libmultipath/checkers/Makefile --- multipath-tools-111219.orig/libmultipath/checkers/Makefile
+++ multipath-tools/libmultipath/checkers/Makefile +++ multipath-tools-111219/libmultipath/checkers/Makefile
@@ -8,6 +8,7 @@ LIBS= \ @@ -8,6 +8,7 @@ LIBS= \
libcheckcciss_tur.so \ libcheckcciss_tur.so \
libcheckreadsector0.so \ libcheckreadsector0.so \
@ -47,7 +47,7 @@ Index: multipath-tools/libmultipath/checkers/Makefile
libcheckhp_sw.so \ libcheckhp_sw.so \
@@ -23,6 +24,9 @@ libcheckdirectio.so: libsg.o directio.o @@ -23,6 +24,9 @@ libcheckdirectio.so: libsg.o directio.o
libcheck%.so: libsg.o %.o libcheck%.so: libsg.o %.o
$(CC) $(SHARED_FLAGS) -o $@ $^ $(CC) $(LDFLAGS) $(SHARED_FLAGS) -o $@ $^
+hp_tur.o: tur.c +hp_tur.o: tur.c
+ $(CC) $(CFLAGS) -DCHECK_WWID -c -o $@ $< + $(CC) $(CFLAGS) -DCHECK_WWID -c -o $@ $<
@ -55,17 +55,11 @@ Index: multipath-tools/libmultipath/checkers/Makefile
install: install:
$(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir) $(INSTALL_PROGRAM) -m 755 $(LIBS) $(DESTDIR)$(libdir)
Index: multipath-tools/libmultipath/checkers/tur.c Index: multipath-tools-111219/libmultipath/checkers/tur.c
=================================================================== ===================================================================
--- multipath-tools.orig/libmultipath/checkers/tur.c --- multipath-tools-111219.orig/libmultipath/checkers/tur.c
+++ multipath-tools/libmultipath/checkers/tur.c +++ multipath-tools-111219/libmultipath/checkers/tur.c
@@ -15,14 +15,101 @@ @@ -24,12 +24,101 @@
#include "checkers.h"
+#include "../libmultipath/debug.h"
#include "../libmultipath/sg_include.h"
#define TUR_CMD_LEN 6 #define TUR_CMD_LEN 6
#define HEAVY_CHECK_COUNT 10 #define HEAVY_CHECK_COUNT 10
@ -73,6 +67,9 @@ Index: multipath-tools/libmultipath/checkers/tur.c
+#define MSG_TUR_UP "HP tur checker reports path is up" +#define MSG_TUR_UP "HP tur checker reports path is up"
+#define MSG_TUR_DOWN "HP tur checker reports path is down" +#define MSG_TUR_DOWN "HP tur checker reports path is down"
+#define MSG_TUR_GHOST "HP tur checker reports path is in standby state" +#define MSG_TUR_GHOST "HP tur checker reports path is in standby state"
+#define MSG_TUR_RUNNING "HP tur checker still running"
+#define MSG_TUR_TIMEOUT "HP tur checker timed out"
+#define MSG_TUR_FAILED "HP tur checker failed to initialize"
+#define EVPD 0x01 +#define EVPD 0x01
+#define PAGE_83 0x83 +#define PAGE_83 0x83
+#define INQUIRY_CMD 0x12 +#define INQUIRY_CMD 0x12
@ -82,11 +79,14 @@ Index: multipath-tools/libmultipath/checkers/tur.c
#define MSG_TUR_UP "tur checker reports path is up" #define MSG_TUR_UP "tur checker reports path is up"
#define MSG_TUR_DOWN "tur checker reports path is down" #define MSG_TUR_DOWN "tur checker reports path is down"
#define MSG_TUR_GHOST "tur checker reports path is in standby state" #define MSG_TUR_GHOST "tur checker reports path is in standby state"
#define MSG_TUR_RUNNING "tur checker still running"
#define MSG_TUR_TIMEOUT "tur checker timed out"
#define MSG_TUR_FAILED "tur checker failed to initialize"
+#endif +#endif
+ +
+#ifdef CHECK_WWID +#ifdef CHECK_WWID
+static int +static int
+do_inq(struct checker * c, char * wwid) +do_inq(int fd, unsigned int timeout, char * wwid)
+{ +{
+ int ret = -1; + int ret = -1;
+ unsigned char inq_cmd[INQUIRY_CMDLEN] = + unsigned char inq_cmd[INQUIRY_CMDLEN] =
@ -111,9 +111,9 @@ Index: multipath-tools/libmultipath/checkers/tur.c
+ io_hdr.dxferp = (unsigned char *)resp_buffer; + io_hdr.dxferp = (unsigned char *)resp_buffer;
+ io_hdr.cmdp = inq_cmd; + io_hdr.cmdp = inq_cmd;
+ io_hdr.sbp = sense_buffer; + io_hdr.sbp = sense_buffer;
+ io_hdr.timeout = 60; // IOCTL timeout value. + io_hdr.timeout = timeout; // IOCTL timeout value.
+ +
+ if (ioctl(c->fd, SG_IO, &io_hdr) < 0) { + if (ioctl(fd, SG_IO, &io_hdr) < 0) {
+ condlog(0, "SG_IO ioctl failed: %s", strerror(errno)); + condlog(0, "SG_IO ioctl failed: %s", strerror(errno));
+ return ret; + return ret;
+ } + }
@ -160,57 +160,100 @@ Index: multipath-tools/libmultipath/checkers/tur.c
+#endif +#endif
struct tur_checker_context { struct tur_checker_context {
void * dummy; dev_t devt;
@@ -30,6 +117,9 @@ struct tur_checker_context { @@ -43,6 +132,7 @@ struct tur_checker_context {
pthread_cond_t active;
pthread_spinlock_t hldr_lock;
int holders;
+ char wwid[WWID_SIZE];
char message[CHECKER_MSG_LEN];
};
int libcheck_init (struct checker * c) @@ -100,12 +190,15 @@ void libcheck_free (struct checker * c)
#define TUR_MSG(msg, fmt, args...) snprintf(msg, CHECKER_MSG_LEN, fmt, ##args);
int
-tur_check(int fd, unsigned int timeout, char *msg)
+tur_check (int fd, unsigned int timeout, char *msg, char *wwid)
{ {
+#ifdef CHECK_WWID struct sg_io_hdr io_hdr;
+ memset(c->wwid, 0, WWID_SIZE);
+#endif
return 0;
}
@@ -45,6 +135,9 @@ libcheck_check (struct checker * c)
unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 }; unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 };
unsigned char sense_buffer[32]; unsigned char sense_buffer[32];
int retry_tur = 5; int retry_tur = 5;
+#ifdef CHECK_WWID +#ifdef CHECK_WWID
+ char wwid[WWID_SIZE]; + char new_wwid[WWID_SIZE];
+#endif +#endif
retry: retry:
memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
@@ -110,6 +203,24 @@ libcheck_check (struct checker * c) @@ -179,6 +272,24 @@ tur_check(int fd, unsigned int timeout,
MSG(c, MSG_TUR_DOWN); TUR_MSG(msg, MSG_TUR_DOWN);
return PATH_DOWN; return PATH_DOWN;
} }
+#ifdef CHECK_WWID +#ifdef CHECK_WWID
+ if (!do_inq(c, wwid)) { + if (!do_inq(fd, timeout, new_wwid)) {
+ +
+ if(!strcmp(c->wwid, "\0")) { + if(!strcmp(wwid, "\0")) {
+ strcpy(c->wwid, wwid); + strcpy(wwid, new_wwid);
+ goto up; + goto up;
+ } + }
+ +
+ if (strcmp(c->wwid , wwid)) { + if (strcmp(wwid , new_wwid)) {
+ condlog(0, + condlog(0,
+ "hp_tur: Lun collided. new_wwid %s old_wwid %s", + "hp_tur: Lun collided. new_wwid %s old_wwid %s",
+ wwid, c->wwid); + new_wwid, wwid);
+ MSG(c, MSG_TUR_DOWN); + TUR_MSG(msg, MSG_TUR_DOWN);
+ return PATH_DOWN; + return PATH_DOWN;
+ } + }
+ } + }
+up: +up:
+#endif +#endif
MSG(c, MSG_TUR_UP); TUR_MSG(msg, MSG_TUR_UP);
return PATH_UP; return PATH_UP;
} }
Index: multipath-tools/multipath.conf.annotated @@ -215,7 +326,7 @@ void *tur_thread(void *ctx)
ct->state = PATH_PENDING;
pthread_mutex_unlock(&ct->lock);
- state = tur_check(ct->fd, ct->timeout, ct->message);
+ state = tur_check(ct->fd, ct->timeout, ct->message, ct->wwid);
/* TUR checker done */
pthread_mutex_lock(&ct->lock);
@@ -275,7 +386,7 @@ libcheck_check (struct checker * c)
ct->devt = sb.st_rdev;
if (c->sync)
- return tur_check(c->fd, c->timeout, c->message);
+ return tur_check(c->fd, c->timeout, c->message, ct->wwid);
/*
* Async mode
@@ -319,7 +430,8 @@ libcheck_check (struct checker * c)
pthread_mutex_unlock(&ct->lock);
condlog(3, "%d:%d: tur thread not responding, "
"using sync mode", TUR_DEVT(ct));
- return tur_check(c->fd, c->timeout, c->message);
+ return tur_check(c->fd, c->timeout, c->message,
+ ct->wwid);
}
/* Start new TUR checker */
ct->state = PATH_UNCHECKED;
@@ -337,7 +449,8 @@ libcheck_check (struct checker * c)
ct->holders--;
condlog(3, "%d:%d: failed to start tur thread, using"
" sync mode", TUR_DEVT(ct));
- return tur_check(c->fd, c->timeout, c->message);
+ return tur_check(c->fd, c->timeout, c->message,
+ ct->wwid);
}
pthread_attr_destroy(&attr);
tur_timeout(&tsp);
Index: multipath-tools-111219/multipath.conf.annotated
=================================================================== ===================================================================
--- multipath-tools.orig/multipath.conf.annotated --- multipath-tools-111219.orig/multipath.conf.annotated
+++ multipath-tools/multipath.conf.annotated +++ multipath-tools-111219/multipath.conf.annotated
@@ -86,7 +86,8 @@ @@ -96,7 +96,8 @@
# # name : path_checker, checker # # name : path_checker, checker
# # scope : multipath & multipathd # # scope : multipath & multipathd
# # desc : the default method used to determine the paths' state # # desc : the default method used to determine the paths' state
@ -220,8 +263,8 @@ Index: multipath-tools/multipath.conf.annotated
# # default : directio # # default : directio
# # # #
# path_checker directio # path_checker directio
@@ -456,7 +457,7 @@ @@ -493,7 +494,7 @@
# # scope : multipathd # # scope : multipathd & multipathd
# # desc : path checking alorithm to use to check path state # # desc : path checking alorithm to use to check path state
# # values : readsector0|tur|emc_clariion|hp_sw|directio|rdac| # # values : readsector0|tur|emc_clariion|hp_sw|directio|rdac|
-# # cciss_tur -# # cciss_tur

View File

@ -1,29 +0,0 @@
From 887b0721d29eed45621b5a7fefaf462378cc9dcd Mon Sep 17 00:00:00 2001
From: Fabio M. Di Nitto <fdinitto@redhat.com>
Date: Mon, 19 Oct 2009 08:33:07 +0200
Subject: [PATCH 11/12] RH: fix init script LSB headers
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
---
:100644 100644 e46b1b8... cfc9cf5... M multipathd/multipathd.init.redhat
multipathd/multipathd.init.redhat | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/multipathd/multipathd.init.redhat b/multipathd/multipathd.init.redhat
index e46b1b8..cfc9cf5 100644
--- a/multipathd/multipathd.init.redhat
+++ b/multipathd/multipathd.init.redhat
@@ -7,6 +7,10 @@
### BEGIN INIT INFO
# Provides: multipathd
+# Required-Start:
+# Required-Stop:
+# Default-Start:
+# Default-Stop:
# Short-Description: Control multipathd
# Description: This service monitors and manages
# device-mapper multipath devices
--
1.6.5.1

View File

@ -1,378 +0,0 @@
---
kpartx/devmapper.c | 10 ++++++++--
kpartx/devmapper.h | 4 ++--
kpartx/kpartx.c | 28 ++++++++++++++++++++--------
libmultipath/config.h | 2 ++
libmultipath/configure.c | 2 +-
libmultipath/devmapper.c | 29 +++++++++++++++++++----------
libmultipath/devmapper.h | 8 +++++---
multipath/main.c | 1 +
multipathd/main.c | 1 +
9 files changed, 59 insertions(+), 26 deletions(-)
Index: multipath-tools/kpartx/devmapper.c
===================================================================
--- multipath-tools.orig/kpartx/devmapper.c
+++ multipath-tools/kpartx/devmapper.c
@@ -52,8 +52,10 @@ dm_prereq (char * str, int x, int y, int
}
extern int
-dm_simplecmd (int task, const char *name, int no_flush) {
+dm_simplecmd (int task, const char *name, int no_flush, uint32_t *cookie) {
int r = 0;
+ int udev_wait_flag = (task == DM_DEVICE_RESUME ||
+ task == DM_DEVICE_REMOVE);
struct dm_task *dmt;
if (!(dmt = dm_task_create(task)))
@@ -68,6 +70,8 @@ dm_simplecmd (int task, const char *name
if (no_flush)
dm_task_no_flush(dmt);
+ if (udev_wait_flag && !dm_task_set_cookie(dmt, cookie, 0))
+ goto out;
r = dm_task_run(dmt);
out:
@@ -78,7 +82,7 @@ dm_simplecmd (int task, const char *name
extern int
dm_addmap (int task, const char *name, const char *target,
const char *params, uint64_t size, const char *uuid, int part,
- mode_t mode, uid_t uid, gid_t gid) {
+ mode_t mode, uid_t uid, gid_t gid, uint32_t *cookie) {
int r = 0;
struct dm_task *dmt;
char *prefixed_uuid = NULL;
@@ -113,6 +117,8 @@ dm_addmap (int task, const char *name, c
dm_task_no_open_count(dmt);
+ if (task == DM_DEVICE_CREATE && !dm_task_set_cookie(dmt, cookie, 0))
+ goto addout;
r = dm_task_run (dmt);
addout:
Index: multipath-tools/kpartx/kpartx.c
===================================================================
--- multipath-tools.orig/kpartx/kpartx.c
+++ multipath-tools/kpartx/kpartx.c
@@ -82,7 +82,7 @@ initpts(void)
addpts("sun", read_sun_pt);
}
-static char short_opts[] = "ladgvp:t:";
+static char short_opts[] = "ladgvp:t:s";
/* Used in gpt.c */
int force_gpt=0;
@@ -96,6 +96,7 @@ usage(void) {
printf("\t-p set device name-partition number delimiter\n");
printf("\t-g force GUID partition table (GPT)\n");
printf("\t-v verbose\n");
+ printf("\t-s sync mode. Don't return until the partitions are created\n");
return 1;
}
@@ -198,7 +199,9 @@ main(int argc, char **argv){
int loopro = 0;
int hotplug = 0;
int loopcreated = 0;
+ int sync = 0;
struct stat buf;
+ uint32_t cookie = 0;
initpts();
init_crc32();
@@ -251,11 +254,17 @@ main(int argc, char **argv){
case 'd':
what = DELETE;
break;
+ case 's':
+ sync = 1;
+ break;
default:
usage();
exit(1);
}
+ if (!sync)
+ dm_udev_set_sync_support(0);
+
if (dm_prereq(DM_TARGET, 0, 0, 0) && (what == ADD || what == DELETE)) {
fprintf(stderr, "device mapper prerequisites not met\n");
exit(1);
@@ -413,8 +422,8 @@ main(int argc, char **argv){
if (!slices[j].size || !dm_map_present(partname))
continue;
- if (!dm_simplecmd(DM_DEVICE_REMOVE,
- partname, 0)) {
+ if (!dm_simplecmd(DM_DEVICE_REMOVE, partname,
+ 0, &cookie)) {
r++;
continue;
}
@@ -463,14 +472,14 @@ main(int argc, char **argv){
if (!dm_addmap(op, partname, DM_TARGET, params,
slices[j].size, uuid, j+1,
buf.st_mode & 0777, buf.st_uid,
- buf.st_gid)) {
+ buf.st_gid, &cookie)) {
fprintf(stderr, "create/reload failed on %s\n",
partname);
r++;
}
if (op == DM_DEVICE_RELOAD &&
- !dm_simplecmd(DM_DEVICE_RESUME,
- partname, 1)) {
+ !dm_simplecmd(DM_DEVICE_RESUME, partname,
+ 1, &cookie)) {
fprintf(stderr, "resume failed on %s\n",
partname);
r++;
@@ -529,11 +538,13 @@ main(int argc, char **argv){
dm_addmap(op, partname, DM_TARGET, params,
slices[j].size, uuid, j+1,
buf.st_mode & 0777,
- buf.st_uid, buf.st_gid);
+ buf.st_uid, buf.st_gid,
+ &cookie);
if (op == DM_DEVICE_RELOAD)
dm_simplecmd(DM_DEVICE_RESUME,
- partname, 1);
+ partname, 1,
+ &cookie);
dm_devn(partname, &slices[j].major,
&slices[j].minor);
@@ -557,6 +568,7 @@ main(int argc, char **argv){
if (n > 0)
break;
}
+ dm_udev_wait(cookie);
dm_lib_release();
dm_lib_exit();
Index: multipath-tools/kpartx/devmapper.h
===================================================================
--- multipath-tools.orig/kpartx/devmapper.h
+++ multipath-tools/kpartx/devmapper.h
@@ -3,9 +3,9 @@
#define MKDEV(ma,mi) ((mi & 0xff) | (ma << 8) | ((mi & ~0xff) << 12))
int dm_prereq (char *, int, int, int);
-int dm_simplecmd (int, const char *, int);
+int dm_simplecmd (int, const char *, int, uint32_t *);
int dm_addmap (int, const char *, const char *, const char *, uint64_t,
- const char *, int, mode_t, uid_t, gid_t);
+ const char *, int, mode_t, uid_t, gid_t, uint32_t *);
int dm_map_present (char *);
char * dm_mapname(int major, int minor);
dev_t dm_get_first_dep(char *devname);
Index: multipath-tools/libmultipath/config.h
===================================================================
--- multipath-tools.orig/libmultipath/config.h
+++ multipath-tools/libmultipath/config.h
@@ -2,6 +2,7 @@
#define _CONFIG_H
#include <sys/types.h>
+#include <stdint.h>
#define ORIGIN_DEFAULT 0
#define ORIGIN_CONFIG 1
@@ -84,6 +85,7 @@ struct config {
uid_t uid;
gid_t gid;
mode_t mode;
+ uint32_t cookie;
char * dev;
char * sysfs_dir;
Index: multipath-tools/libmultipath/devmapper.c
===================================================================
--- multipath-tools.orig/libmultipath/devmapper.c
+++ multipath-tools/libmultipath/devmapper.c
@@ -149,8 +149,10 @@ dm_prereq (void)
}
static int
-dm_simplecmd (int task, const char *name, int no_flush) {
+dm_simplecmd (int task, const char *name, int no_flush, int need_sync) {
int r = 0;
+ int udev_wait_flag = (need_sync && (task == DM_DEVICE_RESUME ||
+ task == DM_DEVICE_REMOVE));
struct dm_task *dmt;
if (!(dmt = dm_task_create (task)))
@@ -166,6 +168,8 @@ dm_simplecmd (int task, const char *name
dm_task_no_flush(dmt); /* for DM_DEVICE_SUSPEND/RESUME */
#endif
+ if (udev_wait_flag && !dm_task_set_cookie(dmt, &conf->cookie, 0))
+ goto out;
r = dm_task_run (dmt);
out:
@@ -174,13 +178,13 @@ dm_simplecmd (int task, const char *name
}
extern int
-dm_simplecmd_flush (int task, const char *name) {
- return dm_simplecmd(task, name, 0);
+dm_simplecmd_flush (int task, const char *name, int needsync) {
+ return dm_simplecmd(task, name, 0, needsync);
}
extern int
dm_simplecmd_noflush (int task, const char *name) {
- return dm_simplecmd(task, name, 1);
+ return dm_simplecmd(task, name, 1, 1);
}
extern int
@@ -226,6 +230,9 @@ dm_addmap (int task, const char *target,
dm_task_no_open_count(dmt);
+ if (task == DM_DEVICE_CREATE &&
+ !dm_task_set_cookie(dmt, &conf->cookie, 0))
+ goto freeout;
r = dm_task_run (dmt);
freeout:
@@ -249,7 +256,7 @@ _dm_addmap_create (struct multipath *mpp
if (!r && dm_map_present(mpp->alias)) {
condlog(3, "%s: failed to load map (a path might be in use)",
mpp->alias);
- dm_flush_map(mpp->alias);
+ dm_flush_map_nosync(mpp->alias);
}
return r;
}
@@ -529,7 +536,7 @@ out:
}
extern int
-dm_flush_map (const char * mapname)
+_dm_flush_map (const char * mapname, int need_sync)
{
int r;
@@ -539,7 +546,7 @@ dm_flush_map (const char * mapname)
if (dm_type(mapname, TGT_MPATH) <= 0)
return 0; /* nothing to do */
- if (dm_remove_partmaps(mapname))
+ if (dm_remove_partmaps(mapname, need_sync))
return 1;
if (dm_get_opencount(mapname)) {
@@ -547,7 +554,7 @@ dm_flush_map (const char * mapname)
return 1;
}
- r = dm_simplecmd_flush(DM_DEVICE_REMOVE, mapname);
+ r = dm_simplecmd_flush(DM_DEVICE_REMOVE, mapname, need_sync);
if (r) {
condlog(4, "multipath map %s removed", mapname);
@@ -883,7 +890,7 @@ bad:
}
int
-dm_remove_partmaps (const char * mapname)
+dm_remove_partmaps (const char * mapname, int need_sync)
{
struct dm_task *dmt;
struct dm_names *names;
@@ -946,7 +953,7 @@ dm_remove_partmaps (const char * mapname
*/
condlog(4, "partition map %s removed",
names->name);
- dm_simplecmd_flush(DM_DEVICE_REMOVE, names->name);
+ dm_simplecmd_flush(DM_DEVICE_REMOVE, names->name, need_sync);
}
next = names->next;
@@ -1102,6 +1109,8 @@ dm_rename (char * old, char * new)
dm_task_no_open_count(dmt);
+ if (!dm_task_set_cookie(dmt, &conf->cookie, 0))
+ goto out;
if (!dm_task_run(dmt))
goto out;
Index: multipath-tools/libmultipath/devmapper.h
===================================================================
--- multipath-tools.orig/libmultipath/devmapper.h
+++ multipath-tools/libmultipath/devmapper.h
@@ -8,7 +8,7 @@
void dm_init(void);
int dm_prereq (void);
-int dm_simplecmd_flush (int, const char *);
+int dm_simplecmd_flush (int, const char *, int);
int dm_simplecmd_noflush (int, const char *);
int dm_addmap_create (struct multipath *mpp);
int dm_addmap_create_ro (struct multipath *mpp);
@@ -18,7 +18,9 @@ int dm_map_present (const char *);
int dm_get_map(char *, unsigned long long *, char *);
int dm_get_status(char *, char *);
int dm_type(const char *, char *);
-int dm_flush_map (const char *);
+int _dm_flush_map (const char *, int);
+#define dm_flush_map(mapname) _dm_flush_map(mapname, 1)
+#define dm_flush_map_nosync(mapname) _dm_flush_map(mapname, 0)
int dm_flush_maps (void);
int dm_fail_path(char * mapname, char * path);
int dm_reinstate_path(char * mapname, char * path);
@@ -31,7 +33,7 @@ int dm_get_maps (vector mp);
int dm_geteventnr (char *name);
int dm_get_minor (char *name);
char * dm_mapname(int major, int minor);
-int dm_remove_partmaps (const char * mapname);
+int dm_remove_partmaps (const char * mapname, int need_sync);
int dm_get_uuid(char *name, char *uuid);
int dm_get_info (char * mapname, struct dm_info ** dmi);
int dm_rename (char * old, char * new);
Index: multipath-tools/multipath/main.c
===================================================================
--- multipath-tools.orig/multipath/main.c
+++ multipath-tools/multipath/main.c
@@ -454,6 +454,7 @@ main (int argc, char *argv[])
condlog(3, "restart multipath configuration process");
out:
+ dm_udev_wait(conf->cookie);
sysfs_cleanup();
dm_lib_release();
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -1396,6 +1396,7 @@ child (void * param)
exit(1);
}
conf->daemon = 1;
+ dm_udev_set_sync_support(0);
/*
* fetch and configure both paths and multipaths
*/
Index: multipath-tools/libmultipath/configure.c
===================================================================
--- multipath-tools.orig/libmultipath/configure.c
+++ multipath-tools/libmultipath/configure.c
@@ -373,7 +373,7 @@ domap (struct multipath * mpp)
if (!r)
r = dm_addmap_reload_ro(mpp);
if (r)
- r = dm_simplecmd_flush(DM_DEVICE_RESUME, mpp->alias);
+ r = dm_simplecmd_flush(DM_DEVICE_RESUME, mpp->alias, 1);
break;
case ACT_RENAME:

View File

@ -1,546 +0,0 @@
---
libmultipath/config.c | 10 ++
libmultipath/config.h | 4 +
libmultipath/dict.c | 92 ++++++++++++++++++++---
libmultipath/discovery.c | 56 +++++++-------
libmultipath/prio.h | 1
libmultipath/prioritizers/Makefile | 3
libmultipath/prioritizers/weighted.c | 139 +++++++++++++++++++++++++++++++++++
libmultipath/prioritizers/weighted.h | 8 ++
libmultipath/propsel.c | 11 ++
libmultipath/structs.h | 1
10 files changed, 286 insertions(+), 39 deletions(-)
Index: multipath-tools/libmultipath/config.c
===================================================================
--- multipath-tools.orig/libmultipath/config.c
+++ multipath-tools/libmultipath/config.c
@@ -156,6 +156,9 @@ free_hwe (struct hwentry * hwe)
if (hwe->prio_name)
FREE(hwe->prio_name);
+ if (hwe->prio_args)
+ FREE(hwe->prio_args);
+
if (hwe->bl_product)
FREE(hwe->bl_product);
@@ -195,6 +198,12 @@ free_mpe (struct mpentry * mpe)
if (mpe->alias)
FREE(mpe->alias);
+ if (mpe->prio_name)
+ FREE(mpe->prio_name);
+
+ if (mpe->prio_args)
+ FREE(mpe->prio_args);
+
FREE(mpe);
}
@@ -279,6 +288,7 @@ merge_hwe (struct hwentry * hwe1, struct
merge_str(selector);
merge_str(checker_name);
merge_str(prio_name);
+ merge_str(prio_args);
merge_str(bl_product);
merge_num(pgpolicy);
merge_num(pgfailback);
Index: multipath-tools/libmultipath/config.h
===================================================================
--- multipath-tools.orig/libmultipath/config.h
+++ multipath-tools/libmultipath/config.h
@@ -25,6 +25,7 @@ struct hwentry {
char * selector;
char * checker_name;
char * prio_name;
+ char * prio_args;
int pgpolicy;
int pgfailback;
@@ -43,6 +44,8 @@ struct mpentry {
char * alias;
char * getuid;
char * selector;
+ char * prio_name;
+ char * prio_args;
int pgpolicy;
int pgfailback;
@@ -97,6 +100,7 @@ struct config {
char * hwhandler;
char * bindings_file;
char * prio_name;
+ char * prio_args;
char * checker_name;
vector keywords;
Index: multipath-tools/libmultipath/dict.c
===================================================================
--- multipath-tools.orig/libmultipath/dict.c
+++ multipath-tools/libmultipath/dict.c
@@ -139,11 +139,23 @@ def_getuid_callout_handler(vector strvec
static int
def_prio_handler(vector strvec)
{
- conf->prio_name = set_value(strvec);
+ char *name, *args;
- if (!conf->prio_name)
+ name = set_value(strvec);
+ if (!name)
return 1;
+ args = strpbrk(name, " \t");
+ if (args) {
+ *args = 0;
+ while(*++args && isblank(*args)); /* Do nothing */
+ }
+
+ conf->prio_name = STRDUP(name);
+ if (args && *args)
+ conf->prio_args = STRDUP(args);
+
+ FREE(name);
return 0;
}
@@ -806,16 +818,27 @@ hw_handler_handler(vector strvec)
static int
hw_prio_handler(vector strvec)
{
+ char *name, *args;
struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
if (!hwe)
return 1;
- hwe->prio_name = set_value(strvec);
-
- if (!hwe->prio_name)
+ name = set_value(strvec);
+ if (!name)
return 1;
+ args = strpbrk(name, " \t");
+ if (args) {
+ *args = 0;
+ while(*++args && isblank(*args)); /* Do nothing */
+ }
+
+ hwe->prio_name = STRDUP(name);
+ if (args && *args)
+ hwe->prio_args = STRDUP(args);
+
+ FREE(name);
return 0;
}
@@ -1293,6 +1316,33 @@ mp_flush_on_last_del_handler(vector strv
return 0;
}
+static int
+mp_prio_handler(vector strvec)
+{
+ char *name, *args;
+ struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
+
+ if (!mpe)
+ return 1;
+
+ name = set_value(strvec);
+ if (!name)
+ return 1;
+
+ args = strpbrk(name, " \t");
+ if (args) {
+ *args = 0;
+ while(*++args && isblank(*args)); /* Do nothing */
+ }
+
+ mpe->prio_name = STRDUP(name);
+ if (args && *args)
+ mpe->prio_args = STRDUP(args);
+
+ FREE(name);
+ return 0;
+}
+
/*
* config file keywords printing
*/
@@ -1472,6 +1522,20 @@ snprint_mp_flush_on_last_del (char * buf
}
static int
+snprint_mp_prio (char * buff, int len, void * data)
+{
+ struct mpentry * mpe = (struct mpentry *)data;
+
+ if (!mpe->prio_name)
+ return 0;
+ if (!strcmp(mpe->prio_name, conf->prio_name) && !mpe->prio_args)
+ return 0;
+ if (!mpe->prio_args)
+ return snprintf(buff, len, "%s", mpe->prio_name);
+ return snprintf(buff, len, "%s %s", mpe->prio_name, mpe->prio_args);
+}
+
+static int
snprint_hw_fast_io_fail(char * buff, int len, void * data)
{
struct hwentry * hwe = (struct hwentry *)data;
@@ -1545,10 +1609,11 @@ snprint_hw_prio (char * buff, int len, v
if (!hwe->prio_name)
return 0;
- if (!strcmp(hwe->prio_name, conf->prio_name))
+ if (!strcmp(hwe->prio_name, conf->prio_name) && !hwe->prio_args)
return 0;
-
- return snprintf(buff, len, "%s", hwe->prio_name);
+ if (!hwe->prio_args)
+ return snprintf(buff, len, "%s", hwe->prio_name);
+ return snprintf(buff, len, "%s %s", hwe->prio_name, hwe->prio_args);
}
static int
@@ -1837,10 +1902,14 @@ snprint_def_prio (char * buff, int len,
return 0;
if (strlen(conf->prio_name) == strlen(DEFAULT_PRIO) &&
- !strcmp(conf->prio_name, DEFAULT_PRIO))
+ !strcmp(conf->prio_name, DEFAULT_PRIO) && !conf->prio_args)
return 0;
-
- return snprintf(buff, len, "%s", conf->prio_name);
+
+ if (!conf->prio_args)
+ return snprintf(buff, len, "%s", conf->prio_name);
+ else
+ return snprintf(buff, len, "%s %s", conf->prio_name,
+ conf->prio_args);
}
static int
@@ -2146,5 +2215,6 @@ init_keywords(void)
install_keyword("mode", &mp_mode_handler, &snprint_mp_mode);
install_keyword("uid", &mp_uid_handler, &snprint_mp_uid);
install_keyword("gid", &mp_gid_handler, &snprint_mp_gid);
+ install_keyword("prio", &mp_prio_handler, &snprint_mp_prio);
install_sublevel_end();
}
Index: multipath-tools/libmultipath/discovery.c
===================================================================
--- multipath-tools.orig/libmultipath/discovery.c
+++ multipath-tools/libmultipath/discovery.c
@@ -800,30 +800,6 @@ get_state (struct path * pp, int daemon)
}
static int
-get_prio (struct path * pp)
-{
- if (!pp)
- return 0;
-
- if (!pp->prio) {
- select_prio(pp);
- if (!pp->prio) {
- condlog(3, "%s: no prio selected", pp->dev);
- return 1;
- }
- }
- pp->priority = prio_getprio(pp->prio, pp);
- if (pp->priority < 0) {
- condlog(3, "%s: %s prio error", pp->dev, prio_name(pp->prio));
- pp->priority = PRIO_UNDEF;
- return 1;
- }
- condlog(3, "%s: %s prio = %u",
- pp->dev, prio_name(pp->prio), pp->priority);
- return 0;
-}
-
-static int
get_uid (struct path * pp)
{
char buff[CALLOUT_MAX_SIZE];
@@ -850,6 +826,32 @@ get_uid (struct path * pp)
return 0;
}
+static int
+get_prio (struct path * pp)
+{
+ if (!pp)
+ return 0;
+
+ if (!pp->prio) {
+ if (!strlen(pp->wwid))
+ get_uid(pp);
+ select_prio(pp);
+ if (!pp->prio) {
+ condlog(3, "%s: no prio selected", pp->dev);
+ return 1;
+ }
+ }
+ pp->priority = prio_getprio(pp->prio, pp);
+ if (pp->priority < 0) {
+ condlog(3, "%s: %s prio error", pp->dev, prio_name(pp->prio));
+ pp->priority = PRIO_UNDEF;
+ return 1;
+ }
+ condlog(3, "%s: %s prio = %u",
+ pp->dev, prio_name(pp->prio), pp->priority);
+ return 0;
+}
+
extern int
pathinfo (struct path *pp, vector hwtable, int mask)
{
@@ -887,6 +889,9 @@ pathinfo (struct path *pp, vector hwtabl
goto blank;
}
+ if (mask & DI_WWID && !strlen(pp->wwid))
+ get_uid(pp);
+
/*
* Retrieve path priority, even for PATH_DOWN paths if it has never
* been successfully obtained before.
@@ -895,9 +900,6 @@ pathinfo (struct path *pp, vector hwtabl
(pp->state != PATH_DOWN || pp->priority == PRIO_UNDEF))
get_prio(pp);
- if (mask & DI_WWID && !strlen(pp->wwid))
- get_uid(pp);
-
return 0;
blank:
Index: multipath-tools/libmultipath/prio.h
===================================================================
--- multipath-tools.orig/libmultipath/prio.h
+++ multipath-tools/libmultipath/prio.h
@@ -24,6 +24,7 @@
#define PRIO_NETAPP "netapp"
#define PRIO_RANDOM "random"
#define PRIO_RDAC "rdac"
+#define PRIO_WEIGHTED "weighted"
/*
* Value used to mark the fact prio was not defined
Index: multipath-tools/libmultipath/prioritizers/Makefile
===================================================================
--- multipath-tools.orig/libmultipath/prioritizers/Makefile
+++ multipath-tools/libmultipath/prioritizers/Makefile
@@ -13,7 +13,8 @@ LIBS = \
libprioalua.so \
libpriotpg_pref.so \
libprionetapp.so \
- libpriohds.so
+ libpriohds.so \
+ libprioweighted.so \
CFLAGS += -I..
Index: multipath-tools/libmultipath/prioritizers/weighted.c
===================================================================
--- /dev/null
+++ multipath-tools/libmultipath/prioritizers/weighted.c
@@ -0,0 +1,139 @@
+/******************************************************************************
+*******************************************************************************
+**
+** Copyright (C) 2009 Red Hat, Inc. All rights reserved.
+**
+** This copyrighted material is made available to anyone wishing to use,
+** modify, copy, or redistribute it subject to the terms and conditions
+** of the GNU General Public License v.2.
+**
+*******************************************************************************
+******************************************************************************/
+
+/* This prioritizer is based on a path's device name or its H:T:B:L. Both of
+ * these can change when the node is rebooted, and can differ from node to
+ * node. (i.e. there is no guarantee that sda will point to the same device
+ * after a reboot) If you use this prioritizer, it may be necessary to
+ * manually edit /etc/multipath.conf after any reboot
+ *
+ * Format:
+ * prio "weighted hbtl <regex> <prio> [<regex> <prio>]
+ * prio "weighted devname <regex> <prio> [<regex> <prio>]
+ *
+ * Examples:
+ * prio "weighted hbtl 4:* 2 3:.:.:. 1"
+ * prio "weighted devname sda 2 sde 1"
+ *
+ */
+
+#include <string.h>
+#include <prio.h>
+#include <debug.h>
+#include <regex.h>
+
+#include "weighted.h"
+
+#define DEFAULT_WEIGHTED_PRIO 0
+
+#define pp_weighted_log(prio, fmt, args...) \
+ condlog(prio, "%s: weighted prio: " fmt, dev, ##args)
+
+static char *
+next_str(char **str)
+{
+ char *next;
+
+ do {
+ next = strsep(str, " \t");
+ } while (next && strcmp(next, "") == 0);
+ return next;
+}
+
+
+static int
+match (char *dev, char *target, char *regex_str, char *prio_str,
+ unsigned int *prio)
+{
+
+ regex_t regex;
+ int err, ret = 0;
+ char *errbuf;
+ size_t errbuf_size;
+ unsigned int prio_match;
+
+ if (sscanf(prio_str, "%u", &prio_match) != 1) {
+ condlog(0, "%s: weighted prio: invalid prio '%s'", dev,
+ prio_str);
+ return 0;
+ }
+ err = regcomp(&regex, regex_str, REG_EXTENDED|REG_NOSUB);
+ if (err) {
+ errbuf_size = regerror(err, &regex, NULL, 0);
+ errbuf = malloc(errbuf_size);
+ regerror(err, &regex, errbuf, errbuf_size);
+ condlog(0, "%s: weighted prio: cannot compile regex '%s' : %s",
+ dev, regex_str, errbuf);
+ free(errbuf);
+ return 0;
+ }
+ if (regexec(&regex, target, 0, NULL, 0) == 0) {
+ *prio = prio_match;
+ ret = 1;
+ }
+
+ regfree(&regex);
+ return ret;
+}
+
+int
+prio_weighted(struct path * pp)
+{
+ char target[FILE_NAME_SIZE];
+ char *buff, *args, *ptr, *prio_str;
+ unsigned int prio = DEFAULT_WEIGHTED_PRIO;
+ char *regex_str = NULL;
+ int regex_size = 0;
+
+ if (!pp->prio_args)
+ return DEFAULT_WEIGHTED_PRIO;
+ buff = args = strdup(pp->prio_args);
+ ptr = next_str(&args);
+
+ if (strcasecmp(ptr, "hbtl") == 0)
+ sprintf(target, "%d:%d:%d:%d", pp->sg_id.host_no,
+ pp->sg_id.channel, pp->sg_id.scsi_id, pp->sg_id.lun);
+ else if (strcasecmp(ptr, "devname") == 0)
+ strcpy(target, pp->dev);
+ else {
+ condlog(0, "%s: weighted prio: invalid argument. Want 'hbtl' or 'devname'. Got '%s'", pp->dev, ptr);
+ goto out;
+ }
+
+ while ((ptr = next_str(&args)) != NULL) {
+
+ prio_str = next_str(&args);
+ if (!prio_str) {
+ condlog(0, "%s weighted prio: missing prio for regex '%s'", pp->dev, ptr);
+ goto out;
+ }
+ if (!regex_str || regex_size < strlen(ptr) + 3){
+ regex_size = strlen(ptr) + 3;
+ regex_str = realloc(regex_str, regex_size);
+ }
+ sprintf(regex_str, "%s%s%s", (ptr[0] == '^')? "" : "^",
+ ptr, (ptr[strlen(ptr)-1] == '$')? "" : "$");
+ if (match(pp->dev, target, regex_str, prio_str, &prio))
+ break;
+ }
+out:
+ free(buff);
+ if (regex_str)
+ free(regex_str);
+ return prio;
+}
+
+int
+getprio(struct path * pp)
+{
+ return prio_weighted(pp);
+}
Index: multipath-tools/libmultipath/propsel.c
===================================================================
--- multipath-tools.orig/libmultipath/propsel.c
+++ multipath-tools/libmultipath/propsel.c
@@ -312,14 +312,25 @@ select_getuid (struct path * pp)
extern int
select_prio (struct path * pp)
{
+ struct mpentry * mpe;
+
+ if ((mpe = find_mpe(pp->wwid)) && mpe->prio_name) {
+ pp->prio = prio_lookup(mpe->prio_name);
+ pp->prio_args = mpe->prio_args;
+ condlog(3, "%s: prio = %s (LUN setting)",
+ pp->dev, mpe->prio_name);
+ return 0;
+ }
if (pp->hwe && pp->hwe->prio_name) {
pp->prio = prio_lookup(pp->hwe->prio_name);
+ pp->prio_args = pp->hwe->prio_args;
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_args = conf->prio_args;
condlog(3, "%s: prio = %s (config file default)",
pp->dev, conf->prio_name);
return 0;
Index: multipath-tools/libmultipath/structs.h
===================================================================
--- multipath-tools.orig/libmultipath/structs.h
+++ multipath-tools/libmultipath/structs.h
@@ -142,6 +142,7 @@ struct path {
int priority;
int pgindex;
char * getuid;
+ char * prio_args;
struct prio * prio;
struct checker checker;
struct multipath * mpp;
Index: multipath-tools/libmultipath/prioritizers/weighted.h
===================================================================
--- /dev/null
+++ multipath-tools/libmultipath/prioritizers/weighted.h
@@ -0,0 +1,8 @@
+#ifndef _WEIGHTED_H
+#define _WEIGHTED_H
+
+#define PRIO_WEIGHTED "weighted"
+
+int prio_weighted(struct path *pp);
+
+#endif

View File

@ -1,150 +0,0 @@
Index: multipath-tools/libmultipath/uevent.c
===================================================================
--- multipath-tools.orig/libmultipath/uevent.c
+++ multipath-tools/libmultipath/uevent.c
@@ -52,6 +52,12 @@ pthread_mutex_t uevc_lock, *uevc_lockp =
pthread_cond_t uev_cond, *uev_condp = &uev_cond;
uev_trigger *my_uev_trigger;
void * my_trigger_data;
+int servicing_uev;
+
+int is_uevent_busy(void)
+{
+ return (uevqhp != NULL || servicing_uev);
+}
static struct uevent * alloc_uevent (void)
{
@@ -96,7 +102,9 @@ uevq_thread(void * et)
while (1) {
pthread_mutex_lock(uevc_lockp);
+ servicing_uev = 0;
pthread_cond_wait(uev_condp, uevc_lockp);
+ servicing_uev = 1;
pthread_mutex_unlock(uevc_lockp);
service_uevq();
Index: multipath-tools/libmultipath/uevent.h
===================================================================
--- multipath-tools.orig/libmultipath/uevent.h
+++ multipath-tools/libmultipath/uevent.h
@@ -17,3 +17,4 @@ struct uevent {
int uevent_listen(int (*store_uev)(struct uevent *, void * trigger_data),
void * trigger_data);
+int is_uevent_busy(void);
Index: multipath-tools/multipathd/cli.c
===================================================================
--- multipath-tools.orig/multipathd/cli.c
+++ multipath-tools/multipathd/cli.c
@@ -174,6 +174,7 @@ load_keys (void)
r += add_key(keys, "devices", DEVICES, 0);
r += add_key(keys, "format", FMT, 1);
r += add_key(keys, "wildcards", WILDCARDS, 0);
+ r += add_key(keys, "count", COUNT, 0);
r += add_key(keys, "quit", QUIT, 0);
r += add_key(keys, "exit", QUIT, 0);
@@ -443,6 +444,7 @@ cli_init (void) {
add_handler(RESTOREQ+MAPS, NULL);
add_handler(REINSTATE+PATH, NULL);
add_handler(FAIL+PATH, NULL);
+ add_handler(COUNT+PATHS, NULL);
add_handler(QUIT, NULL);
return 0;
Index: multipath-tools/multipathd/cli_handlers.h
===================================================================
--- multipath-tools.orig/multipathd/cli_handlers.h
+++ multipath-tools/multipathd/cli_handlers.h
@@ -25,5 +25,6 @@ int cli_restore_all_queueing(void * v, c
int cli_suspend(void * v, char ** reply, int * len, void * data);
int cli_resume(void * v, char ** reply, int * len, void * data);
int cli_reinstate(void * v, char ** reply, int * len, void * data);
+int cli_count_paths(void * v, char ** reply, int * len, void * data);
int cli_fail(void * v, char ** reply, int * len, void * data);
int cli_quit(void * v, char ** reply, int * len, void * data);
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -768,6 +768,7 @@ uxlsnrloop (void * ap)
set_handler_callback(RESTOREQ+MAP, cli_restore_queueing);
set_handler_callback(DISABLEQ+MAPS, cli_disable_all_queueing);
set_handler_callback(RESTOREQ+MAPS, cli_restore_all_queueing);
+ set_handler_callback(COUNT+PATHS, cli_count_paths);
set_handler_callback(QUIT, cli_quit);
umask(077);
Index: multipath-tools/multipathd/cli.h
===================================================================
--- multipath-tools.orig/multipathd/cli.h
+++ multipath-tools/multipathd/cli.h
@@ -23,6 +23,7 @@ enum {
__BLACKLIST,
__DEVICES,
__FMT,
+ __COUNT,
__WILDCARDS,
__QUIT,
};
@@ -51,6 +52,7 @@ enum {
#define BLACKLIST (1 << __BLACKLIST)
#define DEVICES (1 << __DEVICES)
#define FMT (1 << __FMT)
+#define COUNT (1 << __COUNT)
#define WILDCARDS (1 << __WILDCARDS)
#define QUIT (1 << __QUIT)
Index: multipath-tools/multipathd/cli_handlers.c
===================================================================
--- multipath-tools.orig/multipathd/cli_handlers.c
+++ multipath-tools/multipathd/cli_handlers.c
@@ -18,6 +18,29 @@
#include "main.h"
#include "cli.h"
+#include "uevent.h"
+
+int
+count_paths(char **r, int *l, struct vectors *vecs)
+{
+ int i, len;
+ struct path *pp;
+ char * reply;
+ unsigned int maxlen = INITIAL_REPLY_LEN;
+ int monitored_count = 0;
+
+ reply = MALLOC(maxlen);
+ if (!reply)
+ return 1;
+ vector_foreach_slot(vecs->pathvec, pp, i)
+ if (pp->fd != -1)
+ monitored_count++;
+ len = sprintf(reply, "Paths: %d\nBusy: %s\n", monitored_count,
+ is_uevent_busy()? "True" : "False");
+ *r = reply;
+ *l = len + 1;
+ return 0;
+}
int
show_paths (char ** r, int * len, struct vectors * vecs, char * style)
@@ -176,6 +199,16 @@ cli_list_config (void * v, char ** reply
}
int
+cli_count_paths (void * v, char ** reply, int * len, void * data)
+{
+ struct vectors * vecs = (struct vectors *)data;
+
+ condlog(3, "count paths (operator)");
+
+ return count_paths(reply, len, vecs);
+}
+
+int
cli_list_paths (void * v, char ** reply, int * len, void * data)
{
struct vectors * vecs = (struct vectors *)data;

View File

@ -1,23 +0,0 @@
---
multipathd/multipathd.init.redhat | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
Index: multipath-tools/multipathd/multipathd.init.redhat
===================================================================
--- multipath-tools.orig/multipathd/multipathd.init.redhat
+++ multipath-tools/multipathd/multipathd.init.redhat
@@ -75,9 +75,11 @@ start() {
stop() {
root_dev=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $1; }}' /etc/mtab)
- dm_num=`dmsetup info -c --noheadings -o minor $root_dev`
- root_dm_device="dm-$dm_num"
- [ -d $syspath/$root_dm_device ] && teardown_slaves $syspath/$root_dm_device
+ dm_num=`dmsetup info -c --noheadings -o minor $root_dev 2> /dev/null`
+ if [ $? -eq 0 ]; then
+ root_dm_device="dm-$dm_num"
+ [ -d $syspath/$root_dm_device ] && teardown_slaves $syspath/$root_dm_device
+ fi
echo -n $"Stopping $prog daemon: "
killproc $DAEMON

View File

@ -1,17 +0,0 @@
---
multipath/multipath.8 | 2 ++
1 file changed, 2 insertions(+)
Index: multipath-tools/multipath/multipath.8
===================================================================
--- multipath-tools.orig/multipath/multipath.8
+++ multipath-tools/multipath/multipath.8
@@ -75,6 +75,8 @@ is in.
is in the /dev/sdb (as shown by udev in the $DEVNAME variable) or major:minor format.
.I device
may alternatively be a multipath mapname
+.SH NOTES
+a map may be unused if, eg, the file system on it is not mounted or there are no open file descriptors against the device file, as in a raw device.
.SH "SEE ALSO"
.BR udev (8),
.BR dmsetup (8)

View File

@ -1,57 +0,0 @@
---
libmultipath/hwtable.c | 16 ++++++++++++++++
multipath.conf.defaults | 16 ++++++++++++++++
2 files changed, 32 insertions(+)
Index: multipath-tools/libmultipath/hwtable.c
===================================================================
--- multipath-tools.orig/libmultipath/hwtable.c
+++ multipath-tools/libmultipath/hwtable.c
@@ -959,6 +959,22 @@ static struct hwentry default_hw[] = {
.checker_name = RDAC,
.prio_name = PRIO_RDAC,
},
+ {
+ .vendor = "STK",
+ .product = "FLEXLINE 380",
+ .bl_product = "Universal Xport",
+ .getuid = DEFAULT_GETUID,
+ .features = DEFAULT_FEATURES,
+ .hwhandler = "1 rdac",
+ .selector = DEFAULT_SELECTOR,
+ .pgpolicy = GROUP_BY_PRIO,
+ .pgfailback = -FAILBACK_IMMEDIATE,
+ .rr_weight = RR_WEIGHT_NONE,
+ .no_path_retry = NO_PATH_RETRY_QUEUE,
+ .minio = DEFAULT_MINIO,
+ .checker_name = RDAC,
+ .prio_name = PRIO_RDAC,
+ },
/*
* EOL
*/
Index: multipath-tools/multipath.conf.defaults
===================================================================
--- multipath-tools.orig/multipath.conf.defaults
+++ multipath-tools/multipath.conf.defaults
@@ -571,4 +571,20 @@
# path_checker rdac
# prio rdac
# }
+# device {
+# vendor "STK"
+# product "FLEXLINE 380"
+# product_blacklist "Universal Xport"
+# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
+# features "0"
+# hardware_handler "1 rdac"
+# path_selector "round-robin 0"
+# path_grouping_policy group_by_prio
+# failback immediate
+# rr_weight uniform
+# no_path_retry queue
+# rr_min_io 1000
+# path_checker rdac
+# prio rdac
+# }
#}

View File

@ -1,43 +0,0 @@
---
libmultipath/configure.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
Index: multipath-tools/libmultipath/configure.c
===================================================================
--- multipath-tools.orig/libmultipath/configure.c
+++ multipath-tools/libmultipath/configure.c
@@ -284,6 +284,7 @@ lock_multipath (struct multipath * mpp,
struct pathgroup * pgp;
struct path * pp;
int i, j;
+ int x, y;
if (!mpp || !mpp->pg)
return 0;
@@ -294,12 +295,25 @@ lock_multipath (struct multipath * mpp,
vector_foreach_slot(pgp->paths, pp, j) {
if (lock && flock(pp->fd, LOCK_EX | LOCK_NB) &&
errno == EWOULDBLOCK)
- return 1;
+ goto fail;
else if (!lock)
flock(pp->fd, LOCK_UN);
}
}
return 0;
+fail:
+ vector_foreach_slot (mpp->pg, pgp, x) {
+ if (x > i)
+ return 1;
+ if (!pgp->paths)
+ continue;
+ vector_foreach_slot(pgp->paths, pp, y) {
+ if (x == i && y > j)
+ return 1;
+ flock(pp->fd, LOCK_UN);
+ }
+ }
+ return 1;
}
/*

View File

@ -1,52 +0,0 @@
---
libmultipath/pgpolicies.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
Index: multipath-tools/libmultipath/pgpolicies.c
===================================================================
--- multipath-tools.orig/libmultipath/pgpolicies.c
+++ multipath-tools/libmultipath/pgpolicies.c
@@ -205,7 +205,8 @@ out:
extern int
one_path_per_group (struct multipath * mp)
{
- int i;
+ int i, j;
+ unsigned int prio;
struct path * pp;
struct pathgroup * pgp;
@@ -217,16 +218,30 @@ one_path_per_group (struct multipath * m
for (i = 0; i < VECTOR_SIZE(mp->paths); i++) {
pp = VECTOR_SLOT(mp->paths, i);
+ prio = pp->priority;
+
+ vector_foreach_slot(mp->pg, pgp, j) {
+ pp = VECTOR_SLOT(pgp->paths, 0);
+
+ if (prio > pp->priority)
+ break;
+ }
+
pgp = alloc_pathgroup();
if (!pgp)
goto out;
- if (store_pathgroup(mp->pg, pgp))
+ if (store_path(pgp->paths, VECTOR_SLOT(mp->paths, i)))
goto out;
- if (store_path(pgp->paths, pp))
- goto out;
+ if (j < VECTOR_SIZE(mp->pg)) {
+ if (!vector_insert_slot(mp->pg, j, pgp))
+ goto out;
+ } else {
+ if (store_pathgroup(mp->pg, pgp))
+ goto out;
+ }
}
free_pathvec(mp->paths, KEEP_PATHS);
mp->paths = NULL;

View File

@ -1,327 +0,0 @@
---
kpartx/bsd.c | 35 ----------------
kpartx/dos.c | 7 +--
kpartx/kpartx.c | 121 +++++++-------------------------------------------------
kpartx/kpartx.h | 1
kpartx/sun.c | 35 ----------------
5 files changed, 24 insertions(+), 175 deletions(-)
Index: multipath-tools/kpartx/bsd.c
===================================================================
--- multipath-tools.orig/kpartx/bsd.c
+++ multipath-tools/kpartx/bsd.c
@@ -50,10 +50,10 @@ int
read_bsd_pt(int fd, struct slice all, struct slice *sp, int ns) {
struct bsd_disklabel *l;
struct bsd_partition *p;
- unsigned int offset = all.start, end;
+ unsigned int offset = all.start;
int max_partitions;
char *bp;
- int n = 0, i, j;
+ int n = 0;
bp = getblock(fd, offset+1); /* 1 sector suffices */
if (bp == NULL)
@@ -79,36 +79,5 @@ read_bsd_pt(int fd, struct slice all, st
break;
}
}
- /*
- * Convention has it that the bsd disklabel will always have
- * the 'c' partition spanning the entire disk.
- * So we have to check for contained slices.
- */
- for(i = 0; i < n; i++) {
- if (sp[i].size == 0)
- continue;
-
- end = sp[i].start + sp[i].size;
- for(j = 0; j < n; j ++) {
- if ( i == j )
- continue;
- if (sp[j].size == 0)
- continue;
-
- if (sp[i].start < sp[j].start) {
- if (end > sp[j].start &&
- end < sp[j].start + sp[j].size) {
- /* Invalid slice */
- fprintf(stderr,
- "bsd_disklabel: slice %d overlaps with %d\n", i , j);
- sp[i].size = 0;
- }
- } else {
- if (end <= sp[j].start + sp[j].size) {
- sp[i].container = j + 1;
- }
- }
- }
- }
return n;
}
Index: multipath-tools/kpartx/dos.c
===================================================================
--- multipath-tools.orig/kpartx/dos.c
+++ multipath-tools/kpartx/dos.c
@@ -16,7 +16,7 @@ is_extended(int type) {
}
static int
-read_extended_partition(int fd, struct partition *ep, int en,
+read_extended_partition(int fd, struct partition *ep,
struct slice *sp, int ns)
{
struct partition p;
@@ -53,7 +53,6 @@ read_extended_partition(int fd, struct p
if (n < ns) {
sp[n].start = here + le32_to_cpu(p.start_sect);
sp[n].size = le32_to_cpu(p.nr_sects);
- sp[n].container = en + 1;
n++;
} else {
fprintf(stderr,
@@ -98,7 +97,9 @@ read_dos_pt(int fd, struct slice all, st
break;
}
if (is_extended(p.sys_type)) {
- n += read_extended_partition(fd, &p, i, sp+n, ns-n);
+ n += read_extended_partition(fd, &p, sp+n, ns-n);
+ /* hide the extended partition itself */
+ sp[i].size = 2;
}
}
return n;
Index: multipath-tools/kpartx/kpartx.c
===================================================================
--- multipath-tools.orig/kpartx/kpartx.c
+++ multipath-tools/kpartx/kpartx.c
@@ -185,7 +185,7 @@ get_hotplug_device(void)
int
main(int argc, char **argv){
- int fd, i, j, m, n, op, off, arg, c, d;
+ int fd, i, j, k, n, op, off, arg;
struct slice all;
struct pt *ptp;
enum action what = LIST;
@@ -355,49 +355,30 @@ main(int argc, char **argv){
else
continue;
+ /*
+ * test for overlap, as in the case of an extended partition
+ * zero their size to avoid mapping
+ */
+ for (j = 0; j < n; j++) {
+ for (k = j + 1; k < n; k++) {
+ if (slices[k].start > slices[j].start &&
+ slices[k].start < slices[j].start +
+ slices[j].size)
+ slices[j].size = 0;
+ }
+ }
+
switch(what) {
case LIST:
- for (j = 0, c = 0, m = 0; j < n; j++) {
+ for (j = 0; j < n; j++) {
if (slices[j].size == 0)
continue;
- if (slices[j].container > 0) {
- c++;
- continue;
- }
-
- slices[j].minor = m++;
printf("%s%s%d : 0 %" PRIu64 " %s %" PRIu64"\n",
mapname, delim, j+1,
slices[j].size, device,
slices[j].start);
}
- /* Loop to resolve contained slices */
- d = c;
- while (c) {
- for (j = 0; j < n; j++) {
- uint64_t start;
- int k = slices[j].container - 1;
-
- if (slices[j].size == 0)
- continue;
- if (slices[j].minor > 0)
- continue;
- if (slices[j].container == 0)
- continue;
- slices[j].minor = m++;
-
- start = slices[j].start - slices[k].start;
- printf("%s%s%d : 0 %" PRIu64 " /dev/dm-%d %" PRIu64 "\n",
- mapname, delim, j+1,
- slices[j].size,
- slices[k].minor, start);
- c--;
- }
- /* Terminate loop if nothing more to resolve */
- if (d == c)
- break;
- }
if (loopcreated && S_ISREG (buf.st_mode)) {
if (del_loop(device)) {
@@ -443,16 +424,10 @@ main(int argc, char **argv){
break;
case ADD:
- for (j = 0, c = 0; j < n; j++) {
+ for (j = 0; j < n; j++) {
if (slices[j].size == 0)
continue;
- /* Skip all contained slices */
- if (slices[j].container > 0) {
- c++;
- continue;
- }
-
if (safe_sprintf(partname, "%s%s%d",
mapname, delim, j+1)) {
fprintf(stderr, "partname too small\n");
@@ -493,72 +468,6 @@ main(int argc, char **argv){
slices[j].minor, slices[j].size,
DM_TARGET, params);
}
- /* Loop to resolve contained slices */
- d = c;
- while (c) {
- for (j = 0; j < n; j++) {
- uint64_t start;
- int k = slices[j].container - 1;
-
- if (slices[j].size == 0)
- continue;
-
- /* Skip all existing slices */
- if (slices[j].minor > 0)
- continue;
-
- /* Skip all simple slices */
- if (slices[j].container == 0)
- continue;
-
- /* Check container slice */
- if (slices[k].size == 0)
- fprintf(stderr, "Invalid slice %d\n",
- k);
-
- if (safe_sprintf(partname, "%s%s%d",
- mapname, delim, j+1)) {
- fprintf(stderr, "partname too small\n");
- exit(1);
- }
- strip_slash(partname);
-
- start = slices[j].start - slices[k].start;
- if (safe_sprintf(params, "%d:%d %" PRIu64,
- slices[k].major,
- slices[k].minor,
- start)) {
- fprintf(stderr, "params too small\n");
- exit(1);
- }
-
- op = (dm_map_present(partname) ?
- DM_DEVICE_RELOAD : DM_DEVICE_CREATE);
-
- dm_addmap(op, partname, DM_TARGET, params,
- slices[j].size, uuid, j+1,
- buf.st_mode & 0777,
- buf.st_uid, buf.st_gid,
- &cookie);
-
- if (op == DM_DEVICE_RELOAD)
- dm_simplecmd(DM_DEVICE_RESUME,
- partname, 1,
- &cookie);
-
- dm_devn(partname, &slices[j].major,
- &slices[j].minor);
-
- if (verbose)
- printf("add map %s : 0 %" PRIu64 " %s %s\n",
- partname, slices[j].size,
- DM_TARGET, params);
- c--;
- }
- /* Terminate loop */
- if (d == c)
- break;
- }
break;
default:
Index: multipath-tools/kpartx/kpartx.h
===================================================================
--- multipath-tools.orig/kpartx/kpartx.h
+++ multipath-tools/kpartx/kpartx.h
@@ -24,7 +24,6 @@
struct slice {
uint64_t start;
uint64_t size;
- int container;
int major;
int minor;
};
Index: multipath-tools/kpartx/sun.c
===================================================================
--- multipath-tools.orig/kpartx/sun.c
+++ multipath-tools/kpartx/sun.c
@@ -62,8 +62,8 @@ int
read_sun_pt(int fd, struct slice all, struct slice *sp, int ns) {
struct sun_disk_label *l;
struct sun_raw_part *s;
- unsigned int offset = all.start, end;
- int i, j, n;
+ unsigned int offset = all.start;
+ int i, n;
char *bp;
bp = getblock(fd, offset);
@@ -95,37 +95,6 @@ read_sun_pt(int fd, struct slice all, st
break;
}
}
- /*
- * Convention has it that the SUN disklabel will always have
- * the 'c' partition spanning the entire disk.
- * So we have to check for contained slices.
- */
- for(i = 0; i < SUN_DISK_MAXPARTITIONS; i++) {
- if (sp[i].size == 0)
- continue;
-
- end = sp[i].start + sp[i].size;
- for(j = 0; j < SUN_DISK_MAXPARTITIONS; j ++) {
- if ( i == j )
- continue;
- if (sp[j].size == 0)
- continue;
-
- if (sp[i].start < sp[j].start) {
- if (end > sp[j].start &&
- end < sp[j].start + sp[j].size) {
- /* Invalid slice */
- fprintf(stderr,
- "sun_disklabel: slice %d overlaps with %d\n", i , j);
- sp[i].size = 0;
- }
- } else {
- if (end <= sp[j].start + sp[j].size) {
- sp[i].container = j + 1;
- }
- }
- }
- }
return n;
}

View File

@ -1,52 +0,0 @@
Index: multipath-tools/libmultipath/hwtable.c
===================================================================
--- multipath-tools.orig/libmultipath/hwtable.c
+++ multipath-tools/libmultipath/hwtable.c
@@ -282,6 +282,21 @@ static struct hwentry default_hw[] = {
.checker_name = EMC_CLARIION,
.prio_name = PRIO_EMC,
},
+ {
+ .vendor = "EMC",
+ .product = "Invista",
+ .bl_product = "LUNZ",
+ .getuid = DEFAULT_GETUID,
+ .features = DEFAULT_FEATURES,
+ .hwhandler = DEFAULT_HWHANDLER,
+ .selector = DEFAULT_SELECTOR,
+ .pgpolicy = MULTIBUS,
+ .pgfailback = FAILBACK_UNDEF,
+ .rr_weight = RR_WEIGHT_NONE,
+ .no_path_retry = 5,
+ .minio = DEFAULT_MINIO,
+ .prio_name = DEFAULT_PRIO,
+ },
/*
* Fujitsu controller family
*
Index: multipath-tools/multipath.conf.defaults
===================================================================
--- multipath-tools.orig/multipath.conf.defaults
+++ multipath-tools/multipath.conf.defaults
@@ -209,6 +209,21 @@
# prio emc
# }
# device {
+# vendor "EMC"
+# product "Invista"
+# product_blacklist "LUNZ"
+# getuid_callout "/lib/udev/scsi_id --whitelisted --page=pre-spc3-83 --device=/dev/%n"
+# features "0"
+# hardware_handler "0"
+# path_selector "round-robin 0"
+# path_grouping_policy multibus
+# rr_weight uniform
+# no_path_retry 5
+# rr_min_io 1000
+# path_checker tur
+# prio const
+# }
+# device {
# vendor "FSC"
# product "CentricStor"
# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"

View File

@ -1,428 +0,0 @@
---
libmultipath/checkers.h | 15 +--------------
libmultipath/checkers/emc_clariion.c | 4 ++--
libmultipath/checkers/hp_sw.c | 12 ++++++------
libmultipath/checkers/libsg.c | 5 +++--
libmultipath/checkers/libsg.h | 3 ++-
libmultipath/checkers/rdac.c | 9 +++++----
libmultipath/checkers/readsector0.c | 2 +-
libmultipath/checkers/tur.c | 4 ++--
libmultipath/config.h | 1 +
libmultipath/dict.c | 29 +++++++++++++++++++++++++++++
libmultipath/discovery.c | 27 +++++++++++++++++++++++++++
libmultipath/discovery.h | 1 +
libmultipath/propsel.c | 19 +++++++++++++++++--
multipath.conf.annotated | 9 +++++++++
14 files changed, 106 insertions(+), 34 deletions(-)
Index: multipath-tools/libmultipath/checkers.h
===================================================================
--- multipath-tools.orig/libmultipath/checkers.h
+++ multipath-tools/libmultipath/checkers.h
@@ -69,20 +69,6 @@ enum path_check_state {
#define DEFAULT_CHECKER DIRECTIO
-/*
- * Overloaded storage response time can be very long.
- * SG_IO timouts after DEF_TIMEOUT milliseconds, and checkers interprets this
- * as a path failure. multipathd then proactively evicts the path from the DM
- * multipath table in this case.
- *
- * This generaly snow balls and ends up in full eviction and IO errors for end
- * users. Bad. This may also cause SCSI bus resets, causing disruption for all
- * local and external storage hardware users.
- *
- * Provision a long timeout. Longer than any real-world application would cope
- * with.
- */
-#define DEF_TIMEOUT 300000
#define ASYNC_TIMEOUT_SEC 30
/*
@@ -98,6 +84,7 @@ struct checker {
struct list_head node;
int fd;
int sync;
+ unsigned int timeout;
int disable;
char name[CHECKER_NAME_LEN];
char message[CHECKER_MSG_LEN]; /* comm with callers */
Index: multipath-tools/libmultipath/checkers/emc_clariion.c
===================================================================
--- multipath-tools.orig/libmultipath/checkers/emc_clariion.c
+++ multipath-tools/libmultipath/checkers/emc_clariion.c
@@ -113,7 +113,7 @@ int libcheck_check (struct checker * c)
io_hdr.dxferp = sense_buffer;
io_hdr.cmdp = inqCmdBlk;
io_hdr.sbp = sb;
- io_hdr.timeout = DEF_TIMEOUT;
+ io_hdr.timeout = c->timeout;
io_hdr.pack_id = 0;
if (ioctl(c->fd, SG_IO, &io_hdr) < 0) {
MSG(c, "emc_clariion_checker: sending query command failed");
@@ -182,7 +182,7 @@ int libcheck_check (struct checker * c)
unsigned char buf[4096];
memset(buf, 0, 4096);
- ret = sg_read(c->fd, &buf[0], sbb = &sb[0]);
+ ret = sg_read(c->fd, &buf[0], sbb = &sb[0], c->timeout);
if (ret == PATH_DOWN) {
hexadecimal_to_ascii(ct->wwn, wwnstr);
Index: multipath-tools/libmultipath/checkers/hp_sw.c
===================================================================
--- multipath-tools.orig/libmultipath/checkers/hp_sw.c
+++ multipath-tools/libmultipath/checkers/hp_sw.c
@@ -46,7 +46,7 @@ void libcheck_free (struct checker * c)
static int
do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
- void *resp, int mx_resp_len, int noisy)
+ void *resp, int mx_resp_len, int noisy, unsigned int timeout)
{
unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
{ INQUIRY_CMD, 0, 0, 0, 0, 0 };
@@ -70,7 +70,7 @@ do_inq(int sg_fd, int cmddt, int evpd, u
io_hdr.dxferp = resp;
io_hdr.cmdp = inqCmdBlk;
io_hdr.sbp = sense_b;
- io_hdr.timeout = DEF_TIMEOUT;
+ io_hdr.timeout = timeout;
if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
return 1;
@@ -98,7 +98,7 @@ do_inq(int sg_fd, int cmddt, int evpd, u
}
static int
-do_tur (int fd)
+do_tur (int fd, unsigned int timeout)
{
unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 };
struct sg_io_hdr io_hdr;
@@ -111,7 +111,7 @@ do_tur (int fd)
io_hdr.dxfer_direction = SG_DXFER_NONE;
io_hdr.cmdp = turCmdBlk;
io_hdr.sbp = sense_buffer;
- io_hdr.timeout = DEF_TIMEOUT;
+ io_hdr.timeout = timeout;
io_hdr.pack_id = 0;
if (ioctl(fd, SG_IO, &io_hdr) < 0)
@@ -128,12 +128,12 @@ libcheck_check (struct checker * c)
{
char buff[MX_ALLOC_LEN];
- if (0 != do_inq(c->fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) {
+ if (0 != do_inq(c->fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0, c->timeout)) {
MSG(c, MSG_HP_SW_DOWN);
return PATH_DOWN;
}
- if (do_tur(c->fd)) {
+ if (do_tur(c->fd, c->timeout)) {
MSG(c, MSG_HP_SW_GHOST);
return PATH_GHOST;
}
Index: multipath-tools/libmultipath/checkers/libsg.c
===================================================================
--- multipath-tools.orig/libmultipath/checkers/libsg.c
+++ multipath-tools/libmultipath/checkers/libsg.c
@@ -11,7 +11,8 @@
#include "../libmultipath/sg_include.h"
int
-sg_read (int sg_fd, unsigned char * buff, unsigned char * senseBuff)
+sg_read (int sg_fd, unsigned char * buff, unsigned char * senseBuff,
+ unsigned int timeout)
{
/* defaults */
int blocks = 1;
@@ -51,7 +52,7 @@ sg_read (int sg_fd, unsigned char * buff
io_hdr.dxferp = buff;
io_hdr.mx_sb_len = SENSE_BUFF_LEN;
io_hdr.sbp = senseBuff;
- io_hdr.timeout = DEF_TIMEOUT;
+ io_hdr.timeout = timeout;
io_hdr.pack_id = (int)start_block;
if (diop && *diop)
io_hdr.flags |= SG_FLAG_DIRECT_IO;
Index: multipath-tools/libmultipath/checkers/libsg.h
===================================================================
--- multipath-tools.orig/libmultipath/checkers/libsg.h
+++ multipath-tools/libmultipath/checkers/libsg.h
@@ -3,6 +3,7 @@
#define SENSE_BUFF_LEN 32
-int sg_read (int sg_fd, unsigned char * buff, unsigned char * senseBuff);
+int sg_read (int sg_fd, unsigned char * buff, unsigned char * senseBuff,
+ unsigned int timeout);
#endif /* _LIBSG_H */
Index: multipath-tools/libmultipath/checkers/rdac.c
===================================================================
--- multipath-tools.orig/libmultipath/checkers/rdac.c
+++ multipath-tools/libmultipath/checkers/rdac.c
@@ -18,7 +18,6 @@
#define INQUIRY_CMDLEN 6
#define INQUIRY_CMD 0x12
#define SENSE_BUFF_LEN 32
-#define RDAC_DEF_TIMEOUT 60000
#define SCSI_CHECK_CONDITION 0x2
#define SCSI_COMMAND_TERMINATED 0x22
#define SG_ERR_DRIVER_SENSE 0x08
@@ -43,7 +42,8 @@ void libcheck_free (struct checker * c)
}
static int
-do_inq(int sg_fd, unsigned int pg_op, void *resp, int mx_resp_len)
+do_inq(int sg_fd, unsigned int pg_op, void *resp, int mx_resp_len,
+ unsigned int timeout)
{
unsigned char inqCmdBlk[INQUIRY_CMDLEN] = { INQUIRY_CMD, 1, 0, 0, 0, 0 };
unsigned char sense_b[SENSE_BUFF_LEN];
@@ -62,7 +62,7 @@ do_inq(int sg_fd, unsigned int pg_op, vo
io_hdr.dxferp = resp;
io_hdr.cmdp = inqCmdBlk;
io_hdr.sbp = sense_b;
- io_hdr.timeout = RDAC_DEF_TIMEOUT;
+ io_hdr.timeout = timeout;
if (ioctl(sg_fd, SG_IO, &io_hdr) < 0)
return 1;
@@ -103,7 +103,8 @@ 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))) {
+ if (0 != do_inq(c->fd, 0xC9, &inq, sizeof(struct volume_access_inq),
+ c->timeout)) {
MSG(c, MSG_RDAC_DOWN);
return PATH_DOWN;
} else {
Index: multipath-tools/libmultipath/checkers/readsector0.c
===================================================================
--- multipath-tools.orig/libmultipath/checkers/readsector0.c
+++ multipath-tools/libmultipath/checkers/readsector0.c
@@ -29,7 +29,7 @@ int libcheck_check (struct checker * c)
unsigned char sbuf[SENSE_BUFF_LEN];
int ret;
- ret = sg_read(c->fd, &buf[0], &sbuf[0]);
+ ret = sg_read(c->fd, &buf[0], &sbuf[0], c->timeout);
switch (ret)
{
Index: multipath-tools/libmultipath/checkers/tur.c
===================================================================
--- multipath-tools.orig/libmultipath/checkers/tur.c
+++ multipath-tools/libmultipath/checkers/tur.c
@@ -63,7 +63,7 @@ retry:
io_hdr.dxferp = (unsigned char *)resp_buffer;
io_hdr.cmdp = inq_cmd;
io_hdr.sbp = sense_buffer;
- io_hdr.timeout = 60; // IOCTL timeout value.
+ io_hdr.timeout = c->timeout; // IOCTL timeout value.
if (ioctl(c->fd, SG_IO, &io_hdr) < 0) {
condlog(0, "SG_IO ioctl failed: %s", strerror(errno));
@@ -148,7 +148,7 @@ libcheck_check (struct checker * c)
io_hdr.dxfer_direction = SG_DXFER_NONE;
io_hdr.cmdp = turCmdBlk;
io_hdr.sbp = sense_buffer;
- io_hdr.timeout = DEF_TIMEOUT;
+ io_hdr.timeout = c->timeout;
io_hdr.pack_id = 0;
if (ioctl(c->fd, SG_IO, &io_hdr) < 0) {
MSG(c, MSG_TUR_DOWN);
Index: multipath-tools/libmultipath/config.h
===================================================================
--- multipath-tools.orig/libmultipath/config.h
+++ multipath-tools/libmultipath/config.h
@@ -80,6 +80,7 @@ struct config {
int max_fds;
int force_reload;
int queue_without_daemon;
+ int checker_timeout;
int daemon;
int flush_on_last_del;
int attribute_flags;
Index: multipath-tools/libmultipath/dict.c
===================================================================
--- multipath-tools.orig/libmultipath/dict.c
+++ multipath-tools/libmultipath/dict.c
@@ -396,6 +396,25 @@ def_queue_without_daemon(vector strvec)
}
static int
+def_checker_timeout_handler(vector strvec)
+{
+ unsigned int checker_timeout;
+ char *buff;
+
+ buff = set_value(strvec);
+ if (!buff)
+ return 1;
+
+ if (sscanf(buff, "%u", &checker_timeout) == 1)
+ conf->checker_timeout = checker_timeout;
+ else
+ conf->checker_timeout = 0;
+
+ free(buff);
+ return 0;
+}
+
+static int
def_pg_timeout_handler(vector strvec)
{
int pg_timeout;
@@ -2068,6 +2087,15 @@ snprint_def_queue_without_daemon (char *
}
static int
+snprint_def_checker_timeout (char *buff, int len, void *data)
+{
+ if (!conf->checker_timeout)
+ return 0;
+
+ return snprintf(buff, len, "%u", conf->checker_timeout);
+}
+
+static int
snprint_def_pg_timeout (char * buff, int len, void * data)
{
if (conf->pg_timeout == DEFAULT_PGTIMEOUT)
@@ -2166,6 +2194,7 @@ init_keywords(void)
install_keyword("rr_weight", &def_weight_handler, &snprint_def_rr_weight);
install_keyword("no_path_retry", &def_no_path_retry_handler, &snprint_def_no_path_retry);
install_keyword("queue_without_daemon", &def_queue_without_daemon, &snprint_def_queue_without_daemon);
+ install_keyword("checker_timeout", &def_checker_timeout_handler, &snprint_def_checker_timeout);
install_keyword("pg_timeout", &def_pg_timeout_handler, &snprint_def_pg_timeout);
install_keyword("flush_on_last_del", &def_flush_on_last_del_handler, &snprint_def_flush_on_last_del);
install_keyword("user_friendly_names", &names_handler, &snprint_def_user_friendly_names);
Index: multipath-tools/libmultipath/discovery.c
===================================================================
--- multipath-tools.orig/libmultipath/discovery.c
+++ multipath-tools/libmultipath/discovery.c
@@ -164,6 +164,31 @@ sysfs_get_dev (struct sysfs_device * dev
}
int
+sysfs_get_timeout(struct sysfs_device *dev, unsigned int *timeout)
+{
+ char *attr;
+ char attr_path[SYSFS_PATH_SIZE];
+ int r;
+ unsigned int t;
+
+ if (safe_sprintf(attr_path, "%s/device", dev->devpath))
+ return 1;
+
+ attr = sysfs_attr_get_value(dev->devpath, "timeout");
+ if (!attr)
+ return 1;
+
+ r = sscanf(attr, "%u\n", &t);
+
+ if (r != 1)
+ return 1;
+
+ *timeout = t * 1000;
+
+ return 0;
+}
+
+int
sysfs_get_size (struct sysfs_device * dev, unsigned long long * size)
{
char *attr;
@@ -791,6 +816,8 @@ get_state (struct path * pp, int daemon)
return PATH_PENDING;
checker_set_async(c);
}
+ if (!conf->checker_timeout)
+ sysfs_get_timeout(pp->sysdev, &(c->timeout));
state = checker_check(c);
condlog(3, "%s: state = %i", pp->dev, state);
if (state == PATH_DOWN && strlen(checker_message(c)))
Index: multipath-tools/libmultipath/propsel.c
===================================================================
--- multipath-tools.orig/libmultipath/propsel.c
+++ multipath-tools/libmultipath/propsel.c
@@ -16,6 +16,7 @@
#include "defaults.h"
#include "devmapper.h"
#include "prio.h"
+#include "discovery.h"
pgpolicyfn *pgpolicies[] = {
NULL,
@@ -274,17 +275,31 @@ select_checker(struct path *pp)
checker_get(c, pp->hwe->checker_name);
condlog(3, "%s: path checker = %s (controller setting)",
pp->dev, checker_name(c));
- return 0;
+ goto out;
}
if (conf->checker_name) {
checker_get(c, conf->checker_name);
condlog(3, "%s: path checker = %s (config file default)",
pp->dev, checker_name(c));
- return 0;
+ goto out;
}
checker_get(c, DEFAULT_CHECKER);
condlog(3, "%s: path checker = %s (internal default)",
pp->dev, checker_name(c));
+out:
+ if (conf->checker_timeout) {
+ c->timeout = conf->checker_timeout * 1000;
+ condlog(3, "%s: checker timeout = %u ms (config file default)",
+ pp->dev, c->timeout);
+ }
+ else if (sysfs_get_timeout(pp->sysdev, &c->timeout) == 0)
+ condlog(3, "%s: checker timeout = %u ms (sysfs setting)",
+ pp->dev, c->timeout);
+ else {
+ c->timeout = DEF_TIMEOUT;
+ condlog(3, "%s: checker timeout = %u ms (internal default)",
+ pp->dev, c->timeout);
+ }
return 0;
}
Index: multipath-tools/multipath.conf.annotated
===================================================================
--- multipath-tools.orig/multipath.conf.annotated
+++ multipath-tools/multipath.conf.annotated
@@ -202,6 +202,15 @@
# gid disk
#
# #
+# # name : checker_timeout
+# # scope : multipath & multipathd
+# # desc : The timeout to use for path checkers that issue scsi
+# # commands with an explicit timeout, in seconds.
+# # values : n > 0
+# # default : taken from /sys/block/sd<x>/device/timeout
+# checker_timeout 60
+#
+# #
# # name : fast_io_fail_tmo
# # scope : multipath & multipathd
# # desc : The number of seconds the scsi layer will wait after a
Index: multipath-tools/libmultipath/discovery.h
===================================================================
--- multipath-tools.orig/libmultipath/discovery.h
+++ multipath-tools/libmultipath/discovery.h
@@ -36,6 +36,7 @@ int pathinfo (struct path *, vector hwta
struct path * store_pathinfo (vector pathvec, vector hwtable,
char * devname, int flag);
int sysfs_set_scsi_tmo (struct multipath *mpp);
+int sysfs_get_timeout(struct sysfs_device *dev, unsigned int *timeout);
/*
* discovery bitmask

View File

@ -1,68 +0,0 @@
Index: multipath-tools/multipathd/multipathd.8
===================================================================
--- multipath-tools.orig/multipathd/multipathd.8
+++ multipath-tools/multipathd/multipathd.8
@@ -35,9 +35,20 @@ The following commands can be used in in
.B list|show paths
Show the paths that multipathd is monitoring, and their state.
.TP
+.B list|show paths format $format
+Show the paths that multipathd is monitoring, using a format string with path
+format wildcards.
+.TP
+.B list|show status
+Show the number of monitored paths in each path checker state.
+.TP
.B list|show maps|multipaths
Show the multipath devices that the multipathd is monitoring.
.TP
+.B list|show maps|multipaths format $format
+Show the status of all multipath devices that the multipathd is monitoring,
+using a format string with multipath format wildcards.
+.TP
.B list|show maps|multipaths status
Show the status of all multipath devices that the multipathd is monitoring.
.TP
@@ -54,6 +65,9 @@ Show the current multipath topology. Sam
Show topology of a single multipath device specified by $map, e.g. 36005076303ffc56200000000000010aa.
This map could be obtained from "list maps".
.TP
+.B list|show wildcards
+Show the format wildcards used in interactive commands taking $format
+.TP
.B list|show config
Show the currently used configuration, derived from default values and values specified within the configuration file /etc/multipath.conf.
.TP
@@ -69,6 +83,10 @@ Add a path to the list of monitored path
.B remove|del path $path
Stop monitoring a path. $path is as listed in /sys/block (e.g. sda).
.TP
+.B paths count
+Show the number of monitored paths, and whether multipathd is currently
+handeling a uevent.
+.TP
.B add map $map
Add a multipath device to the list of monitored devices. $map can either be a device-mapper device as listed in /sys/block (e.g. dm-0) or it can be the alias for the multipath device (e.g. mpath1) or the uid of the multipath device (e.g. 36005076303ffc56200000000000010aa).
.TP
@@ -96,11 +114,20 @@ Sets path $path into failed state.
.B reinstate path $path
Resumes path $path from failed state.
.TP
+.B disablequeueing maps|multipaths
+Disable queueing on all multipath devices.
+.TP
+.B restorequeueing maps|multipaths
+Restore queueing on all multipath devices.
+.TP
.B disablequeueing map|multipath $map
-Disabled queuing on multipathed map $map
+Disable queuing on multipathed map $map
.TP
.B restorequeueing map|multipath $map
Restore queuing on multipahted map $map
+.TP
+.B quit|exit
+End interactive session.
.SH "SEE ALSO"
.BR multipath (8)

View File

@ -1,98 +0,0 @@
---
libmultipath/dict.c | 2 +-
multipath.conf.annotated | 4 ++--
multipath.conf.defaults | 2 +-
multipath.conf.synthetic | 2 +-
multipath/multipath.conf.5 | 18 +++++++++++++++---
5 files changed, 20 insertions(+), 8 deletions(-)
Index: multipath-tools/libmultipath/dict.c
===================================================================
--- multipath-tools.orig/libmultipath/dict.c
+++ multipath-tools/libmultipath/dict.c
@@ -2181,7 +2181,7 @@ init_keywords(void)
install_keyword("polling_interval", &polling_interval_handler, &snprint_def_polling_interval);
install_keyword("udev_dir", &udev_dir_handler, &snprint_def_udev_dir);
install_keyword("multipath_dir", &multipath_dir_handler, &snprint_def_multipath_dir);
- install_keyword("selector", &def_selector_handler, &snprint_def_selector);
+ install_keyword("path_selector", &def_selector_handler, &snprint_def_selector);
install_keyword("path_grouping_policy", &def_pgpolicy_handler, &snprint_def_path_grouping_policy);
install_keyword("getuid_callout", &def_getuid_callout_handler, &snprint_def_getuid_callout);
install_keyword("prio", &def_prio_handler, &snprint_def_prio);
Index: multipath-tools/multipath.conf.annotated
===================================================================
--- multipath-tools.orig/multipath.conf.annotated
+++ multipath-tools/multipath.conf.annotated
@@ -27,14 +27,14 @@
# polling_interval 10
#
# #
-# # name : selector
+# # name : path_selector
# # scope : multipath
# # desc : the default path selector algorithm to use
# # these algorithms are offered by the kernel multipath target
# # values : "round-robin 0"
# # default : "round-robin 0"
# #
-# selector "round-robin 0"
+# path_selector "round-robin 0"
#
# #
# # name : path_grouping_policy
Index: multipath-tools/multipath.conf.defaults
===================================================================
--- multipath-tools.orig/multipath.conf.defaults
+++ multipath-tools/multipath.conf.defaults
@@ -4,7 +4,7 @@
#defaults {
# udev_dir /dev
# polling_interval 5
-# selector "round-robin 0"
+# path_selector "round-robin 0"
# path_grouping_policy failover
# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
# prio const
Index: multipath-tools/multipath.conf.synthetic
===================================================================
--- multipath-tools.orig/multipath.conf.synthetic
+++ multipath-tools/multipath.conf.synthetic
@@ -5,7 +5,7 @@
#defaults {
# udev_dir /dev
# polling_interval 10
-# selector "round-robin 0"
+# path_selector "round-robin 0"
# path_grouping_policy multibus
# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
# prio const
Index: multipath-tools/multipath/multipath.conf.5
===================================================================
--- multipath-tools.orig/multipath/multipath.conf.5
+++ multipath-tools/multipath/multipath.conf.5
@@ -81,10 +81,22 @@ default verbosity. Higher values increas
levels are between 0 and 6; default is
.I 2
.TP
-.B selector
+.B path_selector
The default path selector algorithm to use; they are offered by the
-kernel multipath target. The only currently implemented is
-.I "round-robin 0"
+kernel multipath target. There are three selector algorithms.
+.RS
+.TP 12
+.B "round-robin 0"
+Loop through every path in the path group, sending the same amount of IO to
+each.
+.TP
+.B "queue-length 0"
+Send the next bunch of IO down the path with the least amount of outstanding IO.
+.TP
+.B "service-time 0"
+Choose the path for the next bunch of IO based on the amount of outstanding IO
+to the path and its relative throughput.
+.RE
.TP
.B path_grouping_policy
The default path grouping policy to apply to unspecified

View File

@ -1,442 +0,0 @@
---
libmultipath/dict.c | 137 ++++++++++++++--------------------------------------
1 file changed, 39 insertions(+), 98 deletions(-)
Index: multipath-tools/libmultipath/dict.c
===================================================================
--- multipath-tools.orig/libmultipath/dict.c
+++ multipath-tools/libmultipath/dict.c
@@ -328,6 +328,10 @@ def_weight_handler(vector strvec)
!strcmp(buff, "priorities"))
conf->rr_weight = RR_WEIGHT_PRIO;
+ if (strlen(buff) == strlen("uniform") &&
+ !strcmp(buff, "uniform"))
+ conf->rr_weight = RR_WEIGHT_NONE;
+
FREE(buff);
return 0;
@@ -923,6 +927,10 @@ hw_weight_handler(vector strvec)
!strcmp(buff, "priorities"))
hwe->rr_weight = RR_WEIGHT_PRIO;
+ if (strlen(buff) == strlen("uniform") &&
+ !strcmp(buff, "uniform"))
+ hwe->rr_weight = RR_WEIGHT_NONE;
+
FREE(buff);
return 0;
@@ -1251,6 +1259,10 @@ mp_weight_handler(vector strvec)
!strcmp(buff, "priorities"))
mpe->rr_weight = RR_WEIGHT_PRIO;
+ if (strlen(buff) == strlen("uniform") &&
+ !strcmp(buff, "uniform"))
+ mpe->rr_weight = RR_WEIGHT_NONE;
+
FREE(buff);
return 0;
@@ -1402,11 +1414,6 @@ snprint_mp_alias (char * buff, int len,
if (!mpe->alias)
return 0;
- if (conf->user_friendly_names &&
- (strlen(mpe->alias) == strlen("mpath")) &&
- !strcmp(mpe->alias, "mpath"))
- return 0;
-
return snprintf(buff, len, "%s", mpe->alias);
}
@@ -1431,7 +1438,7 @@ snprint_mp_selector (char * buff, int le
if (!mpe->selector)
return 0;
- return snprintf(buff, len, "%s", mpe->selector);
+ return snprintf(buff, len, "\"%s\"", mpe->selector);
}
static int
@@ -1494,6 +1501,8 @@ snprint_mp_rr_weight (char * buff, int l
return 0;
if (mpe->rr_weight == RR_WEIGHT_PRIO)
return snprintf(buff, len, "priorities");
+ if (mpe->rr_weight == RR_WEIGHT_NONE)
+ return snprintf(buff, len, "uniform");
return 0;
}
@@ -1568,8 +1577,6 @@ snprint_mp_prio (char * buff, int len, v
if (!mpe->prio_name)
return 0;
- if (!strcmp(mpe->prio_name, conf->prio_name) && !mpe->prio_args)
- return 0;
if (!mpe->prio_args)
return snprintf(buff, len, "%s", mpe->prio_name);
return snprintf(buff, len, "%s %s", mpe->prio_name, mpe->prio_args);
@@ -1635,9 +1642,6 @@ snprint_hw_getuid_callout (char * buff,
if (!hwe->getuid)
return 0;
- if (strlen(hwe->getuid) == strlen(conf->getuid) &&
- !strcmp(hwe->getuid, conf->getuid))
- return 0;
return snprintf(buff, len, "\"%s\"", hwe->getuid);
}
@@ -1649,8 +1653,6 @@ snprint_hw_prio (char * buff, int len, v
if (!hwe->prio_name)
return 0;
- if (!strcmp(hwe->prio_name, conf->prio_name) && !hwe->prio_args)
- return 0;
if (!hwe->prio_args)
return snprintf(buff, len, "%s", hwe->prio_name);
return snprintf(buff, len, "%s %s", hwe->prio_name, hwe->prio_args);
@@ -1663,9 +1665,6 @@ snprint_hw_features (char * buff, int le
if (!hwe->features)
return 0;
- if (strlen(hwe->features) == strlen(conf->features) &&
- !strcmp(hwe->features, conf->features))
- return 0;
return snprintf(buff, len, "\"%s\"", hwe->features);
}
@@ -1677,9 +1676,6 @@ snprint_hw_hardware_handler (char * buff
if (!hwe->hwhandler)
return 0;
- if (strlen(hwe->hwhandler) == strlen(conf->hwhandler) &&
- !strcmp(hwe->hwhandler, conf->hwhandler))
- return 0;
return snprintf(buff, len, "\"%s\"", hwe->hwhandler);
}
@@ -1691,11 +1687,8 @@ snprint_hw_selector (char * buff, int le
if (!hwe->selector)
return 0;
- if (strlen(hwe->selector) == strlen(conf->selector) &&
- !strcmp(hwe->selector, conf->selector))
- return 0;
- return snprintf(buff, len, "%s", hwe->selector);
+ return snprintf(buff, len, "\"%s\"", hwe->selector);
}
static int
@@ -1707,8 +1700,6 @@ snprint_hw_path_grouping_policy (char *
if (!hwe->pgpolicy)
return 0;
- if (hwe->pgpolicy == conf->pgpolicy)
- return 0;
get_pgpolicy_name(str, POLICY_NAME_SIZE, hwe->pgpolicy);
@@ -1722,8 +1713,6 @@ snprint_hw_failback (char * buff, int le
if (!hwe->pgfailback)
return 0;
- if (hwe->pgfailback == conf->pgfailback)
- return 0;
switch(hwe->pgfailback) {
case FAILBACK_UNDEF:
@@ -1745,10 +1734,10 @@ snprint_hw_rr_weight (char * buff, int l
if (!hwe->rr_weight)
return 0;
- if (hwe->rr_weight == conf->rr_weight)
- return 0;
if (hwe->rr_weight == RR_WEIGHT_PRIO)
return snprintf(buff, len, "priorities");
+ if (hwe->rr_weight == RR_WEIGHT_NONE)
+ return snprintf(buff, len, "uniform");
return 0;
}
@@ -1760,8 +1749,6 @@ snprint_hw_no_path_retry (char * buff, i
if (!hwe->no_path_retry)
return 0;
- if (hwe->no_path_retry == conf->no_path_retry)
- return 0;
switch(hwe->no_path_retry) {
case NO_PATH_RETRY_UNDEF:
@@ -1784,8 +1771,6 @@ snprint_hw_rr_min_io (char * buff, int l
if (!hwe->minio)
return 0;
- if (hwe->minio == conf->minio)
- return 0;
return snprintf(buff, len, "%u", hwe->minio);
}
@@ -1797,8 +1782,6 @@ snprint_hw_pg_timeout (char * buff, int
if (!hwe->pg_timeout)
return 0;
- if (hwe->pg_timeout == conf->pg_timeout)
- return 0;
switch (hwe->pg_timeout) {
case PGTIMEOUT_UNDEF:
@@ -1832,8 +1815,6 @@ snprint_hw_path_checker (char * buff, in
if (!hwe->checker_name)
return 0;
- if (!strcmp(hwe->checker_name, conf->checker_name))
- return 0;
return snprintf(buff, len, "%s", hwe->checker_name);
}
@@ -1841,8 +1822,6 @@ snprint_hw_path_checker (char * buff, in
static int
snprint_def_polling_interval (char * buff, int len, void * data)
{
- if (conf->checkint == DEFAULT_CHECKINT)
- return 0;
return snprintf(buff, len, "%i", conf->checkint);
}
@@ -1867,8 +1846,6 @@ snprint_def_dev_loss(char * buff, int le
static int
snprint_def_verbosity (char * buff, int len, void * data)
{
- if (conf->checkint == DEFAULT_VERBOSITY)
- return 0;
return snprintf(buff, len, "%i", conf->verbosity);
}
@@ -1877,9 +1854,6 @@ snprint_def_udev_dir (char * buff, int l
{
if (!conf->udev_dir)
return 0;
- if (strlen(DEFAULT_UDEVDIR) == strlen(conf->udev_dir) &&
- !strcmp(conf->udev_dir, DEFAULT_UDEVDIR))
- return 0;
return snprintf(buff, len, "\"%s\"", conf->udev_dir);
}
@@ -1887,10 +1861,7 @@ snprint_def_udev_dir (char * buff, int l
static int
snprint_def_multipath_dir (char * buff, int len, void * data)
{
- if (!conf->udev_dir)
- return 0;
- if (strlen(DEFAULT_MULTIPATHDIR) == strlen(conf->multipath_dir) &&
- !strcmp(conf->multipath_dir, DEFAULT_MULTIPATHDIR))
+ if (!conf->multipath_dir)
return 0;
return snprintf(buff, len, "\"%s\"", conf->multipath_dir);
@@ -1901,11 +1872,8 @@ snprint_def_selector (char * buff, int l
{
if (!conf->selector)
return 0;
- if (strlen(conf->selector) == strlen(DEFAULT_SELECTOR) &&
- !strcmp(conf->selector, DEFAULT_SELECTOR))
- return 0;
- return snprintf(buff, len, "%s", conf->selector);
+ return snprintf(buff, len, "\"%s\"", conf->selector);
}
static int
@@ -1913,12 +1881,10 @@ snprint_def_path_grouping_policy (char *
{
char str[POLICY_NAME_SIZE];
- if (!conf->pgpolicy)
- return 0;
- if (conf->pgpolicy == DEFAULT_PGPOLICY)
- return 0;
-
- get_pgpolicy_name(str, POLICY_NAME_SIZE, conf->pgpolicy);
+ if (conf->pgpolicy)
+ get_pgpolicy_name(str, POLICY_NAME_SIZE, conf->pgpolicy);
+ else
+ get_pgpolicy_name(str, POLICY_NAME_SIZE, DEFAULT_PGPOLICY);
return snprintf(buff, len, "%s", str);
}
@@ -1928,9 +1894,6 @@ snprint_def_getuid_callout (char * buff,
{
if (!conf->getuid)
return 0;
- if (strlen(conf->getuid) == strlen(DEFAULT_GETUID) &&
- !strcmp(conf->getuid, DEFAULT_GETUID))
- return 0;
return snprintf(buff, len, "\"%s\"", conf->getuid);
}
@@ -1941,10 +1904,6 @@ snprint_def_prio (char * buff, int len,
if (!conf->prio_name)
return 0;
- if (strlen(conf->prio_name) == strlen(DEFAULT_PRIO) &&
- !strcmp(conf->prio_name, DEFAULT_PRIO) && !conf->prio_args)
- return 0;
-
if (!conf->prio_args)
return snprintf(buff, len, "%s", conf->prio_name);
else
@@ -1957,9 +1916,6 @@ snprint_def_features (char * buff, int l
{
if (!conf->features)
return 0;
- if (strlen(conf->features) == strlen(DEFAULT_FEATURES) &&
- !strcmp(conf->features, DEFAULT_FEATURES))
- return 0;
return snprintf(buff, len, "\"%s\"", conf->features);
}
@@ -1969,9 +1925,6 @@ snprint_def_path_checker (char * buff, i
{
if (!conf->checker_name)
return 0;
- if (strlen(conf->checker_name) == strlen(DEFAULT_CHECKER) &&
- !strcmp(conf->checker_name, DEFAULT_CHECKER))
- return 0;
return snprintf(buff, len, "%s", conf->checker_name);
}
@@ -1979,12 +1932,11 @@ snprint_def_path_checker (char * buff, i
static int
snprint_def_failback (char * buff, int len, void * data)
{
+ int pgfailback = conf->pgfailback;
if (!conf->pgfailback)
- return 0;
- if (conf->pgfailback == DEFAULT_FAILBACK)
- return 0;
+ pgfailback = DEFAULT_FAILBACK;
- switch(conf->pgfailback) {
+ switch(pgfailback) {
case FAILBACK_UNDEF:
break;
case -FAILBACK_MANUAL:
@@ -1992,7 +1944,7 @@ snprint_def_failback (char * buff, int l
case -FAILBACK_IMMEDIATE:
return snprintf(buff, len, "immediate");
default:
- return snprintf(buff, len, "%i", conf->pgfailback);
+ return snprintf(buff, len, "%i", pgfailback);
}
return 0;
}
@@ -2000,12 +1952,10 @@ snprint_def_failback (char * buff, int l
static int
snprint_def_rr_min_io (char * buff, int len, void * data)
{
- if (!conf->minio)
- return 0;
- if (conf->minio == DEFAULT_MINIO)
- return 0;
-
- return snprintf(buff, len, "%u", conf->minio);
+ if (conf->minio)
+ return snprintf(buff, len, "%u", conf->minio);
+ else
+ return snprintf(buff, len, "%u", DEFAULT_MINIO);
}
static int
@@ -2045,11 +1995,11 @@ static int
snprint_def_rr_weight (char * buff, int len, void * data)
{
if (!conf->rr_weight)
- return 0;
- if (conf->rr_weight == DEFAULT_RR_WEIGHT)
- return 0;
+ return snprintf(buff, len, "uniform");
if (conf->rr_weight == RR_WEIGHT_PRIO)
return snprintf(buff, len, "priorities");
+ if (conf->rr_weight == RR_WEIGHT_NONE)
+ return snprintf(buff, len, "uniform");
return 0;
}
@@ -2057,9 +2007,6 @@ snprint_def_rr_weight (char * buff, int
static int
snprint_def_no_path_retry (char * buff, int len, void * data)
{
- if (conf->no_path_retry == DEFAULT_NO_PATH_RETRY)
- return 0;
-
switch(conf->no_path_retry) {
case NO_PATH_RETRY_UNDEF:
break;
@@ -2081,6 +2028,7 @@ snprint_def_queue_without_daemon (char *
case QUE_NO_DAEMON_OFF:
return snprintf(buff, len, "no");
case QUE_NO_DAEMON_ON:
+ case QUE_NO_DAEMON_UNDEF:
return snprintf(buff, len, "yes");
}
return 0;
@@ -2098,12 +2046,8 @@ snprint_def_checker_timeout (char *buff,
static int
snprint_def_pg_timeout (char * buff, int len, void * data)
{
- if (conf->pg_timeout == DEFAULT_PGTIMEOUT)
- return 0;
-
switch (conf->pg_timeout) {
case PGTIMEOUT_UNDEF:
- break;
case -PGTIMEOUT_NONE:
return snprintf(buff, len, "none");
default:
@@ -2117,6 +2061,7 @@ snprint_def_flush_on_last_del (char * bu
{
switch (conf->flush_on_last_del) {
case FLUSH_DISABLED:
+ case FLUSH_UNDEF:
return snprintf(buff, len, "no");
case FLUSH_ENABLED:
return snprintf(buff, len, "yes");
@@ -2127,8 +2072,6 @@ snprint_def_flush_on_last_del (char * bu
static int
snprint_def_find_multipaths (char * buff, int len, void * data)
{
- if (conf->find_multipaths == DEFAULT_FIND_MULTIPATHS)
- return 0;
if (!conf->find_multipaths)
return snprintf(buff, len, "no");
@@ -2139,8 +2082,6 @@ snprint_def_find_multipaths (char * buff
static int
snprint_def_user_friendly_names (char * buff, int len, void * data)
{
- if (conf->user_friendly_names == DEFAULT_USER_FRIENDLY_NAMES)
- return 0;
if (!conf->user_friendly_names)
return snprintf(buff, len, "no");
@@ -2187,7 +2128,7 @@ init_keywords(void)
install_keyword("prio", &def_prio_handler, &snprint_def_prio);
install_keyword("features", &def_features_handler, &snprint_def_features);
install_keyword("path_checker", &def_path_checker_handler, &snprint_def_path_checker);
- install_keyword("checker", &def_path_checker_handler, &snprint_def_path_checker);
+ install_keyword("checker", &def_path_checker_handler, NULL);
install_keyword("failback", &default_failback_handler, &snprint_def_failback);
install_keyword("rr_min_io", &def_minio_handler, &snprint_def_rr_min_io);
install_keyword("max_fds", &max_fds_handler, &snprint_max_fds);
@@ -2248,7 +2189,7 @@ init_keywords(void)
install_keyword("getuid_callout", &hw_getuid_callout_handler, &snprint_hw_getuid_callout);
install_keyword("path_selector", &hw_selector_handler, &snprint_hw_selector);
install_keyword("path_checker", &hw_path_checker_handler, &snprint_hw_path_checker);
- install_keyword("checker", &hw_path_checker_handler, &snprint_hw_path_checker);
+ install_keyword("checker", &hw_path_checker_handler, NULL);
install_keyword("features", &hw_features_handler, &snprint_hw_features);
install_keyword("hardware_handler", &hw_handler_handler, &snprint_hw_hardware_handler);
install_keyword("prio", &hw_prio_handler, &snprint_hw_prio);

View File

@ -1,57 +0,0 @@
---
libmultipath/dict.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
Index: multipath-tools/libmultipath/dict.c
===================================================================
--- multipath-tools.orig/libmultipath/dict.c
+++ multipath-tools/libmultipath/dict.c
@@ -720,6 +720,22 @@ product_handler(vector strvec)
}
static int
+revision_handler(vector strvec)
+{
+ struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
+
+ if (!hwe)
+ return 1;
+
+ hwe->revision = set_value(strvec);
+
+ if (!hwe->revision)
+ return 1;
+
+ return 0;
+}
+
+static int
bl_product_handler(vector strvec)
{
struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
@@ -1625,6 +1641,17 @@ snprint_hw_product (char * buff, int len
}
static int
+snprint_hw_revision (char * buff, int len, void * data)
+{
+ struct hwentry * hwe = (struct hwentry *)data;
+
+ if (!hwe->revision)
+ return 0;
+
+ return snprintf(buff, len, "\"%s\"", hwe->revision);
+}
+
+static int
snprint_hw_bl_product (char * buff, int len, void * data)
{
struct hwentry * hwe = (struct hwentry *)data;
@@ -2184,6 +2211,7 @@ init_keywords(void)
install_sublevel();
install_keyword("vendor", &vendor_handler, &snprint_hw_vendor);
install_keyword("product", &product_handler, &snprint_hw_product);
+ install_keyword("revision", &revision_handler, &snprint_hw_revision);
install_keyword("product_blacklist", &bl_product_handler, &snprint_hw_bl_product);
install_keyword("path_grouping_policy", &hw_pgpolicy_handler, &snprint_hw_path_grouping_policy);
install_keyword("getuid_callout", &hw_getuid_callout_handler, &snprint_hw_getuid_callout);

View File

@ -1,68 +0,0 @@
---
multipathd/main.c | 34 +++++++++++++++++++++++++++++-----
1 file changed, 29 insertions(+), 5 deletions(-)
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -48,6 +48,7 @@
#include <configure.h>
#include <prio.h>
#include <finder.h>
+#include <pgpolicies.h>
#include "main.h"
#include "pidfile.h"
@@ -911,10 +912,33 @@ retry_count_tick(vector mpvec)
}
}
+int update_path_groups(struct multipath *mpp, struct vectors *vecs)
+{
+ int i;
+ struct path * pp;
+
+ update_mpp_paths(mpp, vecs->pathvec);
+ vector_foreach_slot (mpp->paths, pp, i)
+ pathinfo(pp, conf->hwtable, DI_PRIO);
+ setup_map(mpp);
+ mpp->action = ACT_RELOAD;
+ if (domap(mpp) <= 0) {
+ condlog(0, "%s: failed to update map : %s", mpp->alias,
+ strerror(errno));
+ return 1;
+ }
+ dm_lib_release();
+ setup_multipath(vecs, mpp);
+ sync_map_state(mpp);
+
+ return 0;
+}
+
void
check_path (struct vectors * vecs, struct path * pp)
{
int newstate;
+ int oldpriority;
if (!pp->mpp)
return;
@@ -1024,12 +1048,12 @@ check_path (struct vectors * vecs, struc
* path prio refreshing
*/
condlog(4, "path prio refresh");
+ oldpriority = pp->priority;
pathinfo(pp, conf->hwtable, DI_PRIO);
-
- /*
- * pathgroup failback policy
- */
- if (need_switch_pathgroup(pp->mpp, 0)) {
+ if (pp->priority != oldpriority &&
+ pp->mpp->pgpolicyfn == (pgpolicyfn *)group_by_prio)
+ update_path_groups(pp->mpp, vecs);
+ else if (need_switch_pathgroup(pp->mpp, 0)) {
if (pp->mpp->pgfailback > 0 &&
pp->mpp->failback_tick <= 0)
pp->mpp->failback_tick =

View File

@ -1,146 +0,0 @@
---
libmultipath/finder.c | 2 +-
libmultipath/finder.h | 1 +
multipath/main.c | 35 ++++++++++++++++++++++++++++-------
multipath/multipath.rules | 8 ++++++++
4 files changed, 38 insertions(+), 8 deletions(-)
Index: multipath-tools/libmultipath/finder.c
===================================================================
--- multipath-tools.orig/libmultipath/finder.c
+++ multipath-tools/libmultipath/finder.c
@@ -78,7 +78,7 @@ write_out_wwid(int fd, char *wwid) {
return 1;
}
-static int
+int
check_wwids_file(char *wwid, int write_wwid)
{
int scan_fd, fd, can_write, found, ret;
Index: multipath-tools/libmultipath/finder.h
===================================================================
--- multipath-tools.orig/libmultipath/finder.h
+++ multipath-tools/libmultipath/finder.h
@@ -14,5 +14,6 @@
int should_multipath(struct path *pp, vector pathvec);
int remember_wwid(char *wwid);
+int check_wwids_file(char *wwid, int write_wwid);
#endif /* _FINDER_H */
Index: multipath-tools/multipath/main.c
===================================================================
--- multipath-tools.orig/multipath/main.c
+++ multipath-tools/multipath/main.c
@@ -51,6 +51,7 @@
#include <errno.h>
#include <sys/time.h>
#include <sys/resource.h>
+#include <finder.h>
int logsink;
@@ -79,7 +80,7 @@ usage (char * progname)
{
fprintf (stderr, VERSION_STRING);
fprintf (stderr, "Usage:\n");
- fprintf (stderr, " %s [-d] [-r] [-v lvl] [-p pol] [-b fil] [dev]\n", progname);
+ fprintf (stderr, " %s [-c] [-d] [-r] [-v lvl] [-p pol] [-b fil] [dev]\n", progname);
fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [dev]\n", progname);
fprintf (stderr, " %s -F [-v lvl]\n", progname);
fprintf (stderr, " %s -h\n", progname);
@@ -91,6 +92,7 @@ usage (char * progname)
" -ll show multipath topology (maximum info)\n" \
" -f flush a multipath device map\n" \
" -F flush all multipath device maps\n" \
+ " -c check if a device should be a path in a multipath device\n" \
" -d dry run, do not create or update devmaps\n" \
" -r force devmap reload\n" \
" -p policy failover|multibus|group_by_serial|group_by_prio\n" \
@@ -249,10 +251,11 @@ configure (void)
/*
* if we have a blacklisted device parameter, exit early
*/
- if (dev &&
- (filter_devnode(conf->blist_devnode, conf->elist_devnode, dev) > 0))
- goto out;
-
+ if (dev && (filter_devnode(conf->blist_devnode, conf->elist_devnode, dev) > 0)) {
+ if (conf->dry_run == 2)
+ printf("%s is not a valid multipath device path\n", conf->dev);
+ goto out;
+ }
/*
* scope limiting must be translated into a wwid
* failing the translation is fatal (by policy)
@@ -268,6 +271,15 @@ configure (void)
if (filter_wwid(conf->blist_wwid, conf->elist_wwid,
refwwid) > 0)
goto out;
+ if (conf->dry_run == 2) {
+ if (check_wwids_file(refwwid, 0) == 0){
+ printf("%s is a valid multipath device path\n", conf->dev);
+ r = 0;
+ }
+ else
+ printf("%s is not a valid multipath device path\n", conf->dev);
+ goto out;
+ }
}
/*
@@ -350,7 +362,7 @@ main (int argc, char *argv[])
condlog(0, "multipath tools need sysfs mounted");
exit(1);
}
- while ((arg = getopt(argc, argv, ":dhl::FfM:v:p:b:r")) != EOF ) {
+ while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:r")) != EOF ) {
switch(arg) {
case 1: printf("optarg : %s\n",optarg);
break;
@@ -364,8 +376,12 @@ main (int argc, char *argv[])
case 'b':
conf->bindings_file = optarg;
break;
+ case 'c':
+ conf->dry_run = 2;
+ break;
case 'd':
- conf->dry_run = 1;
+ if (!conf->dry_run)
+ conf->dry_run = 1;
break;
case 'f':
conf->remove = FLUSH_ONE;
@@ -438,6 +454,11 @@ main (int argc, char *argv[])
dm_init();
+ if (conf->dry_run == 2 &&
+ (!conf->dev || conf->dev_type == DEV_DEVMAP)) {
+ condlog(0, "the -c option requires a path to check");
+ goto out;
+ }
if (conf->remove == FLUSH_ONE) {
if (conf->dev_type == DEV_DEVMAP)
r = dm_flush_map(conf->dev);
Index: multipath-tools/multipath/multipath.rules
===================================================================
--- multipath-tools.orig/multipath/multipath.rules
+++ multipath-tools/multipath/multipath.rules
@@ -1,6 +1,14 @@
# multipath wants the devmaps presented as meaninglful device names
# so name them after their devmap name
SUBSYSTEM!="block", GOTO="end_mpath"
+TEST!="/sbin/multipath", GOTO="check_usr"
+ENV{MPATH_GOT_HERE}="$env{DEVNAME}"
+PROGRAM=="/sbin/multipath -c /dev/$env{DEVNAME}", ENV{DM_MULTIPATH_DEVICE_PATH}="1"
+GOTO="skip_usr"
+LABEL="check_usr"
+ENV{MPATH_GOT_HERE} = "2"
+PROGRAM=="/usr/sbin/multipath -c /dev/$env{DEVNAME}", ENV{DM_MULTIPATH_DEVICE_PATH}="1"
+LABEL="skip_usr"
RUN+="socket:/org/kernel/dm/multipath_event"
KERNEL!="dm-*", GOTO="end_mpath"
ACTION!="change", GOTO="end_mpath"

View File

@ -1,23 +0,0 @@
diff --git a/libmultipath/print.c b/libmultipath/print.c
index 10e5ce5..9753fe2 100644
--- a/libmultipath/print.c
+++ b/libmultipath/print.c
@@ -378,6 +378,7 @@ snprint_pg_selector (char * buff, size_t len, struct pathgroup * pgp)
static int
snprint_pg_pri (char * buff, size_t len, struct pathgroup * pgp)
{
+ int avg_priority = 0;
/*
* path group priority is not updated for every path prio change,
* but only on switch group code path.
@@ -385,7 +386,9 @@ snprint_pg_pri (char * buff, size_t len, struct pathgroup * pgp)
* Printing is another reason to update.
*/
path_group_prio_update(pgp);
- return snprint_int(buff, len, pgp->priority);
+ if (pgp->enabled_paths)
+ avg_priority = pgp->priority / pgp->enabled_paths;
+ return snprint_int(buff, len, avg_priority);
}
static int

View File

@ -1,617 +0,0 @@
---
libmultipath/hwtable.c | 4
libmultipath/prio.h | 2
libmultipath/prioritizers/Makefile | 2
libmultipath/prioritizers/netapp.c | 243 ------------------------------------
libmultipath/prioritizers/netapp.h | 7 -
libmultipath/prioritizers/ontap.c | 245 +++++++++++++++++++++++++++++++++++++
libmultipath/prioritizers/ontap.h | 7 +
multipath.conf.defaults | 4
multipath/multipath.conf.5 | 2
9 files changed, 259 insertions(+), 257 deletions(-)
Index: multipath-tools/libmultipath/hwtable.c
===================================================================
--- multipath-tools.orig/libmultipath/hwtable.c
+++ multipath-tools/libmultipath/hwtable.c
@@ -769,7 +769,7 @@ static struct hwentry default_hw[] = {
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = 128,
.checker_name = DIRECTIO,
- .prio_name = PRIO_NETAPP,
+ .prio_name = PRIO_ONTAP,
},
/*
* IBM NSeries (NETAPP) controller family
@@ -790,7 +790,7 @@ static struct hwentry default_hw[] = {
.no_path_retry = NO_PATH_RETRY_UNDEF,
.minio = 128,
.checker_name = DIRECTIO,
- .prio_name = PRIO_NETAPP,
+ .prio_name = PRIO_ONTAP,
},
/*
* Pillar Data controller family
Index: multipath-tools/libmultipath/prio.h
===================================================================
--- multipath-tools.orig/libmultipath/prio.h
+++ multipath-tools/libmultipath/prio.h
@@ -21,7 +21,7 @@
#define PRIO_EMC "emc"
#define PRIO_HDS "hds"
#define PRIO_HP_SW "hp_sw"
-#define PRIO_NETAPP "netapp"
+#define PRIO_ONTAP "ontap"
#define PRIO_RANDOM "random"
#define PRIO_RDAC "rdac"
#define PRIO_WEIGHTED "weighted"
Index: multipath-tools/libmultipath/prioritizers/Makefile
===================================================================
--- multipath-tools.orig/libmultipath/prioritizers/Makefile
+++ multipath-tools/libmultipath/prioritizers/Makefile
@@ -12,7 +12,7 @@ LIBS = \
libpriordac.so \
libprioalua.so \
libpriotpg_pref.so \
- libprionetapp.so \
+ libprioontap.so \
libpriohds.so \
libprioweighted.so \
Index: multipath-tools/libmultipath/prioritizers/netapp.c
===================================================================
--- multipath-tools.orig/libmultipath/prioritizers/netapp.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright 2005 Network Appliance, Inc., All Rights Reserved
- * Author: David Wysochanski available at davidw@netapp.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License v2 for more details.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-#include <assert.h>
-
-#include <sg_include.h>
-#include <debug.h>
-#include <prio.h>
-
-#define INQUIRY_CMD 0x12
-#define INQUIRY_CMDLEN 6
-#define DEFAULT_PRIOVAL 10
-#define RESULTS_MAX 256
-#define SG_TIMEOUT 30000
-
-#define pp_netapp_log(prio, fmt, args...) \
- condlog(prio, "%s: netapp prio: " fmt, dev, ##args)
-
-static void dump_cdb(unsigned char *cdb, int size)
-{
- int i;
- char buf[10*5+1];
- char * p = &buf[0];
-
- condlog(0, "- SCSI CDB: ");
- for (i=0; i<size; i++) {
- p += snprintf(p, 10*(size-i), "0x%02x ", cdb[i]);
- }
- condlog(0, "%s", buf);
-}
-
-static void process_sg_error(struct sg_io_hdr *io_hdr)
-{
- int i;
- char buf[128*5+1];
- char * p = &buf[0];
-
- condlog(0, "- masked_status=0x%02x, host_status=0x%02x, "
- "driver_status=0x%02x", io_hdr->masked_status,
- io_hdr->host_status, io_hdr->driver_status);
- if (io_hdr->sb_len_wr > 0) {
- condlog(0, "- SCSI sense data: ");
- for (i=0; i<io_hdr->sb_len_wr; i++) {
- p += snprintf(p, 128*(io_hdr->sb_len_wr-i), "0x%02x ",
- io_hdr->sbp[i]);
- }
- condlog(0, "%s", buf);
- }
-}
-
-/*
- * Returns:
- * -1: error, errno set
- * 0: success
- */
-static int send_gva(const char *dev, int fd, unsigned char pg,
- unsigned char *results, int *results_size)
-{
- unsigned char sb[128];
- unsigned char cdb[10] = {0xc0, 0, 0x1, 0xa, 0x98, 0xa,
- pg, sizeof(sb), 0, 0};
- struct sg_io_hdr io_hdr;
- int ret = -1;
-
- memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
- io_hdr.interface_id = 'S';
- io_hdr.cmd_len = sizeof (cdb);
- io_hdr.mx_sb_len = sizeof (sb);
- io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
- io_hdr.dxfer_len = *results_size;
- io_hdr.dxferp = results;
- io_hdr.cmdp = cdb;
- io_hdr.sbp = sb;
- io_hdr.timeout = SG_TIMEOUT;
- io_hdr.pack_id = 0;
- if (ioctl(fd, SG_IO, &io_hdr) < 0) {
- pp_netapp_log(0, "SG_IO ioctl failed, errno=%d", errno);
- dump_cdb(cdb, sizeof(cdb));
- goto out;
- }
- if (io_hdr.info & SG_INFO_OK_MASK) {
- pp_netapp_log(0, "SCSI error");
- dump_cdb(cdb, sizeof(cdb));
- process_sg_error(&io_hdr);
- goto out;
- }
-
- if (results[4] != 0x0a || results[5] != 0x98 ||
- results[6] != 0x0a ||results[7] != 0x01) {
- dump_cdb(cdb, sizeof(cdb));
- pp_netapp_log(0, "GVA return wrong format ");
- pp_netapp_log(0, "results[4-7] = 0x%02x 0x%02x 0x%02x 0x%02x",
- results[4], results[5], results[6], results[7]);
- goto out;
- }
- ret = 0;
- out:
- return(ret);
-}
-
-/*
- * Retuns:
- * -1: Unable to obtain proxy info
- * 0: Device _not_ proxy path
- * 1: Device _is_ proxy path
- */
-static int get_proxy(const char *dev, int fd)
-{
- unsigned char results[256];
- unsigned char sb[128];
- unsigned char cdb[INQUIRY_CMDLEN] = {INQUIRY_CMD, 1, 0xc1, 0,
- sizeof(sb), 0};
- struct sg_io_hdr io_hdr;
- int ret = -1;
-
- memset(&results, 0, sizeof (results));
- memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
- io_hdr.interface_id = 'S';
- io_hdr.cmd_len = sizeof (cdb);
- io_hdr.mx_sb_len = sizeof (sb);
- io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
- io_hdr.dxfer_len = sizeof (results);
- io_hdr.dxferp = results;
- io_hdr.cmdp = cdb;
- io_hdr.sbp = sb;
- io_hdr.timeout = SG_TIMEOUT;
- io_hdr.pack_id = 0;
- if (ioctl(fd, SG_IO, &io_hdr) < 0) {
- pp_netapp_log(0, "ioctl sending inquiry command failed, "
- "errno=%d", errno);
- dump_cdb(cdb, sizeof(cdb));
- goto out;
- }
- if (io_hdr.info & SG_INFO_OK_MASK) {
- pp_netapp_log(0, "SCSI error");
- dump_cdb(cdb, sizeof(cdb));
- process_sg_error(&io_hdr);
- goto out;
- }
-
- if (results[1] != 0xc1 || results[8] != 0x0a ||
- results[9] != 0x98 || results[10] != 0x0a ||
- results[11] != 0x0 || results[12] != 0xc1 ||
- results[13] != 0x0) {
- pp_netapp_log(0,"proxy info page in unknown format - ");
- pp_netapp_log(0,"results[8-13]=0x%02x 0x%02x 0x%02x 0x%02x "
- "0x%02x 0x%02x",
- results[8], results[9], results[10],
- results[11], results[12], results[13]);
- dump_cdb(cdb, sizeof(cdb));
- goto out;
- }
- ret = (results[19] & 0x02) >> 1;
-
- out:
- return(ret);
-}
-
-/*
- * Returns priority of device based on device info.
- *
- * 4: FCP non-proxy, FCP proxy unknown, or unable to determine protocol
- * 3: iSCSI HBA
- * 2: iSCSI software
- * 1: FCP proxy
- */
-static int netapp_prio(const char *dev, int fd)
-{
- unsigned char results[RESULTS_MAX];
- int results_size=RESULTS_MAX;
- int rc;
- int is_proxy;
- int is_iscsi_software;
- int is_iscsi_hardware;
- int tot_len;
-
- is_iscsi_software = is_iscsi_hardware = is_proxy = 0;
-
- memset(&results, 0, sizeof (results));
- rc = send_gva(dev, fd, 0x41, results, &results_size);
- if (rc == 0) {
- tot_len = results[0] << 24 | results[1] << 16 |
- results[2] << 8 | results[3];
- if (tot_len <= 8) {
- goto try_fcp_proxy;
- }
- if (results[8] != 0x41) {
- pp_netapp_log(0, "GVA page 0x41 error - "
- "results[8] = 0x%x", results[8]);
- goto try_fcp_proxy;
- }
- if ((strncmp((char *)&results[12], "ism_sw", 6) == 0) ||
- (strncmp((char *)&results[12], "iswt", 4) == 0)) {
- is_iscsi_software = 1;
- goto prio_select;
- }
- else if (strncmp((char *)&results[12], "ism_sn", 6) == 0) {
- is_iscsi_hardware = 1;
- goto prio_select;
- }
- }
-
- try_fcp_proxy:
- rc = get_proxy(dev, fd);
- if (rc >= 0) {
- is_proxy = rc;
- }
-
- prio_select:
- if (is_iscsi_hardware) {
- return 3;
- } else if (is_iscsi_software) {
- return 2;
- } else {
- if (is_proxy) {
- return 1;
- } else {
- /* Either non-proxy, or couldn't get proxy info */
- return 4;
- }
- }
-}
-
-int getprio (struct path * pp)
-{
- return netapp_prio(pp->dev, pp->fd);
-}
Index: multipath-tools/libmultipath/prioritizers/netapp.h
===================================================================
--- multipath-tools.orig/libmultipath/prioritizers/netapp.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _NETAPP_H
-#define _NETAPP_H
-
-#define PRIO_NETAPP "netapp"
-int prio_netapp(struct path * pp);
-
-#endif
Index: multipath-tools/libmultipath/prioritizers/ontap.c
===================================================================
--- /dev/null
+++ multipath-tools/libmultipath/prioritizers/ontap.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright 2005 Network Appliance, Inc., All Rights Reserved
+ * Author: David Wysochanski available at davidw@netapp.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License v2 for more details.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <sg_include.h>
+#include <debug.h>
+#include <prio.h>
+
+#define INQUIRY_CMD 0x12
+#define INQUIRY_CMDLEN 6
+#define DEFAULT_PRIOVAL 10
+#define RESULTS_MAX 256
+#define SG_TIMEOUT 60000
+
+#define pp_ontap_log(prio, fmt, args...) \
+ condlog(prio, "%s: ontap prio: " fmt, dev, ##args)
+
+static void dump_cdb(unsigned char *cdb, int size)
+{
+ int i;
+ char buf[10*5+1];
+ char * p = &buf[0];
+
+ condlog(0, "- SCSI CDB: ");
+ for (i=0; i<size; i++) {
+ p += snprintf(p, 10*(size-i), "0x%02x ", cdb[i]);
+ }
+ condlog(0, "%s", buf);
+}
+
+static void process_sg_error(struct sg_io_hdr *io_hdr)
+{
+ int i;
+ char buf[128*5+1];
+ char * p = &buf[0];
+
+ condlog(0, "- masked_status=0x%02x, host_status=0x%02x, "
+ "driver_status=0x%02x", io_hdr->masked_status,
+ io_hdr->host_status, io_hdr->driver_status);
+ if (io_hdr->sb_len_wr > 0) {
+ condlog(0, "- SCSI sense data: ");
+ for (i=0; i<io_hdr->sb_len_wr; i++) {
+ p += snprintf(p, 128*(io_hdr->sb_len_wr-i), "0x%02x ",
+ io_hdr->sbp[i]);
+ }
+ condlog(0, "%s", buf);
+ }
+}
+
+/*
+ * Returns:
+ * -1: error, errno set
+ * 0: success
+ */
+static int send_gva(const char *dev, int fd, unsigned char pg,
+ unsigned char *results, int *results_size)
+{
+ unsigned char sb[128];
+ unsigned char cdb[10] = {0xc0, 0, 0x1, 0xa, 0x98, 0xa,
+ pg, sizeof(sb), 0, 0};
+ struct sg_io_hdr io_hdr;
+ int ret = -1;
+
+ memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
+ io_hdr.interface_id = 'S';
+ io_hdr.cmd_len = sizeof (cdb);
+ io_hdr.mx_sb_len = sizeof (sb);
+ io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+ io_hdr.dxfer_len = *results_size;
+ io_hdr.dxferp = results;
+ io_hdr.cmdp = cdb;
+ io_hdr.sbp = sb;
+ io_hdr.timeout = SG_TIMEOUT;
+ io_hdr.pack_id = 0;
+ if (ioctl(fd, SG_IO, &io_hdr) < 0) {
+ pp_ontap_log(0, "SG_IO ioctl failed, errno=%d", errno);
+ dump_cdb(cdb, sizeof(cdb));
+ goto out;
+ }
+ if (io_hdr.info & SG_INFO_OK_MASK) {
+ pp_ontap_log(0, "SCSI error");
+ dump_cdb(cdb, sizeof(cdb));
+ process_sg_error(&io_hdr);
+ goto out;
+ }
+
+ if (results[4] != 0x0a || results[5] != 0x98 ||
+ results[6] != 0x0a ||results[7] != 0x01) {
+ dump_cdb(cdb, sizeof(cdb));
+ pp_ontap_log(0, "GVA return wrong format ");
+ pp_ontap_log(0, "results[4-7] = 0x%02x 0x%02x 0x%02x 0x%02x",
+ results[4], results[5], results[6], results[7]);
+ goto out;
+ }
+ ret = 0;
+ out:
+ return(ret);
+}
+
+/*
+ * Retuns:
+ * -1: Unable to obtain proxy info
+ * 0: Device _not_ proxy path
+ * 1: Device _is_ proxy path
+ */
+static int get_proxy(const char *dev, int fd)
+{
+ unsigned char results[256];
+ unsigned char sb[128];
+ unsigned char cdb[INQUIRY_CMDLEN] = {INQUIRY_CMD, 1, 0xc1, 0,
+ sizeof(sb), 0};
+ struct sg_io_hdr io_hdr;
+ int ret = -1;
+
+ memset(&results, 0, sizeof (results));
+ memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
+ io_hdr.interface_id = 'S';
+ io_hdr.cmd_len = sizeof (cdb);
+ io_hdr.mx_sb_len = sizeof (sb);
+ io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+ io_hdr.dxfer_len = sizeof (results);
+ io_hdr.dxferp = results;
+ io_hdr.cmdp = cdb;
+ io_hdr.sbp = sb;
+ io_hdr.timeout = SG_TIMEOUT;
+ io_hdr.pack_id = 0;
+ if (ioctl(fd, SG_IO, &io_hdr) < 0) {
+ pp_ontap_log(0, "ioctl sending inquiry command failed, "
+ "errno=%d", errno);
+ dump_cdb(cdb, sizeof(cdb));
+ goto out;
+ }
+ if (io_hdr.info & SG_INFO_OK_MASK) {
+ pp_ontap_log(0, "SCSI error");
+ dump_cdb(cdb, sizeof(cdb));
+ process_sg_error(&io_hdr);
+ goto out;
+ }
+
+ if (results[1] != 0xc1 || results[8] != 0x0a ||
+ results[9] != 0x98 || results[10] != 0x0a ||
+ results[11] != 0x0 || results[12] != 0xc1 ||
+ results[13] != 0x0) {
+ pp_ontap_log(0,"proxy info page in unknown format - ");
+ pp_ontap_log(0,"results[8-13]=0x%02x 0x%02x 0x%02x 0x%02x "
+ "0x%02x 0x%02x",
+ results[8], results[9], results[10],
+ results[11], results[12], results[13]);
+ dump_cdb(cdb, sizeof(cdb));
+ goto out;
+ }
+ ret = (results[19] & 0x02) >> 1;
+
+ out:
+ return(ret);
+}
+
+/*
+ * Returns priority of device based on device info.
+ *
+ * 4: FCP non-proxy, FCP proxy unknown, or unable to determine protocol
+ * 3: iSCSI HBA
+ * 2: iSCSI software
+ * 1: FCP proxy
+ */
+static int ontap_prio(const char *dev, int fd)
+{
+ unsigned char results[RESULTS_MAX];
+ int results_size=RESULTS_MAX;
+ int rc;
+ int is_proxy;
+ int is_iscsi_software;
+ int is_iscsi_hardware;
+ int tot_len;
+
+ is_iscsi_software = is_iscsi_hardware = is_proxy = 0;
+
+ memset(&results, 0, sizeof (results));
+ rc = send_gva(dev, fd, 0x41, results, &results_size);
+ if (rc >= 0) {
+ tot_len = results[0] << 24 | results[1] << 16 |
+ results[2] << 8 | results[3];
+ if (tot_len <= 8) {
+ goto try_fcp_proxy;
+ }
+ if (results[8] != 0x41) {
+ pp_ontap_log(0, "GVA page 0x41 error - "
+ "results[8] = 0x%x", results[8]);
+ goto try_fcp_proxy;
+ }
+ if ((strncmp((char *)&results[12], "ism_sw", 6) == 0) ||
+ (strncmp((char *)&results[12], "iswt", 4) == 0)) {
+ is_iscsi_software = 1;
+ goto prio_select;
+ }
+ else if (strncmp((char *)&results[12], "ism_sn", 6) == 0) {
+ is_iscsi_hardware = 1;
+ goto prio_select;
+ }
+ } else {
+ return 0;
+ }
+
+ try_fcp_proxy:
+ rc = get_proxy(dev, fd);
+ if (rc >= 0) {
+ is_proxy = rc;
+ }
+
+ prio_select:
+ if (is_iscsi_hardware) {
+ return 3;
+ } else if (is_iscsi_software) {
+ return 2;
+ } else {
+ if (is_proxy) {
+ return 1;
+ } else {
+ /* Either non-proxy, or couldn't get proxy info */
+ return 4;
+ }
+ }
+}
+
+int getprio (struct path * pp)
+{
+ return ontap_prio(pp->dev, pp->fd);
+}
Index: multipath-tools/libmultipath/prioritizers/ontap.h
===================================================================
--- /dev/null
+++ multipath-tools/libmultipath/prioritizers/ontap.h
@@ -0,0 +1,7 @@
+#ifndef _ONTAP_H
+#define _ONTAP_H
+
+#define PRIO_ONTAP "ontap"
+int prio_ontap(struct path * pp);
+
+#endif
Index: multipath-tools/multipath.conf.defaults
===================================================================
--- multipath-tools.orig/multipath.conf.defaults
+++ multipath-tools/multipath.conf.defaults
@@ -444,7 +444,7 @@
# rr_weight uniform
# rr_min_io 128
# path_checker directio
-# prio netapp
+# prio ontap
# }
# device {
# vendor "IBM"
@@ -458,7 +458,7 @@
# rr_weight uniform
# rr_min_io 128
# path_checker directio
-# prio netapp
+# prio ontap
# }
# device {
# vendor "Pillar"
Index: multipath-tools/multipath/multipath.conf.5
===================================================================
--- multipath-tools.orig/multipath/multipath.conf.5
+++ multipath-tools/multipath/multipath.conf.5
@@ -149,7 +149,7 @@ Generate the path priority for EMC array
.B mpath_prio_alua /dev/%n
Generate the path priority based on the SCSI-3 ALUA settings.
.TP
-.B mpath_prio_netapp /dev/%n
+.B mpath_prio_ontap /dev/%n
Generate the path priority for NetApp arrays.
.TP
.B mpath_prio_rdac /dev/%n

View File

@ -1,53 +0,0 @@
---
libmultipath/hwtable.c | 15 +++++++++++++++
multipath.conf.defaults | 13 +++++++++++++
2 files changed, 28 insertions(+)
Index: multipath-tools/libmultipath/hwtable.c
===================================================================
--- multipath-tools.orig/libmultipath/hwtable.c
+++ multipath-tools/libmultipath/hwtable.c
@@ -990,6 +990,21 @@ static struct hwentry default_hw[] = {
.checker_name = RDAC,
.prio_name = PRIO_RDAC,
},
+ {
+ .vendor = "EUROLOGC",
+ .product = "FC2502",
+ .getuid ="/lib/udev/scsi_id --page=0x80 --whitelisted --device=/dev/%n",
+ .features = DEFAULT_FEATURES,
+ .hwhandler = DEFAULT_HWHANDLER,
+ .selector = DEFAULT_SELECTOR,
+ .pgpolicy = GROUP_BY_PRIO,
+ .pgfailback = FAILBACK_UNDEF,
+ .rr_weight = RR_WEIGHT_NONE,
+ .no_path_retry = NO_PATH_RETRY_UNDEF,
+ .minio = DEFAULT_MINIO,
+ .checker_name = DEFAULT_CHECKER,
+ .prio_name = DEFAULT_PRIO,
+ },
/*
* EOL
*/
Index: multipath-tools/multipath.conf.defaults
===================================================================
--- multipath-tools.orig/multipath.conf.defaults
+++ multipath-tools/multipath.conf.defaults
@@ -602,4 +602,17 @@
# path_checker rdac
# prio rdac
# }
+# device {
+# vendor "EUROLOGC"
+# product "FC2502"
+# getuid_callout "/lib/udev/scsi_id --page=0x80 --whitelisted --device=/dev/%n"
+# features "0"
+# hardware_handler "0"
+# path_selector "round-robin 0"
+# path_grouping_policy group_by_prio
+# rr_weight uniform
+# rr_min_io 1000
+# path_checker directio
+# prio const
+# }
#}

View File

@ -1,135 +0,0 @@
---
libmultipath/config.h | 1 +
libmultipath/configure.c | 6 +++++-
libmultipath/file.c | 32 ++++++++++++++++++++++++++++++++
libmultipath/file.h | 1 +
multipath/main.c | 8 ++++++--
5 files changed, 45 insertions(+), 3 deletions(-)
Index: multipath-tools/libmultipath/config.h
===================================================================
--- multipath-tools.orig/libmultipath/config.h
+++ multipath-tools/libmultipath/config.h
@@ -87,6 +87,7 @@ struct config {
int fast_io_fail;
unsigned int dev_loss;
int find_multipaths;
+ int allow_queueing;
uid_t uid;
gid_t gid;
mode_t mode;
Index: multipath-tools/libmultipath/configure.c
===================================================================
--- multipath-tools.orig/libmultipath/configure.c
+++ multipath-tools/libmultipath/configure.c
@@ -36,6 +36,7 @@
#include "prio.h"
#include "util.h"
#include "finder.h"
+#include "file.h"
extern int
setup_map (struct multipath * mpp)
@@ -567,7 +568,10 @@ coalesce_paths (struct vectors * vecs, v
if (r == DOMAP_DRY)
continue;
- if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF) {
+ if (!conf->daemon && !conf->allow_queueing &&
+ !pidfile_check(DEFAULT_PIDFILE))
+ dm_queue_if_no_path(mpp->alias, 0);
+ else if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF) {
if (mpp->no_path_retry == NO_PATH_RETRY_FAIL)
dm_queue_if_no_path(mpp->alias, 0);
else
Index: multipath-tools/multipath/main.c
===================================================================
--- multipath-tools.orig/multipath/main.c
+++ multipath-tools/multipath/main.c
@@ -80,7 +80,7 @@ usage (char * progname)
{
fprintf (stderr, VERSION_STRING);
fprintf (stderr, "Usage:\n");
- fprintf (stderr, " %s [-c] [-d] [-r] [-v lvl] [-p pol] [-b fil] [dev]\n", progname);
+ fprintf (stderr, " %s [-c] [-d] [-r] [-v lvl] [-p pol] [-b fil] [-q] [dev]\n", progname);
fprintf (stderr, " %s -l|-ll|-f [-v lvl] [-b fil] [dev]\n", progname);
fprintf (stderr, " %s -F [-v lvl]\n", progname);
fprintf (stderr, " %s -h\n", progname);
@@ -93,6 +93,7 @@ usage (char * progname)
" -f flush a multipath device map\n" \
" -F flush all multipath device maps\n" \
" -c check if a device should be a path in a multipath device\n" \
+ " -q allow queue_if_no_path when multipathd is not running\n"\
" -d dry run, do not create or update devmaps\n" \
" -r force devmap reload\n" \
" -p policy failover|multibus|group_by_serial|group_by_prio\n" \
@@ -362,7 +363,7 @@ main (int argc, char *argv[])
condlog(0, "multipath tools need sysfs mounted");
exit(1);
}
- while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:r")) != EOF ) {
+ while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:rq")) != EOF ) {
switch(arg) {
case 1: printf("optarg : %s\n",optarg);
break;
@@ -379,6 +380,9 @@ main (int argc, char *argv[])
case 'c':
conf->dry_run = 2;
break;
+ case 'q':
+ conf->allow_queueing = 1;
+ break;
case 'd':
if (!conf->dry_run)
conf->dry_run = 1;
Index: multipath-tools/libmultipath/file.c
===================================================================
--- multipath-tools.orig/libmultipath/file.c
+++ multipath-tools/libmultipath/file.c
@@ -176,3 +176,35 @@ fail:
close(fd);
return -1;
}
+
+int pidfile_check(const char *file)
+{
+ int fd;
+ struct flock lock;
+
+ fd = open(file, O_RDONLY);
+ if (fd < 0) {
+ if (errno == ENOENT)
+ return 0;
+ condlog(0, "Cannot open pidfile, %s : %s", file,
+ strerror(errno));
+ return -1;
+ }
+ lock.l_type = F_WRLCK;
+ lock.l_start = 0;
+ lock.l_whence = SEEK_SET;
+ lock.l_len = 0;
+
+ if (fcntl(fd, F_GETLK, &lock) < 0) {
+ condlog(0, "Cannot check lock on pidfile, %s : %s", file,
+ strerror(errno));
+ return -1;
+ }
+ close(fd);
+ if (lock.l_type == F_UNLCK)
+ return 0;
+ return 1;
+}
+
+
+
Index: multipath-tools/libmultipath/file.h
===================================================================
--- multipath-tools.orig/libmultipath/file.h
+++ multipath-tools/libmultipath/file.h
@@ -7,5 +7,6 @@
#define FILE_TIMEOUT 30
int open_file(char *file, int *can_write, char *header);
+int pidfile_check(const char *file);
#endif /* _FILE_H */

View File

@ -1,141 +0,0 @@
---
libmultipath/dict.c | 12 ++++++++++++
libmultipath/print.c | 2 ++
libmultipath/structs.h | 3 ++-
multipathd/main.c | 31 +++++++++++++++++++++++++++++--
4 files changed, 45 insertions(+), 3 deletions(-)
Index: multipath-tools/libmultipath/dict.c
===================================================================
--- multipath-tools.orig/libmultipath/dict.c
+++ multipath-tools/libmultipath/dict.c
@@ -348,6 +348,8 @@ default_failback_handler(vector strvec)
conf->pgfailback = -FAILBACK_MANUAL;
else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
conf->pgfailback = -FAILBACK_IMMEDIATE;
+ else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
+ conf->pgfailback = -FAILBACK_FOLLOWOVER;
else
conf->pgfailback = atoi(buff);
@@ -917,6 +919,8 @@ hw_failback_handler(vector strvec)
hwe->pgfailback = -FAILBACK_MANUAL;
else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
hwe->pgfailback = -FAILBACK_IMMEDIATE;
+ else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
+ hwe->pgfailback = -FAILBACK_FOLLOWOVER;
else
hwe->pgfailback = atoi(buff);
@@ -1169,6 +1173,8 @@ mp_failback_handler(vector strvec)
mpe->pgfailback = -FAILBACK_MANUAL;
else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
mpe->pgfailback = -FAILBACK_IMMEDIATE;
+ else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
+ mpe->pgfailback = -FAILBACK_FOLLOWOVER;
else
mpe->pgfailback = atoi(buff);
@@ -1472,6 +1478,8 @@ snprint_mp_failback (char * buff, int le
return snprintf(buff, len, "manual");
case -FAILBACK_IMMEDIATE:
return snprintf(buff, len, "immediate");
+ case -FAILBACK_FOLLOWOVER:
+ return snprintf(buff, len, "followover");
default:
return snprintf(buff, len, "%i", mpe->pgfailback);
}
@@ -1748,6 +1756,8 @@ snprint_hw_failback (char * buff, int le
return snprintf(buff, len, "manual");
case -FAILBACK_IMMEDIATE:
return snprintf(buff, len, "immediate");
+ case -FAILBACK_FOLLOWOVER:
+ return snprintf(buff, len, "followover");
default:
return snprintf(buff, len, "%i", hwe->pgfailback);
}
@@ -1970,6 +1980,8 @@ snprint_def_failback (char * buff, int l
return snprintf(buff, len, "manual");
case -FAILBACK_IMMEDIATE:
return snprintf(buff, len, "immediate");
+ case -FAILBACK_FOLLOWOVER:
+ return snprintf(buff, len, "followover");
default:
return snprintf(buff, len, "%i", pgfailback);
}
Index: multipath-tools/libmultipath/print.c
===================================================================
--- multipath-tools.orig/libmultipath/print.c
+++ multipath-tools/libmultipath/print.c
@@ -142,6 +142,8 @@ snprint_failback (char * buff, size_t le
{
if (mpp->pgfailback == -FAILBACK_IMMEDIATE)
return snprintf(buff, len, "immediate");
+ if (mpp->pgfailback == -FAILBACK_FOLLOWOVER)
+ return snprintf(buff, len, "followover");
if (!mpp->failback_tick)
return snprintf(buff, len, "-");
Index: multipath-tools/libmultipath/structs.h
===================================================================
--- multipath-tools.orig/libmultipath/structs.h
+++ multipath-tools/libmultipath/structs.h
@@ -39,7 +39,8 @@ enum rr_weight_mode {
enum failback_mode {
FAILBACK_UNDEF,
FAILBACK_MANUAL,
- FAILBACK_IMMEDIATE
+ FAILBACK_IMMEDIATE,
+ FAILBACK_FOLLOWOVER
};
enum sysfs_buses {
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -875,6 +875,32 @@ mpvec_garbage_collector (struct vectors
}
}
+/* This is called after a path has started working again. It the multipath
+ * device for this path uses the followover failback type, and this is the
+ * best pathgroup, and this is the first path in the pathgroup to come back
+ * up, then switch to this pathgroup */
+static int
+followover_should_failback(struct path * pp)
+{
+ struct pathgroup * pgp;
+ struct path *pp1;
+ int i;
+
+ if (pp->mpp->pgfailback != -FAILBACK_FOLLOWOVER ||
+ !pp->mpp->pg || !pp->pgindex ||
+ pp->pgindex != pp->mpp->bestpg)
+ return 0;
+
+ pgp = VECTOR_SLOT(pp->mpp->pg, pp->pgindex - 1);
+ vector_foreach_slot(pgp->paths, pp1, i) {
+ if (pp1 == pp)
+ continue;
+ if (pp1->state != PATH_DOWN && pp1->state != PATH_SHAKY)
+ return 0;
+ }
+ return 1;
+}
+
static void
defered_failback_tick (vector mpvec)
{
@@ -1013,8 +1039,9 @@ check_path (struct vectors * vecs, struc
if (pp->mpp->pgfailback > 0)
pp->mpp->failback_tick =
pp->mpp->pgfailback + 1;
- else if (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE &&
- need_switch_pathgroup(pp->mpp, 1))
+ else if (need_switch_pathgroup(pp->mpp, 1) &&
+ (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE ||
+ followover_should_failback(pp)))
switch_pathgroup(pp->mpp);
/*

View File

@ -1,46 +0,0 @@
---
libmultipath/checkers.c | 5 +++++
libmultipath/checkers.h | 1 +
libmultipath/discovery.c | 1 +
3 files changed, 7 insertions(+)
Index: multipath-tools/libmultipath/discovery.c
===================================================================
--- multipath-tools.orig/libmultipath/discovery.c
+++ multipath-tools/libmultipath/discovery.c
@@ -807,6 +807,7 @@ get_state (struct path * pp, int daemon)
return PATH_UNCHECKED;
}
}
+ checker_clear_message(c);
if (path_offline(pp)) {
condlog(3, "%s: path offline", pp->dev);
return PATH_DOWN;
Index: multipath-tools/libmultipath/checkers.c
===================================================================
--- multipath-tools.orig/libmultipath/checkers.c
+++ multipath-tools/libmultipath/checkers.c
@@ -183,6 +183,11 @@ char * checker_message (struct checker *
return c->message;
}
+void checker_clear_message (struct checker *c)
+{
+ c->message[0] = '\0';
+}
+
void checker_get (struct checker * dst, char * name)
{
struct checker * src = checker_lookup(name);
Index: multipath-tools/libmultipath/checkers.h
===================================================================
--- multipath-tools.orig/libmultipath/checkers.h
+++ multipath-tools/libmultipath/checkers.h
@@ -117,6 +117,7 @@ int checker_check (struct checker *);
int checker_selected (struct checker *);
char * checker_name (struct checker *);
char * checker_message (struct checker *);
+void checker_clear_message (struct checker *c);
void checker_get (struct checker *, char *);
#endif /* _CHECKERS_H */

View File

@ -1,31 +0,0 @@
---
libmultipath/structs_vec.c | 2 +-
multipathd/main.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -1178,7 +1178,7 @@ configure (struct vectors * vecs, int st
/*
* create new set of maps & push changed ones into dm
*/
- if (coalesce_paths(vecs, mpvec, NULL, 0))
+ if (coalesce_paths(vecs, mpvec, NULL, 1))
return 1;
/*
Index: multipath-tools/libmultipath/structs_vec.c
===================================================================
--- multipath-tools.orig/libmultipath/structs_vec.c
+++ multipath-tools/libmultipath/structs_vec.c
@@ -355,7 +355,7 @@ retry:
goto out;
}
- //adopt_paths(vecs->pathvec, mpp);
+ adopt_paths(vecs->pathvec, mpp);
if (!mpp->hwe)
mpp->hwe = extract_hwe_from_path(mpp);
if (!mpp->hwe) {

View File

@ -1,61 +0,0 @@
---
libmultipath/hwtable.c | 34 ++++++++++++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
Index: multipath-tools/libmultipath/hwtable.c
===================================================================
--- multipath-tools.orig/libmultipath/hwtable.c
+++ multipath-tools/libmultipath/hwtable.c
@@ -455,6 +455,36 @@ static struct hwentry default_hw[] = {
.prio_name = PRIO_RDAC,
},
{
+ .vendor = "IBM",
+ .product = "1745",
+ .getuid = DEFAULT_GETUID,
+ .features = "2 pg_init_retries 50",
+ .hwhandler = "1 rdac",
+ .selector = DEFAULT_SELECTOR,
+ .pgpolicy = GROUP_BY_PRIO,
+ .pgfailback = -FAILBACK_IMMEDIATE,
+ .rr_weight = RR_WEIGHT_NONE,
+ .no_path_retry = 15,
+ .minio = DEFAULT_MINIO,
+ .checker_name = RDAC,
+ .prio_name = PRIO_RDAC,
+ },
+ {
+ .vendor = "IBM",
+ .product = "1746",
+ .getuid = DEFAULT_GETUID,
+ .features = "2 pg_init_retries 50",
+ .hwhandler = "1 rdac",
+ .selector = DEFAULT_SELECTOR,
+ .pgpolicy = GROUP_BY_PRIO,
+ .pgfailback = -FAILBACK_IMMEDIATE,
+ .rr_weight = RR_WEIGHT_NONE,
+ .no_path_retry = 15,
+ .minio = DEFAULT_MINIO,
+ .checker_name = RDAC,
+ .prio_name = PRIO_RDAC,
+ },
+ {
/* IBM DS4700 */
.vendor = "IBM",
.product = "1814",
@@ -853,13 +883,13 @@ static struct hwentry default_hw[] = {
.vendor = "SGI",
.product = "IS.*",
.getuid = DEFAULT_GETUID,
- .features = DEFAULT_FEATURES,
+ .features = "2 pg_init_retries 50",
.hwhandler = "1 rdac",
.selector = DEFAULT_SELECTOR,
.pgpolicy = GROUP_BY_PRIO,
.pgfailback = -FAILBACK_IMMEDIATE,
.rr_weight = RR_WEIGHT_NONE,
- .no_path_retry = NO_PATH_RETRY_QUEUE,
+ .no_path_retry = 15,
.minio = DEFAULT_MINIO,
.checker_name = RDAC,
.prio_name = PRIO_RDAC,

View File

@ -1,251 +0,0 @@
---
multipath/multipath.conf.5 | 148 +++++++++++++++++++++++++++++++++++++--------
1 file changed, 122 insertions(+), 26 deletions(-)
Index: multipath-tools/multipath/multipath.conf.5
===================================================================
--- multipath-tools.orig/multipath/multipath.conf.5
+++ multipath-tools/multipath/multipath.conf.5
@@ -76,6 +76,33 @@ default is
directory where udev creates its device nodes; default is
.I /dev
.TP
+.B multipath_dir
+directory where the dynamic shared objects are stored; default is system
+dependent, commonly
+.I /lib/multipath
+.TP
+.B find_multipaths
+If set to
+.I yes
+, instead of trying to create a multipath device for every non-blacklisted
+path, multipath will only create a device if one of three condidions are
+met.
+.I 1
+There are at least two non-blacklisted paths with the same wwid,
+.I 2
+the user manually forces the creation, by specifying a device with the multipath
+command, or
+.I 3
+a path has the same WWID as a multipath device that was previously created
+while find_multipaths was set (even if that multipath device doesn't currently
+exist).
+Whenever a multipath device is created with find_multipaths set, multipath will
+remeber the WWID of the device, so that it will automatically create the
+device again, as soon as it sees a path with that WWID. This should allow most
+users to have multipath automatically choose the correct paths to make into
+multipath devices, without having to edit the blacklist; Default is
+.I no
+.TP
.B verbosity
default verbosity. Higher values increase the verbosity level. Valid
levels are between 0 and 6; default is
@@ -130,39 +157,38 @@ identifier. Should be specified with an
is
.I /lib/udev/scsi_id --whitelisted --device=/dev/%n
.TP
-.B prio_callout
-The default program and args to callout to obtain a path priority
-value. The specified program will be executed and should return a
-numeric value specifying the relative priority of this path. Higher
-number have a higher priority. A '%n' in the command line will be expanded
-to the device name, a '%b' will be expanded to the device number in
-.I major:minor
-format.
-.I "none"
-is a valid value. Currently the following path priority programs are
-implemented:
+.B prio
+The default method used to obtain a path priority value. Possible
+values are
.RS
.TP 12
-.B mpath_prio_emc /dev/%n
+.B const
+Set a priority of one to all paths
+.TP
+.B emc
Generate the path priority for EMC arrays
.TP
-.B mpath_prio_alua /dev/%n
+.B alua
Generate the path priority based on the SCSI-3 ALUA settings.
.TP
-.B mpath_prio_ontap /dev/%n
+.B tpg_pref
+Generate the path prority based on the SCSI-3 ALUA settings, using
+the preferred port bit.
+.TP
+.B ontap
Generate the path priority for NetApp arrays.
.TP
-.B mpath_prio_rdac /dev/%n
+.B rdac
Generate the path priority for LSI/Engenio RDAC controller.
.TP
-.B mpath_prio_hp_sw /dev/%n
+.B hp_sw
Generate the path priority for Compaq/HP controller in
active/standby mode.
.TP
-.B mpath_prio_hds_modular %b
+.B hds
Generate the path priority for Hitachi HDS Modular storage arrays.
.TP
-Default value is \fBnone\fR.
+Default value is \fBconst\fR.
.RE
.TP
.B features
@@ -203,13 +229,26 @@ Default value is \fIreadsector0\fR.
.RE
.TP
.B failback
-Tell the daemon to manage path group failback, or not to. 0 or
-.I immediate
-means immediate failback, values >0 means deferred failback (in
-seconds).
-.I manual
-means no failback. Default value is
-.I manual
+Tell multipathd how to manage path group failback.
+.RS
+.TP 12
+.B immediate
+Immediately failback to the highest priority pathgroup that contains
+active paths.
+.TP
+.B manual
+Do not perform automatic failback.
+.TP
+.B followover
+Only perform automatic failback when the first path of a pathgroup
+becomes active. This keeps a node from automatically failing back when
+another node requested the failover.
+.TP
+.B values > 0
+deferred failback (time to defer in seconds)
+.TP
+Default value is \fImanual\fR.
+.RE
.TP
.B rr_min_io
The number of IO to route to a path before switching to the next in
@@ -245,6 +284,20 @@ be overriden by any specific aliases in
Default is
.I no
.TP
+.B queue_without_daemon
+If set to
+.I no
+, multipathd will disable queueing for all devices when it is shut down.
+Default is
+.I yes
+.TP
+.B flush_on_last_del
+If set to
+.I yes
+, multipathd will disable queueing when the last path to a device has been
+deleted. Default is
+.I no
+.TP
.B max_fds
Specify the maximum number of file descriptors that can be opened by multipath
and multipathd. This is equivalent to ulimit -n. A value of \fImax\fR will set
@@ -253,6 +306,11 @@ maximum number of open fds is taken from
1024. To be safe, this should be set to the maximum number of paths plus 32,
if that number is greated than 1024.
.TP
+.B checker_timeout
+Specify the timeout to user for path checkers that issue scsi commands with an
+explict timeout, in seconds; default taken from
+.I /sys/block/sd<x>/device/timeout
+.TP
.B fast_io_fail_tmo
Specify the number of seconds the scsi layer will wait after a problem has been
detected on a FC remote port before failing IO to devices on that remote port.
@@ -263,6 +321,18 @@ will disable the timeout.
.B dev_loss_tmo
Specify the number of seconds the scsi layer will wait after a problem has
been detected on a FC remote port before removing it from the system.
+.TP
+.B mode
+The mode to use for the multipath device nodes, in octal; default determined
+by the process
+.TP
+.B uid
+The user id to use for the multipath device nodes. You may use either the
+numeric or symbolic uid; default determined by the process.
+.TP
+.B gid
+The group id to use for the mutipath device nodes. You may use either the
+numeric or symbolic gid; default determined by the process.
.
.SH "blacklist section"
The
@@ -345,9 +415,21 @@ section:
.TP
.B failback
.TP
+.B prio
+.TP
.B no_path_retry
.TP
.B rr_min_io
+.TP
+.B rr_weight
+.TP
+.B flush_on_last_del
+.TP
+.B mode
+.TP
+.B uid
+.TP
+.B gid
.RE
.PD
.LP
@@ -368,6 +450,9 @@ subsection recognizes the following attr
.B product
(Mandatory) Product identifier
.TP
+.B revision
+Revision identifier
+.TP
.B product_blacklist
Product strings to blacklist for this vendor
.TP
@@ -378,6 +463,15 @@ The following hardware handler are imple
.TP 12
.B 1 emc
Hardware handler for EMC storage arrays.
+.TP
+.B 1 alua
+Hardware handler for SCSI-3 ALUA arrays.
+.TP
+.B 1 hp_sw
+Hardware handler for Compaq/HP controllers.
+.TP
+.B 1 rdac
+Hardware handler for the LSI/Engenio RDAC controllers.
.RE
.LP
The following attributes are optional; if not set the default values
@@ -398,7 +492,7 @@ section:
.TP
.B features
.TP
-.B prio_callout
+.B prio
.TP
.B failback
.TP
@@ -411,6 +505,8 @@ section:
.B fast_io_fail_tmo
.TP
.B dev_loss_tmo
+.TP
+.B flush_on_last_del
.RE
.PD
.LP

View File

@ -1,17 +0,0 @@
---
multipathd/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -63,7 +63,7 @@
#define CMDSIZE 160
#define LOG_MSG(a,b) \
- if (strlen(b)) condlog(a, "%s: %s", pp->dev, b);
+ if (strlen(b)) condlog(a, "%s: %s - %s", pp->mpp->alias, pp->dev, b);
pthread_cond_t exit_cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t exit_mutex = PTHREAD_MUTEX_INITIALIZER;

View File

@ -1,54 +0,0 @@
---
libmultipath/checkers/rdac.c | 32 ++++++++++++++++++++------------
1 file changed, 20 insertions(+), 12 deletions(-)
Index: multipath-tools/libmultipath/checkers/rdac.c
===================================================================
--- multipath-tools.orig/libmultipath/checkers/rdac.c
+++ multipath-tools/libmultipath/checkers/rdac.c
@@ -101,25 +101,33 @@ extern int
libcheck_check (struct checker * c)
{
struct volume_access_inq inq;
+ int ret;
memset(&inq, 0, sizeof(struct volume_access_inq));
if (0 != do_inq(c->fd, 0xC9, &inq, sizeof(struct volume_access_inq),
c->timeout)) {
- MSG(c, MSG_RDAC_DOWN);
- return PATH_DOWN;
- } else {
- if ((inq.PQ_PDT & 0x20) || (inq.PQ_PDT & 0x7f)) {
- /* LUN not connected*/
- return PATH_DOWN;
- }
+ ret = PATH_DOWN;
+ goto done;
+ } else if ((inq.PQ_PDT & 0x20) || (inq.PQ_PDT & 0x7f)) {
+ /* LUN not connected*/
+ ret = PATH_DOWN;
+ goto done;
}
- if (inq.avtcvp & 0x1) {
+ ret = ((inq.avtcvp & 0x1) ? PATH_UP : PATH_GHOST);
+
+done:
+ switch (ret) {
+ case PATH_DOWN:
+ MSG(c, MSG_RDAC_DOWN);
+ break;
+ case PATH_UP:
MSG(c, MSG_RDAC_UP);
- return PATH_UP;
- }
- else {
+ break;
+ case PATH_GHOST:
MSG(c, MSG_RDAC_GHOST);
- return PATH_GHOST;
+ break;
}
+
+ return ret;
}

View File

@ -1,17 +0,0 @@
---
libmultipath/discovery.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: multipath-tools/libmultipath/discovery.c
===================================================================
--- multipath-tools.orig/libmultipath/discovery.c
+++ multipath-tools/libmultipath/discovery.c
@@ -258,7 +258,7 @@ sysfs_set_scsi_tmo (struct multipath *mp
sprintf(value, "off");
else
snprintf(value, 11, "%u", mpp->fast_io_fail);
- if (sysfs_attr_set_value(attr_path, "fast_io_fail",
+ if (sysfs_attr_set_value(attr_path, "fast_io_fail_tmo",
value))
return 1;
}

View File

@ -1,16 +0,0 @@
---
libmultipath/sysfs.c | 1 +
1 file changed, 1 insertion(+)
Index: multipath-tools/libmultipath/sysfs.c
===================================================================
--- multipath-tools.orig/libmultipath/sysfs.c
+++ multipath-tools/libmultipath/sysfs.c
@@ -407,6 +407,7 @@ sysfs_attr_set_value(const char *devpath
path_full, ret);
ret = -1;
}
+ close(fd);
out:
return ret;
}

View File

@ -1,16 +0,0 @@
---
multipathd/main.c | 1 +
1 file changed, 1 insertion(+)
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -1242,6 +1242,7 @@ reconfigure (struct vectors * vecs)
conf->checkint = DEFAULT_CHECKINT;
conf->max_checkint = MAX_CHECKINT(conf->checkint);
}
+ conf->daemon = 1;
configure(vecs, 1);
free_config(old);
return 0;

View File

@ -1,25 +0,0 @@
---
libmultipath/dmparser.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
Index: multipath-tools/libmultipath/dmparser.c
===================================================================
--- multipath-tools.orig/libmultipath/dmparser.c
+++ multipath-tools/libmultipath/dmparser.c
@@ -13,6 +13,7 @@
#include "structs.h"
#include "util.h"
#include "debug.h"
+#include "config.h"
#define WORD_SIZE 64
@@ -286,7 +287,7 @@ disassemble_map (vector pathvec, char *
strncpy(pp->dev_t, word, BLK_DEV_SIZE);
/* Only call this in multipath client mode */
- if (!mpp->waiter && store_path(pathvec, pp))
+ if (!conf->daemon && store_path(pathvec, pp))
goto out1;
}
FREE(word);

View File

@ -1,24 +0,0 @@
---
libmultipath/structs_vec.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: multipath-tools/libmultipath/structs_vec.c
===================================================================
--- multipath-tools.orig/libmultipath/structs_vec.c
+++ multipath-tools/libmultipath/structs_vec.c
@@ -355,7 +355,6 @@ retry:
goto out;
}
- adopt_paths(vecs->pathvec, mpp);
if (!mpp->hwe)
mpp->hwe = extract_hwe_from_path(mpp);
if (!mpp->hwe) {
@@ -498,6 +497,7 @@ int update_multipath (struct vectors *ve
if (setup_multipath(vecs, mpp))
return 1; /* mpp freed in setup_multipath */
+ adopt_paths(vecs->pathvec, mpp);
/*
* compare checkers states with DM states
*/

View File

@ -1,52 +0,0 @@
---
multipathd/main.c | 20 ++++++--------------
1 file changed, 6 insertions(+), 14 deletions(-)
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -965,6 +965,7 @@ check_path (struct vectors * vecs, struc
{
int newstate;
int oldpriority;
+ int new_path_up = 0;
if (!pp->mpp)
return;
@@ -1033,16 +1034,7 @@ check_path (struct vectors * vecs, struc
else
reinstate_path(pp, 0);
- /*
- * schedule [defered] failback
- */
- if (pp->mpp->pgfailback > 0)
- pp->mpp->failback_tick =
- pp->mpp->pgfailback + 1;
- else if (need_switch_pathgroup(pp->mpp, 1) &&
- (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE ||
- followover_should_failback(pp)))
- switch_pathgroup(pp->mpp);
+ new_path_up = 1;
/*
* if at least one path is up in a group, and
@@ -1080,13 +1072,13 @@ check_path (struct vectors * vecs, struc
if (pp->priority != oldpriority &&
pp->mpp->pgpolicyfn == (pgpolicyfn *)group_by_prio)
update_path_groups(pp->mpp, vecs);
- else if (need_switch_pathgroup(pp->mpp, 0)) {
+ else if (need_switch_pathgroup(pp->mpp, new_path_up)) {
if (pp->mpp->pgfailback > 0 &&
- pp->mpp->failback_tick <= 0)
+ (new_path_up || pp->mpp->failback_tick <= 0))
pp->mpp->failback_tick =
pp->mpp->pgfailback + 1;
- else if (pp->mpp->pgfailback ==
- -FAILBACK_IMMEDIATE)
+ else if (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE ||
+ (new_path_up && followover_should_failback(pp)))
switch_pathgroup(pp->mpp);
}
}

View File

@ -1,114 +0,0 @@
---
libmultipath/config.c | 50 +++++++++++++++++++++++---------------------------
1 file changed, 23 insertions(+), 27 deletions(-)
Index: multipath-tools/libmultipath/config.c
===================================================================
--- multipath-tools.orig/libmultipath/config.c
+++ multipath-tools/libmultipath/config.c
@@ -24,33 +24,30 @@
static int
hwe_strmatch (struct hwentry *hwe1, struct hwentry *hwe2)
{
- if (hwe1->vendor && hwe2->vendor && strcmp(hwe1->vendor, hwe2->vendor))
+ if (hwe1->vendor) {
+ if (!hwe2->vendor || strcmp(hwe1->vendor, hwe2->vendor))
+ return 1;
+ }
+ else if (hwe2->vendor)
return 1;
- if (hwe1->product && hwe2->product && strcmp(hwe1->product, hwe2->product))
+ if (hwe1->product) {
+ if (!hwe2->product || strcmp(hwe1->product, hwe2->product))
+ return 1;
+ }
+ else if (hwe2->product)
return 1;
- if (hwe1->revision && hwe2->revision && strcmp(hwe1->revision, hwe2->revision))
+ if (hwe1->revision) {
+ if (!hwe2->revision || strcmp(hwe1->revision, hwe2->revision))
+ return 1;
+ }
+ else if (hwe2->revision)
return 1;
return 0;
}
-static struct hwentry *
-find_hwe_strmatch (vector hwtable, struct hwentry *hwe)
-{
- int i;
- struct hwentry *tmp, *ret = NULL;
-
- vector_foreach_slot (hwtable, tmp, i) {
- if (hwe_strmatch(tmp, hwe))
- continue;
- ret = tmp;
- break;
- }
- return ret;
-}
-
struct hwentry *
find_hwe (vector hwtable, char * vendor, char * product, char * revision)
{
@@ -264,15 +261,13 @@ set_param_str(char * str)
}
#define merge_str(s) \
- if (hwe2->s) { \
- if (hwe1->s) \
- FREE(hwe1->s); \
+ if (!hwe1->s && hwe2->s) { \
if (!(hwe1->s = set_param_str(hwe2->s))) \
return 1; \
}
#define merge_num(s) \
- if (hwe2->s) \
+ if (!hwe1->s && hwe2->s) \
hwe1->s = hwe2->s
@@ -295,6 +290,10 @@ merge_hwe (struct hwentry * hwe1, struct
merge_num(rr_weight);
merge_num(no_path_retry);
merge_num(minio);
+ merge_num(pg_timeout);
+ merge_num(flush_on_last_del);
+ merge_num(fast_io_fail);
+ merge_num(dev_loss);
return 0;
}
@@ -304,9 +303,6 @@ store_hwe (vector hwtable, struct hwentr
{
struct hwentry * hwe;
- if (find_hwe_strmatch(hwtable, dhwe))
- return 0;
-
if (!(hwe = alloc_hwe()))
return 1;
@@ -463,8 +459,6 @@ load_config (char * file)
if (!conf->hwtable)
goto out;
}
- if (setup_default_hwtable(conf->hwtable))
- goto out;
/*
* read the config file
@@ -494,6 +488,8 @@ load_config (char * file)
goto out;
}
}
+ if (setup_default_hwtable(conf->hwtable))
+ goto out;
/*
* remove duplica in hwtable. config file takes precedence
* over build-in hwtable

View File

@ -1,228 +0,0 @@
---
multipath/main.c | 4 -
multipath/mpathconf | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 121 insertions(+), 6 deletions(-)
Index: multipath-tools/multipath/mpathconf
===================================================================
--- multipath-tools.orig/multipath/mpathconf
+++ multipath-tools/multipath/mpathconf
@@ -27,10 +27,13 @@ function usage
echo "usage: $0 <command>"
echo ""
echo "Commands:"
- echo "Enable: --enable [--user_friendly_names <y|n>] [--find_multipaths <y|n>"
+ echo "Enable: --enable "
echo "Disable: --disable"
- echo "Set user_friendly_names: --user_friendly_names <y|n>"
- echo "Set find_multipaths: --find_multipaths <y|n>"
+ echo "Set user_friendly_names (Default n): --user_friendly_names <y|n>"
+ echo "Set find_multipaths (Default n): --find_multipaths <y|n>"
+ echo "Load the dm-multipath modules on enable (Default y): --with_module <y|n>"
+ echo "start/stop/reload multipathd (Default n): --with_multipathd <y|n>"
+ echo "chkconfig on/off multipathd (Default y): --with_chkconfig <y|n>"
echo ""
}
@@ -64,6 +67,33 @@ function parse_args
exit 1
fi
;;
+ --with_module)
+ if [ -n "$2" ]; then
+ MODULE=$2
+ shift 2
+ else
+ usage
+ exit 1
+ fi
+ ;;
+ --with_multipathd)
+ if [ -n "$2" ]; then
+ MULTIPATHD=$2
+ shift 2
+ else
+ usage
+ exit 1
+ fi
+ ;;
+ --with_chkconfig)
+ if [ -n "$2" ]; then
+ CHKCONFIG=$2
+ shift 2
+ else
+ usage
+ exit 1
+ fi
+ ;;
*)
usage
exit
@@ -73,10 +103,11 @@ function parse_args
function validate_args
{
- if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" ]; then
+ if [ "$ENABLE" = "0" ] && [ -n "$FRIENDLY" -o -n "$FIND" -o -n "$MODULE" ]; then
echo "ignoring extra parameters on disable"
FRIENDLY=""
FIND=""
+ MODULE=""
fi
if [ -n "$FRIENDLY" ] && [ "$FRIENDLY" != "y" -a "$FRIENDLY" != "n" ]; then
echo "--user_friendly_names must be either 'y' or 'n'"
@@ -89,6 +120,18 @@ function validate_args
if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" ]; then
DISPLAY=1
fi
+ if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then
+ echo "--with_module must be either 'y' or 'n'"
+ exit 1
+ fi
+ if [ -n "$MULTIPATHD" ] && [ "$MULTIPATHD" != "y" -a "$MULTIPATHD" != "n" ]; then
+ echo "--with_multipathd must be either 'y' or 'n'"
+ exit 1
+ fi
+ if [ -n "$CHKCONFIG" ] && [ "$CHKCONFIG" != "y" -a "$CHKCONFIG" != "n" ]; then
+ echo "--with_chkconfig must be either 'y' or 'n'"
+ exit 1
+ fi
}
umask 0077
@@ -119,6 +162,34 @@ if grep -q "^defaults[[:space:]]*{" $TMP
HAVE_DEFAULTS=1
fi
+if [ -z "$MODULE" -o "$MODULE" = "y" ]; then
+ if lsmod | grep -q "dm_multipath" ; then
+ HAVE_MODULE=1
+ else
+ HAVE_MODULE=0
+ fi
+fi
+
+if [ "$MULTIPATHD" = "y" ]; then
+ if service multipathd status > /dev/null ; then
+ HAVE_MULTIPATHD=1
+ else
+ HAVE_MULTIPATHD=0
+ fi
+fi
+
+if [ -z "$CHKCONFIG" -o "$CHKCONFIG" = "y" ]; then
+ chkconfig --list multipathd > /dev/null 2>&1
+ if [ $? != 0 ]; then
+ chkconfig --add multipathd
+ fi
+ if chkconfig --list multipathd | grep -q "on" ; then
+ HAVE_CHKCONFIG=1
+ else
+ HAVE_CHKCONFIG=0
+ fi
+fi
+
if [ "$HAVE_BLACKLIST" = "1" ]; then
if sed -n '/^blacklist[[:space:]]*{/,/^}/ p' $TMPFILE | grep -q "^[[:space:]]*devnode \"\.\?\*\"" ; then
HAVE_DISABLE=1
@@ -156,6 +227,23 @@ if [ -n "$DISPLAY" ]; then
else
echo "user_friendly_names is enabled"
fi
+ if [ -n "$HAVE_MODULE" ]; then
+ if [ "$HAVE_MODULE" = 1 ]; then
+ echo "dm_multipath module is loaded"
+ else
+ echo "dm_multipath module is not loaded"
+ fi
+ fi
+ if [ -n "$HAVE_MULTIPATHD" ]; then
+ service multipathd status
+ fi
+ if [ -n "$HAVE_CHKCONFIG" ]; then
+ if [ "$HAVE_CHKCONFIG" = 1 ]; then
+ echo "multipathd is chkconfiged on"
+ else
+ echo "multipathd is chkconfiged off"
+ fi
+ fi
exit 0
fi
@@ -192,28 +280,34 @@ fi
if [ "$FIND" = "n" ]; then
if [ "$HAVE_FIND" = 1 ]; then
sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(yes\|1\)/ find_multipaths no/' $TMPFILE
+ CHANGED_CONFIG=1
fi
elif [ "$FIND" = "y" ]; then
if [ -z "$HAVE_FIND" ]; then
sed -i '/^defaults[[:space:]]*{/ a\
find_multipaths yes
' $TMPFILE
+ CHANGED_CONFIG=1
elif [ "$HAVE_FIND" = 0 ]; then
sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*find_multipaths[[:space:]]*\(no\|0\)/ find_multipaths yes/' $TMPFILE
+ CHANGED_CONFIG=1
fi
fi
if [ "$FRIENDLY" = "n" ]; then
if [ "$HAVE_FRIENDLY" = 1 ]; then
sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(yes\|1\)/ user_friendly_names no/' $TMPFILE
+ CHANGED_CONFIG=1
fi
elif [ "$FRIENDLY" = "y" ]; then
if [ -z "$HAVE_FRIENDLY" ]; then
sed -i '/^defaults[[:space:]]*{/ a\
user_friendly_names yes
' $TMPFILE
+ CHANGED_CONFIG=1
elif [ "$HAVE_FRIENDLY" = 0 ]; then
sed -i '/^defaults[[:space:]]*{/,/^}/ s/^[[:space:]]*user_friendly_names[[:space:]]*\(no\|0\)/ user_friendly_names yes/' $TMPFILE
+ CHANGED_CONFIG=1
fi
fi
@@ -232,3 +326,24 @@ if [ $? != 0 ]; then
fi
rm -f $TMPFILE
+
+if [ "$ENABLE" = 1 ]; then
+ if [ "$HAVE_MODULE" = 0 ]; then
+ modprobe dm_multipath
+ fi
+ if [ "$HAVE_MULTIPATHD" = 0 ]; then
+ service multipathd start
+ fi
+ if [ "$HAVE_CHKCONFIG" = 0 ]; then
+ chkconfig multipathd on
+ fi
+elif [ "$ENABLE" = 0 ]; then
+ if [ "$HAVE_MULTIPATHD" = 1 ]; then
+ service multipathd stop
+ fi
+ if [ "$HAVE_CHKCONFIG" = 1 ]; then
+ chkconfig multipathd off
+ fi
+elif [ -n "$CHANGED_CONFIG" -a "$HAVE_MULTIPATHD" = 1 ]; then
+ service multipathd reload
+fi
Index: multipath-tools/multipath/main.c
===================================================================
--- multipath-tools.orig/multipath/main.c
+++ multipath-tools/multipath/main.c
@@ -345,10 +345,10 @@ main (int argc, char *argv[])
exit(1);
}
- if (dm_prereq())
+ if (load_config(DEFAULT_CONFIGFILE))
exit(1);
- if (load_config(DEFAULT_CONFIGFILE))
+ if (dm_prereq())
exit(1);
if (init_checkers()) {

View File

@ -1,17 +0,0 @@
---
libmultipath/discovery.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: multipath-tools/libmultipath/discovery.c
===================================================================
--- multipath-tools.orig/libmultipath/discovery.c
+++ multipath-tools/libmultipath/discovery.c
@@ -174,7 +174,7 @@ sysfs_get_timeout(struct sysfs_device *d
if (safe_sprintf(attr_path, "%s/device", dev->devpath))
return 1;
- attr = sysfs_attr_get_value(dev->devpath, "timeout");
+ attr = sysfs_attr_get_value(attr_path, "timeout");
if (!attr)
return 1;

View File

@ -1,154 +0,0 @@
---
multipath/Makefile | 3 +
multipath/mpathconf.8 | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 119 insertions(+)
Index: multipath-tools/multipath/mpathconf.8
===================================================================
--- /dev/null
+++ multipath-tools/multipath/mpathconf.8
@@ -0,0 +1,116 @@
+.TH MPATHCONF 8 "June 2010" "" "Linux Administrator's Manual"
+.SH NAME
+mpathconf - A tool for configuring device-mapper-multipath
+.SH SYNOPSIS
+.B mpathconf
+.RB [\| commands \|]
+.RB [\| options \|]
+.SH DESCRIPTION
+.B mpathconf
+is a utility that creates or modifies
+.B /etc/multipath.conf.
+It can enable or disable multipathing and configure some common options.
+.B mpathconf
+can also load the
+.B dm_multipath
+module, start and stop the
+.B multipathd
+daemon, and configure the
+.B multipathd
+service to start automatically or not. If
+.B mpathconf
+is called with no commands, it will display the current configuration.
+
+The default options for mpathconf are
+.B --with_module
+and
+.B --with_chkconfig.
+The
+.B --with_multipathd
+option is not set by default. Enabling multipathing will load the
+.B dm_multipath
+module and chkconfig
+.B multipathd
+to start on the next boot, but it will not immediately start it. This is so
+that users can manually edit their config file if necessary, before starting
+.B multipathd.
+
+If
+.B /etc/multipath.conf
+already exists, mpathconf will edit it. If it does not exist, mpathconf will
+use
+.B /usr/share/doc/device-mapper-multipath-0.4.9/multipath.conf
+as the starting file. This file has
+.B user_friendly_names
+set. If this file does not exist, mpathconf will create
+.B /etc/multipath.conf
+from scratch. For most users, this means that
+.B user_friendly_names
+will be set by default, unless they use the
+.B --user_friendly_names n
+command.
+.SH COMMANDS
+.TP
+.B --enable
+Removes any line that blacklists all device nodes from the
+.B /etc/multipath.conf
+blacklist section.
+.TP
+.B --disable
+Adds a line that blacklists all device nodes to the
+.B /etc/multipath.conf
+blacklist section. If no blacklist section exists, it will create one.
+.TP
+.B --user_friendly_name \fP { \fBy\fP | \fBn\fP }
+If set to \fBy\fP, this adds the line
+.B user_friendly_names yes
+to the
+.B /etc/multipath.conf
+defaults section. If set to \fBn\fP, this removes the line, if present. This
+command can be used along with any other command.
+.TP
+.B --find_multipaths\fP { \fBy\fP | \fBn\fP }
+If set to \fBy\fP, this adds the line
+.B find_multipaths yes
+to the
+.B /etc/multipath.conf
+defaults section. If set to \fBn\fP, this removes the line, if present. This
+command can be used aldong with any other command.
+.SH OPTIONS
+.TP
+.B --with_module\fP { \fBy\fP | \fBn\fP }
+If set to \fBy\fP, this runs
+.B modprobe dm_multipath
+to install the multipath modules. This option only works with the
+.B --enable
+command. This option is set to \fBy\fP by default.
+.TP
+.B --with_multipathd { \fBy\fP | \fBn\fP }
+If set to \fBy\fP, this runs
+.B service multipathd start
+to start the multipathd daemon on \fB--enable\fP,
+.B service multipathd stop
+to start the multipathd daemon on \fB--disable\fP, and
+.B service multipathd reload
+to reconfigure multipathd on \fB--user_frindly_names\fP and
+\fB--find_multipaths\fP.
+This option is set to \fBn\fP by default.
+.TP
+.B --with_chkconfig { \fBy\fP | \fBn\fP }
+If set to \fBy\fP, this runs
+.B chkconfig multipathd on
+to set multipathd to start automatically on \fB--enable\fP and
+.B chkconfig multipathd off
+to stop multipathd for starting automatically on \fB--disable\fP.
+This option is set to \fBy\fP by default.
+.SH FILES
+.BR /etc/multipath.conf
+.SH "SEE ALSO"
+.BR multipath.conf (5),
+.BR chkconfig (8),
+.BR modprobe (8),
+.BR multipath (8),
+.BR multipathd (8),
+.BR service (8),
+.SH AUTHOR
+Benjamin Marzinski <bmarzins@redhat.com>
Index: multipath-tools/multipath/Makefile
===================================================================
--- multipath-tools.orig/multipath/Makefile
+++ multipath-tools/multipath/Makefile
@@ -17,6 +17,7 @@ $(EXEC): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LDFLAGS)
$(GZIP) $(EXEC).8 > $(EXEC).8.gz
$(GZIP) $(EXEC).conf.5 > $(EXEC).conf.5.gz
+ $(GZIP) mpathconf.8 > mpathconf.8.gz
install:
$(INSTALL_PROGRAM) -d $(DESTDIR)$(bindir)
@@ -28,6 +29,7 @@ install:
$(INSTALL_PROGRAM) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
$(INSTALL_PROGRAM) -d $(DESTDIR)$(man5dir)
$(INSTALL_PROGRAM) -m 644 $(EXEC).conf.5.gz $(DESTDIR)$(man5dir)
+ $(INSTALL_PROGRAM) -m 644 mpathconf.8.gz $(DESTDIR)$(mandir)
uninstall:
rm $(DESTDIR)/lib/udev/rules.d/multipath.rules
@@ -35,6 +37,7 @@ uninstall:
rm $(DESTDIR)$(bindir)/mpathconf
rm $(DESTDIR)$(mandir)/$(EXEC).8.gz
rm $(DESTDIR)$(man5dir)/$(EXEC).conf.5.gz
+ rm $(DESTDIR)$(mandir)/mpathconf.8.gz
clean:
rm -f core *.o $(EXEC) *.gz

View File

@ -1,115 +0,0 @@
---
libmultipath/structs_vec.c | 42 ++++++++++++++++++++++++++----------------
libmultipath/structs_vec.h | 2 +-
multipathd/main.c | 2 +-
3 files changed, 28 insertions(+), 18 deletions(-)
Index: multipath-tools/libmultipath/structs_vec.c
===================================================================
--- multipath-tools.orig/libmultipath/structs_vec.c
+++ multipath-tools/libmultipath/structs_vec.c
@@ -45,8 +45,15 @@ update_mpp_paths(struct multipath * mpp,
return 0;
}
+/* Getting the pathinfo for paths we already have seems like a hack.
+ * It's necessary since sometimes a multipath device we get from the
+ * kernel conatains paths that aren't in our pathvector. In this case
+ * we need to add the paths just like any other, making sure
+ * that we only accept paths that are allowed by our configuration.
+ */
+
extern int
-adopt_paths (vector pathvec, struct multipath * mpp)
+adopt_paths (vector pathvec, struct multipath * mpp, int verify_all)
{
int i;
struct path * pp;
@@ -58,19 +65,22 @@ adopt_paths (vector pathvec, struct mult
return 1;
vector_foreach_slot (pathvec, pp, i) {
- if (!strncmp(mpp->wwid, pp->wwid, WWID_SIZE)) {
- condlog(3, "%s: ownership set to %s",
- pp->dev, mpp->alias);
- pp->mpp = mpp;
-
- if (!mpp->paths && !(mpp->paths = vector_alloc()))
- return 1;
-
- if (!find_path_by_dev(mpp->paths, pp->dev) &&
- store_path(mpp->paths, pp))
- return 1;
- pathinfo(pp, conf->hwtable, DI_PRIO | DI_CHECKER);
+ if (strncmp(mpp->wwid, pp->wwid, WWID_SIZE))
+ continue;
+ condlog(3, "%s: ownership set to %s", pp->dev, mpp->alias);
+ pp->mpp = mpp;
+
+ if (!mpp->paths && !(mpp->paths = vector_alloc()))
+ return 1;
+
+ if (find_path_by_dev(mpp->paths, pp->dev)) {
+ if (!verify_all)
+ continue;
}
+ else if (store_path(mpp->paths, pp))
+ return 1;
+
+ pathinfo(pp, conf->hwtable, DI_PRIO | DI_CHECKER);
}
return 0;
}
@@ -389,7 +399,7 @@ add_map_without_path (struct vectors * v
return NULL; /* mpp freed in setup_multipath */
}
- if (adopt_paths(vecs->pathvec, mpp))
+ if (adopt_paths(vecs->pathvec, mpp, 1))
goto out;
if (!vector_alloc_slot(vecs->mpvec))
@@ -422,7 +432,7 @@ add_map_with_path (struct vectors * vecs
select_alias(mpp);
mpp->size = pp->size;
- if (adopt_paths(vecs->pathvec, mpp))
+ if (adopt_paths(vecs->pathvec, mpp, 1))
goto out;
if (add_vec) {
@@ -497,7 +507,7 @@ int update_multipath (struct vectors *ve
if (setup_multipath(vecs, mpp))
return 1; /* mpp freed in setup_multipath */
- adopt_paths(vecs->pathvec, mpp);
+ adopt_paths(vecs->pathvec, mpp, 0);
/*
* compare checkers states with DM states
*/
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -413,7 +413,7 @@ rescan:
if (mpp) {
condlog(4,"%s: adopting all paths for path %s",
mpp->alias, pp->dev);
- if (adopt_paths(vecs->pathvec, mpp))
+ if (adopt_paths(vecs->pathvec, mpp, 1))
goto fail; /* leave path added to pathvec */
verify_paths(mpp, vecs, NULL);
Index: multipath-tools/libmultipath/structs_vec.h
===================================================================
--- multipath-tools.orig/libmultipath/structs_vec.h
+++ multipath-tools/libmultipath/structs_vec.h
@@ -15,7 +15,7 @@ struct vectors {
void set_no_path_retry(struct multipath *mpp);
-int adopt_paths (vector pathvec, struct multipath * mpp);
+int adopt_paths (vector pathvec, struct multipath * mpp, int verify_all);
void orphan_paths (vector pathvec, struct multipath * mpp);
void orphan_path (struct path * pp);

View File

@ -1,16 +0,0 @@
---
multipath/main.c | 1 +
1 file changed, 1 insertion(+)
Index: multipath-tools/multipath/main.c
===================================================================
--- multipath-tools.orig/multipath/main.c
+++ multipath-tools/multipath/main.c
@@ -203,6 +203,7 @@ get_dm_mpvec (vector curmp, vector pathv
if (!conf->dry_run)
reinstate_paths(mpp);
+ remember_wwid(mpp->wwid);
}
return 0;
}

View File

@ -1,41 +0,0 @@
---
multipath/multipath.rules | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
Index: multipath-tools/multipath/multipath.rules
===================================================================
--- multipath-tools.orig/multipath/multipath.rules
+++ multipath-tools/multipath/multipath.rules
@@ -1,19 +1,23 @@
# multipath wants the devmaps presented as meaninglful device names
# so name them after their devmap name
SUBSYSTEM!="block", GOTO="end_mpath"
-TEST!="/sbin/multipath", GOTO="check_usr"
-ENV{MPATH_GOT_HERE}="$env{DEVNAME}"
-PROGRAM=="/sbin/multipath -c /dev/$env{DEVNAME}", ENV{DM_MULTIPATH_DEVICE_PATH}="1"
-GOTO="skip_usr"
-LABEL="check_usr"
-ENV{MPATH_GOT_HERE} = "2"
-PROGRAM=="/usr/sbin/multipath -c /dev/$env{DEVNAME}", ENV{DM_MULTIPATH_DEVICE_PATH}="1"
-LABEL="skip_usr"
+
+ENV{MPATH_SBIN_PATH}="/sbin"
+TEST!="$env{MPATH_SBIN_PATH}/multipath", ENV{MPATH_SBIN_PATH}="/usr/sbin"
+
+ACTION=="add", ENV{DEVTYPE}!="partition", \
+ ENV{DM_MULTIPATH_DEVICE_PATH}!="1", \
+ PROGRAM=="$env{MPATH_SBIN_PATH}/multipath -c $tempnode", \
+ ENV{DM_MULTIPATH_DEVICE_PATH}="1"
+
+ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{DEVTYPE}!="partition", \
+ RUN+="/sbin/partx -d --nr 1-1024 $env{DEVNAME}"
+
RUN+="socket:/org/kernel/dm/multipath_event"
KERNEL!="dm-*", GOTO="end_mpath"
ACTION!="change", GOTO="end_mpath"
ENV{DM_SUSPENDED}=="1", GOTO="end_mpath"
ENV{DM_UUID}!="mpath-?*", GOTO="end_mpath"
ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath"
-RUN+="$env{DM_SBIN_PATH}/kpartx -a -p p $tempnode"
+RUN+="$env{MPATH_SBIN_PATH}/kpartx -a -p p $tempnode"
LABEL="end_mpath"

View File

@ -1,142 +0,0 @@
---
libmultipath/structs_vec.c | 18 ++++++++++--------
libmultipath/structs_vec.h | 6 ++++--
libmultipath/waiter.c | 2 +-
multipathd/cli_handlers.c | 14 +++++++++++---
4 files changed, 26 insertions(+), 14 deletions(-)
Index: multipath-tools/multipathd/cli_handlers.c
===================================================================
--- multipath-tools.orig/multipathd/cli_handlers.c
+++ multipath-tools/multipathd/cli_handlers.c
@@ -81,7 +81,8 @@ show_paths (char ** r, int * len, struct
}
int
-show_map_topology (char ** r, int * len, struct multipath * mpp)
+show_map_topology (char ** r, int * len, struct multipath * mpp,
+ struct vectors * vecs)
{
char * c;
char * reply;
@@ -90,6 +91,8 @@ show_map_topology (char ** r, int * len,
reply = MALLOC(maxlen);
+ if (update_multipath(vecs, mpp->alias, 0))
+ return 1;
while (again) {
if (!reply)
return 1;
@@ -127,9 +130,14 @@ show_maps_topology (char ** r, int * len
c = reply;
- vector_foreach_slot(vecs->mpvec, mpp, i)
+ vector_foreach_slot(vecs->mpvec, mpp, i) {
+ if (update_multipath(vecs, mpp->alias, 0)) {
+ i--;
+ continue;
+ }
c += snprint_multipath_topology(c, reply + maxlen - c,
mpp, 2);
+ }
again = ((c - reply) == (maxlen - 1));
@@ -244,7 +252,7 @@ cli_list_map_topology (void * v, char **
condlog(3, "list multipath %s (operator)", param);
- return show_map_topology(reply, len, mpp);
+ return show_map_topology(reply, len, mpp, vecs);
}
int
Index: multipath-tools/libmultipath/structs_vec.c
===================================================================
--- multipath-tools.orig/libmultipath/structs_vec.c
+++ multipath-tools/libmultipath/structs_vec.c
@@ -325,7 +325,7 @@ set_no_path_retry(struct multipath *mpp)
}
extern int
-setup_multipath (struct vectors * vecs, struct multipath * mpp)
+__setup_multipath (struct vectors * vecs, struct multipath * mpp, int reset)
{
retry:
if (dm_get_info(mpp->alias, &mpp->dmi)) {
@@ -371,11 +371,13 @@ retry:
condlog(3, "%s: no hardware entry found, using defaults",
mpp->alias);
}
- select_rr_weight(mpp);
- select_pgfailback(mpp);
- set_no_path_retry(mpp);
- select_pg_timeout(mpp);
- select_flush_on_last_del(mpp);
+ if (reset) {
+ select_rr_weight(mpp);
+ select_pgfailback(mpp);
+ set_no_path_retry(mpp);
+ select_pg_timeout(mpp);
+ select_flush_on_last_del(mpp);
+ }
return 0;
out:
@@ -487,7 +489,7 @@ verify_paths(struct multipath * mpp, str
return count;
}
-int update_multipath (struct vectors *vecs, char *mapname)
+int update_multipath (struct vectors *vecs, char *mapname, int reset)
{
struct multipath *mpp;
struct pathgroup *pgp;
@@ -504,7 +506,7 @@ int update_multipath (struct vectors *ve
free_pgvec(mpp->pg, KEEP_PATHS);
mpp->pg = NULL;
- if (setup_multipath(vecs, mpp))
+ if (__setup_multipath(vecs, mpp, reset))
return 1; /* mpp freed in setup_multipath */
adopt_paths(vecs->pathvec, mpp, 0);
Index: multipath-tools/libmultipath/structs_vec.h
===================================================================
--- multipath-tools.orig/libmultipath/structs_vec.h
+++ multipath-tools/libmultipath/structs_vec.h
@@ -21,7 +21,9 @@ void orphan_path (struct path * pp);
int verify_paths(struct multipath * mpp, struct vectors * vecs, vector rpvec);
int update_mpp_paths(struct multipath * mpp, vector pathvec);
-int setup_multipath (struct vectors * vecs, struct multipath * mpp);
+int __setup_multipath (struct vectors * vecs, struct multipath * mpp,
+ int reset);
+#define setup_multipath(vecs, mpp) __setup_multipath(vecs, mpp, 1)
int update_multipath_strings (struct multipath *mpp, vector pathvec);
void remove_map (struct multipath * mpp, struct vectors * vecs, int purge_vec);
@@ -33,7 +35,7 @@ struct multipath * add_map_without_path
int minor, char * alias);
struct multipath * add_map_with_path (struct vectors * vecs,
struct path * pp, int add_vec);
-int update_multipath (struct vectors *vecs, char *mapname);
+int update_multipath (struct vectors *vecs, char *mapname, int reset);
void update_queue_mode_del_path(struct multipath *mpp);
void update_queue_mode_add_path(struct multipath *mpp);
Index: multipath-tools/libmultipath/waiter.c
===================================================================
--- multipath-tools.orig/libmultipath/waiter.c
+++ multipath-tools/libmultipath/waiter.c
@@ -161,7 +161,7 @@ int waiteventloop (struct event_thread *
*/
pthread_cleanup_push(cleanup_lock, &waiter->vecs->lock);
lock(waiter->vecs->lock);
- r = update_multipath(waiter->vecs, waiter->mapname);
+ r = update_multipath(waiter->vecs, waiter->mapname, 1);
lock_cleanup_pop(waiter->vecs->lock);
if (r) {

View File

@ -1,91 +0,0 @@
Index: multipath-tools/multipath/main.c
===================================================================
--- multipath-tools.orig/multipath/main.c
+++ multipath-tools/multipath/main.c
@@ -22,6 +22,8 @@
* Copyright (c) 2005 Edward Goggin, EMC
*/
+#include <sys/types.h>
+#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
@@ -52,6 +54,7 @@
#include <sys/time.h>
#include <sys/resource.h>
#include <finder.h>
+#include "dev_t.h"
int logsink;
@@ -333,13 +336,29 @@ out:
return r;
}
+static int
+get_dev_type(char *dev) {
+ struct stat buf;
+ int i;
+
+ if (stat(dev, &buf) == 0 && S_ISBLK(buf.st_mode)) {
+ if (dm_is_dm_major(MAJOR(buf.st_rdev)))
+ return DEV_DEVMAP;
+ return DEV_DEVNODE;
+ }
+ else if (sscanf(dev, "%d:%d", &i, &i) == 2)
+ return DEV_DEVT;
+ else
+ return DEV_DEVMAP;
+}
+
int
main (int argc, char *argv[])
{
int arg;
extern char *optarg;
extern int optind;
- int i, r = 1;
+ int r = 1;
if (getuid() != 0) {
fprintf(stderr, "need to be root\n");
@@ -436,14 +455,7 @@ main (int argc, char *argv[])
goto out;
strncpy(conf->dev, argv[optind], FILE_NAME_SIZE);
-
- if (filepresent(conf->dev))
- conf->dev_type = DEV_DEVNODE;
- else if (sscanf(conf->dev, "%d:%d", &i, &i) == 2)
- conf->dev_type = DEV_DEVT;
- else
- conf->dev_type = DEV_DEVMAP;
-
+ conf->dev_type = get_dev_type(conf->dev);
}
conf->daemon = 0;
Index: multipath-tools/multipath/dev_t.h
===================================================================
--- multipath-tools.orig/multipath/dev_t.h
+++ multipath-tools/multipath/dev_t.h
@@ -1,15 +1,3 @@
-#define MINORBITS 20
-#define MINORMASK ((1U << MINORBITS) - 1)
-
-#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
-#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
-#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))
-
-#define print_dev_t(buffer, dev) \
- sprintf((buffer), "%u:%u\n", MAJOR(dev), MINOR(dev))
-
-#define format_dev_t(buffer, dev) \
- ({ \
- sprintf(buffer, "%u:%u", MAJOR(dev), MINOR(dev)); \
- buffer; \
- })
+#define MAJOR(dev) ((dev & 0xfff00) >> 8)
+#define MINOR(dev) ((dev & 0xff) | ((dev >> 12) & 0xfff00))
+#define MKDEV(ma,mi) ((mi & 0xff) | (ma << 8) | ((mi & ~0xff) << 12))

View File

@ -1,35 +0,0 @@
---
libmultipath/configure.c | 4 ++--
libmultipath/log.h | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
Index: multipath-tools/libmultipath/configure.c
===================================================================
--- multipath-tools.orig/libmultipath/configure.c
+++ multipath-tools/libmultipath/configure.c
@@ -193,8 +193,8 @@ select_action (struct multipath * mpp, v
return;
}
if (cmpp->size != mpp->size) {
- mpp->action = ACT_RELOAD;
- condlog(3, "%s: set ACT_RELOAD (size change)",
+ mpp->action = ACT_RESIZE;
+ condlog(3, "%s: set ACT_RESIZE (size change)",
mpp->alias);
return;
}
Index: multipath-tools/libmultipath/log.h
===================================================================
--- multipath-tools.orig/libmultipath/log.h
+++ multipath-tools/libmultipath/log.h
@@ -1,8 +1,8 @@
#ifndef LOG_H
#define LOG_H
-#define DEFAULT_AREA_SIZE 8192
-#define MAX_MSG_SIZE 128
+#define DEFAULT_AREA_SIZE 16384
+#define MAX_MSG_SIZE 256
#ifndef LOGLEVEL
#define LOGLEVEL 5

View File

@ -1,66 +0,0 @@
---
libmultipath/dmparser.c | 37 ++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
Index: multipath-tools/libmultipath/dmparser.c
===================================================================
--- multipath-tools.orig/libmultipath/dmparser.c
+++ multipath-tools/libmultipath/dmparser.c
@@ -6,6 +6,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include "checkers.h"
#include "vector.h"
@@ -44,6 +45,40 @@ merge_words (char ** dst, char * word, i
return 0;
}
+char *
+assemble_features (struct multipath *mp)
+{
+ static char features[PARAMS_SIZE];
+ unsigned int nr_features;
+ char *ptr;
+
+ if (!conf->daemon || mp->no_path_retry == NO_PATH_RETRY_UNDEF ||
+ mp->no_path_retry == NO_PATH_RETRY_FAIL ||
+ strstr(mp->features, "queue_if_no_path"))
+ return mp->features;
+ if (18 > PARAMS_SIZE - 1 - strlen(mp->features)) {
+ fprintf(stderr, "not enough size to modify features\n");
+ return mp->features;
+ }
+ if (sscanf(mp->features, "%u", &nr_features) != 1) {
+ fprintf(stderr, "can't find number of features\n");
+ return mp->features;
+ }
+ ptr = mp->features;
+ while (isspace(*ptr))
+ ptr++;
+ if (*ptr == '\0') {
+ fprintf(stderr, "features is empty\n");
+ return mp->features;
+ }
+ while(*ptr != '\0' && !isspace(*ptr))
+ ptr++;
+
+ snprintf(features, PARAMS_SIZE, "%u%s queue_if_no_path",
+ nr_features + 1, ptr);
+ return features;
+}
+
/*
* Transforms the path group vector into a proper device map string
*/
@@ -62,7 +97,7 @@ assemble_map (struct multipath * mp)
freechar = sizeof(mp->params);
shift = snprintf(p, freechar, "%s %s %i %i",
- mp->features, mp->hwhandler,
+ assemble_features(mp), mp->hwhandler,
VECTOR_SIZE(mp->pg), mp->bestpg);
if (shift >= freechar) {

View File

@ -1,68 +0,0 @@
---
libmultipath/discovery.c | 9 +++++++--
multipathd/main.c | 13 ++++++++++---
2 files changed, 17 insertions(+), 5 deletions(-)
Index: multipath-tools/libmultipath/discovery.c
===================================================================
--- multipath-tools.orig/libmultipath/discovery.c
+++ multipath-tools/libmultipath/discovery.c
@@ -794,8 +794,13 @@ get_state (struct path * pp, int daemon)
condlog(3, "%s: get_state", pp->dev);
if (!checker_selected(c)) {
- if (daemon)
- pathinfo(pp, conf->hwtable, DI_SYSFS);
+ if (daemon || pp->sysdev == NULL) {
+ if (pathinfo(pp, conf->hwtable, DI_SYSFS) != 0) {
+ condlog(3, "%s: couldn't get sysfs pathinfo",
+ pp->dev);
+ return PATH_UNCHECKED;
+ }
+ }
select_checker(pp);
if (!checker_selected(c)) {
condlog(3, "%s: No checker selected", pp->dev);
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -365,6 +365,7 @@ ev_add_path (char * devname, struct vect
struct multipath * mpp;
struct path * pp;
char empty_buff[WWID_SIZE] = {0};
+ int retries = 3;
if (strstr(devname, "..") != NULL) {
/*
@@ -450,12 +451,14 @@ rescan:
/*
* deal with asynchronous uevents :((
*/
- if (mpp->action == ACT_RELOAD) {
+ if (mpp->action == ACT_RELOAD && retries-- > 0) {
condlog(0, "%s: uev_add_path sleep", mpp->alias);
sleep(1);
update_mpp_paths(mpp, vecs->pathvec);
goto rescan;
}
+ else if (mpp->action == ACT_RELOAD)
+ condlog(0, "%s: giving up reload", mpp->alias);
else
goto fail_map;
}
@@ -473,8 +476,12 @@ rescan:
start_waiter_thread(mpp, vecs))
goto fail_map;
- condlog(2, "%s path added to devmap %s", devname, mpp->alias);
- return 0;
+ if (retries > 0) {
+ condlog(2, "%s path added to devmap %s", devname, mpp->alias);
+ return 0;
+ }
+ else
+ return 1;
fail_map:
remove_map(mpp, vecs, 1);

View File

@ -1,16 +0,0 @@
--- multipath-tools/multipathd/main.c 2010-06-18 09:44:59.000000000 +0200
+++ multipath-tools.new/multipathd/main.c 2010-06-18 10:21:41.000000000 +0200
@@ -317,11 +317,9 @@ ev_remove_map (char * devname, struct ve
if (!mpp) {
condlog(2, "%s: devmap not registered, can't remove",
devname);
- return 0;
+ return 1;
}
- flush_map(mpp, vecs);
-
- return 0;
+ return flush_map(mpp, vecs);
}
static int

View File

@ -1,77 +0,0 @@
diff -urp multipath-tools-0.4.9-23.el6-Snapshot8/libmultipath/discovery.c multipath-tools-0.4.9-23.el6-findrport/libmultipath/discovery.c
--- multipath-tools-0.4.9-23.el6-Snapshot8/libmultipath/discovery.c 2010-07-30 15:06:10.000000000 +0900
+++ multipath-tools-0.4.9-23.el6-findrport/libmultipath/discovery.c 2010-07-30 18:02:47.000000000 +0900
@@ -10,6 +10,7 @@
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
+#include <libgen.h>
#include "checkers.h"
#include "vector.h"
@@ -229,6 +230,41 @@ sysfs_get_fc_nodename (struct sysfs_devi
return 1;
}
+static int
+find_rport_id(struct path *pp)
+{
+ char attr_path[SYSFS_PATH_SIZE];
+ char *dir, *base;
+ int host, channel, rport_id = -1;
+
+ if (safe_sprintf(attr_path,
+ "/class/fc_transport/target%i:%i:%i",
+ pp->sg_id.host_no, pp->sg_id.channel,
+ pp->sg_id.scsi_id)) {
+ condlog(0, "attr_path too small for target");
+ return 1;
+ }
+
+ if (sysfs_resolve_link(attr_path, SYSFS_PATH_SIZE))
+ return -1;
+
+ condlog(4, "target%d:%d:%d -> path %s", pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.scsi_id, attr_path);
+ dir = attr_path;
+ do {
+ base = basename(dir);
+ dir = dirname(dir);
+
+ if (sscanf((const char *)base, "rport-%d:%d-%d", &host, &channel, &rport_id) == 3)
+ break;
+ } while (strcmp((const char *)dir, "/"));
+
+ if (rport_id < 0)
+ return -1;
+
+ condlog(4, "target%d:%d:%d -> rport_id %d", pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.scsi_id, rport_id);
+ return rport_id;
+}
+
int
sysfs_set_scsi_tmo (struct multipath *mpp)
{
@@ -236,15 +272,21 @@ sysfs_set_scsi_tmo (struct multipath *mp
struct path *pp;
int i;
char value[11];
+ int rport_id;
if (!mpp->dev_loss && !mpp->fast_io_fail)
return 0;
vector_foreach_slot(mpp->paths, pp, i) {
+ rport_id = find_rport_id(pp);
+ if (rport_id < 0) {
+ condlog(0, "failed to find rport_id for target%d:%d:%d", pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.scsi_id);
+ return 1;
+ }
if (safe_snprintf(attr_path, SYSFS_PATH_SIZE,
"/class/fc_remote_ports/rport-%d:%d-%d",
pp->sg_id.host_no, pp->sg_id.channel,
- pp->sg_id.scsi_id)) {
- condlog(0, "attr_path '/class/fc_remote_ports/rport-%d:%d-%d' too large", pp->sg_id.host_no, pp->sg_id.channel, pp->sg_id.scsi_id);
+ rport_id)) {
+ condlog(0, "attr_path '/class/fc_remote_ports/rport-%d:%d-%d' too large", pp->sg_id.host_no, pp->sg_id.channel, rport_id);
return 1;
}
if (mpp->dev_loss){

View File

@ -1,17 +0,0 @@
---
libmultipath/hwtable.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: multipath-tools/libmultipath/hwtable.c
===================================================================
--- multipath-tools.orig/libmultipath/hwtable.c
+++ multipath-tools/libmultipath/hwtable.c
@@ -221,7 +221,7 @@ static struct hwentry default_hw[] = {
.rr_weight = RR_WEIGHT_NONE,
.no_path_retry = 12,
.minio = DEFAULT_MINIO,
- .checker_name = CCISS_TUR,
+ .checker_name = TUR,
.prio_name = DEFAULT_PRIO,
},
/*

View File

@ -1,19 +0,0 @@
---
multipath/multipath.rules | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
Index: multipath-tools/multipath/multipath.rules
===================================================================
--- multipath-tools.orig/multipath/multipath.rules
+++ multipath-tools/multipath/multipath.rules
@@ -16,8 +16,9 @@ ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{
RUN+="socket:/org/kernel/dm/multipath_event"
KERNEL!="dm-*", GOTO="end_mpath"
ACTION!="change", GOTO="end_mpath"
-ENV{DM_SUSPENDED}=="1", GOTO="end_mpath"
+ENV{DM_UUID}=="mpath-?*|part[0-9]*-mpath-?*", OPTIONS+="link_priority=10"
ENV{DM_UUID}!="mpath-?*", GOTO="end_mpath"
+ENV{DM_SUSPENDED}=="1", GOTO="end_mpath"
ENV{DM_ACTION}=="PATH_FAILED", GOTO="end_mpath"
RUN+="$env{MPATH_SBIN_PATH}/kpartx -a -p p $tempnode"
LABEL="end_mpath"

View File

@ -1,13 +0,0 @@
Index: multipath-tools/libmultipath/alias.c
===================================================================
--- multipath-tools.orig/libmultipath/alias.c
+++ multipath-tools/libmultipath/alias.c
@@ -141,7 +141,7 @@ rlookup_binding(FILE *f, char **map_wwid
curr_id = scan_devname(alias);
if (curr_id >= id)
id = curr_id + 1;
- wwid = strtok(NULL, " \t");
+ wwid = strtok(NULL, "");
if (!wwid){
condlog(3,
"Ignoring malformed line %u in bindings file",

View File

@ -1,79 +0,0 @@
---
multipathd/main.c | 45 +++++++++++++++++++++++++++++++++++----------
1 file changed, 35 insertions(+), 10 deletions(-)
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -943,14 +943,41 @@ retry_count_tick(vector mpvec)
}
}
-int update_path_groups(struct multipath *mpp, struct vectors *vecs)
+int update_prio(struct path *pp, int refresh_all)
+{
+ int oldpriority;
+ struct pathgroup * pgp;
+ int i, j, changed = 0;
+
+ if (refresh_all) {
+ vector_foreach_slot (pp->mpp->pg, pgp, i) {
+ vector_foreach_slot (pgp->paths, pp, j) {
+ oldpriority = pp->priority;
+ pathinfo(pp, conf->hwtable, DI_PRIO);
+ if (pp->priority != oldpriority)
+ changed = 1;
+ }
+ }
+ return changed;
+ }
+ oldpriority = pp->priority;
+ pathinfo(pp, conf->hwtable, DI_PRIO);
+
+ if (pp->priority == oldpriority)
+ return 0;
+ return 1;
+}
+
+int update_path_groups(struct multipath *mpp, struct vectors *vecs, int refresh)
{
int i;
struct path * pp;
update_mpp_paths(mpp, vecs->pathvec);
- vector_foreach_slot (mpp->paths, pp, i)
- pathinfo(pp, conf->hwtable, DI_PRIO);
+ if (!refresh) {
+ vector_foreach_slot (mpp->paths, pp, i)
+ pathinfo(pp, conf->hwtable, DI_PRIO);
+ }
setup_map(mpp);
mpp->action = ACT_RELOAD;
if (domap(mpp) <= 0) {
@@ -969,7 +996,6 @@ void
check_path (struct vectors * vecs, struct path * pp)
{
int newstate;
- int oldpriority;
int new_path_up = 0;
if (!pp->mpp)
@@ -1072,12 +1098,11 @@ check_path (struct vectors * vecs, struc
* path prio refreshing
*/
condlog(4, "path prio refresh");
- oldpriority = pp->priority;
- pathinfo(pp, conf->hwtable, DI_PRIO);
- if (pp->priority != oldpriority &&
- pp->mpp->pgpolicyfn == (pgpolicyfn *)group_by_prio)
- update_path_groups(pp->mpp, vecs);
- else if (need_switch_pathgroup(pp->mpp, new_path_up)) {
+ if (update_prio(pp, new_path_up) &&
+ pp->mpp->pgpolicyfn == (pgpolicyfn *)group_by_prio &&
+ pp->mpp->pgfailback != -FAILBACK_FOLLOWOVER)
+ update_path_groups(pp->mpp, vecs, !new_path_up);
+ else if (need_switch_pathgroup(pp->mpp, 0)) {
if (pp->mpp->pgfailback > 0 &&
(new_path_up || pp->mpp->failback_tick <= 0))
pp->mpp->failback_tick =

View File

@ -1,35 +0,0 @@
---
multipath/mpathconf | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
Index: multipath-tools/multipath/mpathconf
===================================================================
--- multipath-tools.orig/multipath/mpathconf
+++ multipath-tools/multipath/mpathconf
@@ -17,6 +17,8 @@
# This program was largely ripped off from lvmconf
#
+unset ENABLE FIND FRIENDLY MODULE MULTIPATHD CHKCONFIG HAVE_DISABLE HAVE_FIND HAVE_BLACKLIST HAVE_DEFAULTS HAVE_FRIENDLY HAVE_MULTIPATHD HAVE_CHKCONFIG HAVE_MODULE SHOW_STATUS CHANGED_CONFIG
+
DEFAULT_CONFIGFILE="/usr/share/doc/device-mapper-multipath-0.4.9/multipath.conf"
CONFIGFILE="/etc/multipath.conf"
MULTIPATHDIR="/etc/multipath"
@@ -118,7 +120,7 @@ function validate_args
exit 1
fi
if [ -z "$ENABLE" -a -z "$FIND" -a -z "$FRIENDLY" ]; then
- DISPLAY=1
+ SHOW_STATUS=1
fi
if [ -n "$MODULE" ] && [ "$MODULE" != "y" -a "$MODULE" != "n" ]; then
echo "--with_module must be either 'y' or 'n'"
@@ -211,7 +213,7 @@ if [ "$HAVE_DEFAULTS" = "1" ]; then
fi
fi
-if [ -n "$DISPLAY" ]; then
+if [ -n "$SHOW_STATUS" ]; then
if [ -z "$HAVE_DISABLE" -o "$HAVE_DISABLE" = 0 ]; then
echo "multipath is enabled"
else

View File

@ -1,36 +0,0 @@
---
libmultipath/hwtable.c | 4 ++--
multipath.conf.defaults | 3 ++-
2 files changed, 4 insertions(+), 3 deletions(-)
Index: multipath-tools/libmultipath/hwtable.c
===================================================================
--- multipath-tools.orig/libmultipath/hwtable.c
+++ multipath-tools/libmultipath/hwtable.c
@@ -261,9 +261,9 @@ static struct hwentry default_hw[] = {
.pgpolicy = MULTIBUS,
.pgfailback = FAILBACK_UNDEF,
.rr_weight = RR_WEIGHT_NONE,
- .no_path_retry = NO_PATH_RETRY_UNDEF,
+ .no_path_retry = 6,
.minio = DEFAULT_MINIO,
- .checker_name = DIRECTIO,
+ .checker_name = TUR,
.prio_name = DEFAULT_PRIO,
},
{
Index: multipath-tools/multipath.conf.defaults
===================================================================
--- multipath-tools.orig/multipath.conf.defaults
+++ multipath-tools/multipath.conf.defaults
@@ -187,8 +187,9 @@
# path_selector "round-robin 0"
# path_grouping_policy multibus
# rr_weight uniform
+# no_path_retry 6
# rr_min_io 1000
-# path_checker directio
+# path_checker tur
# prio const
# }
# device {

View File

@ -1,89 +0,0 @@
---
libmultipath/hwtable.c | 34 ++++++++++++++++++++++++++++++++++
multipath.conf.defaults | 28 ++++++++++++++++++++++++++++
2 files changed, 62 insertions(+)
Index: multipath-tools/libmultipath/hwtable.c
===================================================================
--- multipath-tools.orig/libmultipath/hwtable.c
+++ multipath-tools/libmultipath/hwtable.c
@@ -717,6 +717,40 @@ static struct hwentry default_hw[] = {
.prio_name = DEFAULT_PRIO,
},
{
+ /* IBM 3303 NVDISK */
+ .vendor = "IBM",
+ .product = "3303 NVDISK",
+ .getuid = DEFAULT_GETUID,
+ .features = DEFAULT_FEATURES,
+ .hwhandler = DEFAULT_HWHANDLER,
+ .selector = DEFAULT_SELECTOR,
+ .pgpolicy = FAILOVER,
+ .pgfailback = -FAILBACK_IMMEDIATE,
+ .rr_weight = RR_WEIGHT_NONE,
+ .no_path_retry = (300 / DEFAULT_CHECKINT),
+ .minio = DEFAULT_MINIO,
+ .checker_name = TUR,
+ .prio_name = DEFAULT_PRIO,
+ .prio_args = NULL,
+ },
+ {
+ /* AIX NVDISK */
+ .vendor = "AIX",
+ .product = "NVDISK",
+ .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 = (300 / DEFAULT_CHECKINT),
+ .minio = DEFAULT_MINIO,
+ .checker_name = TUR,
+ .prio_name = PRIO_ALUA,
+ .prio_args = NULL,
+ },
+ {
/* DELL MD3000 */
.vendor = "DELL",
.product = "MD3000",
Index: multipath-tools/multipath.conf.defaults
===================================================================
--- multipath-tools.orig/multipath.conf.defaults
+++ multipath-tools/multipath.conf.defaults
@@ -474,6 +474,34 @@
# path_checker tur
# prio alua
# }
+# device {
+# vendor "IBM"
+# product "3303 NVDISK"
+# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
+# features "0"
+# hardware_handler "0"
+# path_grouping_policy failover
+# failback immediate
+# no_path_retry 60
+# rr_weight uniform
+# rr_min_io 1000
+# path_checker tur
+# }
+# device {
+# vendor "AIX"
+# product "NVDISK"
+# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
+# features "0"
+# hardware_handler "1 alua"
+# path_grouping_policy group_by_prio
+# failback immediate
+# no_path_retry 60
+# rr_weight uniform
+# rr_min_io 1000
+# path_checker tur
+# prio alua
+# prio_args ""
+# }
# device {
# vendor "SGI"
# product "TP9[13]00"

View File

@ -1,74 +0,0 @@
---
libmultipath/hwtable.c | 17 ++++++++++++++++-
multipath.conf.defaults | 16 +++++++++++++++-
2 files changed, 31 insertions(+), 2 deletions(-)
Index: multipath-tools/libmultipath/hwtable.c
===================================================================
--- multipath-tools.orig/libmultipath/hwtable.c
+++ multipath-tools/libmultipath/hwtable.c
@@ -224,6 +224,21 @@ static struct hwentry default_hw[] = {
.checker_name = TUR,
.prio_name = DEFAULT_PRIO,
},
+ {
+ .vendor = "HP",
+ .product = "OPEN-.*",
+ .getuid = DEFAULT_GETUID,
+ .features = DEFAULT_FEATURES,
+ .hwhandler = DEFAULT_HWHANDLER,
+ .selector = DEFAULT_SELECTOR,
+ .pgpolicy = MULTIBUS,
+ .pgfailback = FAILBACK_UNDEF,
+ .rr_weight = RR_WEIGHT_NONE,
+ .no_path_retry = 18,
+ .minio = DEFAULT_MINIO,
+ .checker_name = TUR,
+ .prio_name = DEFAULT_PRIO,
+ },
/*
* DDN controller family
*
@@ -325,7 +340,7 @@ static struct hwentry default_hw[] = {
* Mail : matthias.rudolph@hds.com
*/
{
- .vendor = "(HITACHI|HP)",
+ .vendor = "HITACHI",
.product = "OPEN-.*",
.getuid = DEFAULT_GETUID,
.features = DEFAULT_FEATURES,
Index: multipath-tools/multipath.conf.defaults
===================================================================
--- multipath-tools.orig/multipath.conf.defaults
+++ multipath-tools/multipath.conf.defaults
@@ -166,6 +166,20 @@
# prio const
# }
# device {
+# vendor "HP"
+# product "OPEN-.*"
+# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
+# features "0"
+# hardware_handler "0"
+# path_selector "round-robin 0"
+# path_grouping_policy multibus
+# rr_weight uniform
+# no_path_retry 18
+# rr_min_io 1000
+# path_checker tur
+# prio const
+# }
+# device {
# vendor "DDN"
# product "SAN DataDirector"
# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
@@ -238,7 +252,7 @@
# prio const
# }
# device {
-# vendor "(HITACHI|HP)"
+# vendor "HITACHI"
# product "OPEN-.*"
# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
# features "1 queue_if_no_path"

View File

@ -1,30 +0,0 @@
---
libmultipath/hwtable.c | 2 +-
multipath.conf.defaults | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
Index: multipath-tools/libmultipath/hwtable.c
===================================================================
--- multipath-tools.orig/libmultipath/hwtable.c
+++ multipath-tools/libmultipath/hwtable.c
@@ -349,7 +349,7 @@ static struct hwentry default_hw[] = {
.pgpolicy = MULTIBUS,
.pgfailback = FAILBACK_UNDEF,
.rr_weight = RR_WEIGHT_NONE,
- .no_path_retry = NO_PATH_RETRY_UNDEF,
+ .no_path_retry = 6,
.minio = DEFAULT_MINIO,
.checker_name = TUR,
.prio_name = DEFAULT_PRIO,
Index: multipath-tools/multipath.conf.defaults
===================================================================
--- multipath-tools.orig/multipath.conf.defaults
+++ multipath-tools/multipath.conf.defaults
@@ -260,6 +260,7 @@
# path_selector "round-robin 0"
# path_grouping_policy multibus
# rr_weight uniform
+# no_path_retry 6
# rr_min_io 100
# path_checker tur
# prio const

View File

@ -1,20 +0,0 @@
---
multipathd/cli.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
Index: multipath-tools/multipathd/cli.c
===================================================================
--- multipath-tools.orig/multipathd/cli.c
+++ multipath-tools/multipathd/cli.c
@@ -228,8 +228,10 @@ get_cmdvec (char * cmd, vector *v)
vector cmdvec, strvec;
strvec = alloc_strvec(cmd);
- if (!strvec)
+ if (!strvec) {
+ *v = NULL;
return 0;
+ }
cmdvec = vector_alloc();
*v = cmdvec;

View File

@ -1,34 +0,0 @@
---
libmultipath/discovery.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
Index: multipath-tools/libmultipath/discovery.c
===================================================================
--- multipath-tools.orig/libmultipath/discovery.c
+++ multipath-tools/libmultipath/discovery.c
@@ -289,12 +289,6 @@ sysfs_set_scsi_tmo (struct multipath *mp
condlog(0, "attr_path '/class/fc_remote_ports/rport-%d:%d-%d' too large", pp->sg_id.host_no, pp->sg_id.channel, rport_id);
return 1;
}
- if (mpp->dev_loss){
- snprintf(value, 11, "%u", mpp->dev_loss);
- if (sysfs_attr_set_value(attr_path, "dev_loss_tmo",
- value))
- return 1;
- }
if (mpp->fast_io_fail){
if (mpp->fast_io_fail == -1)
sprintf(value, "off");
@@ -304,6 +298,12 @@ sysfs_set_scsi_tmo (struct multipath *mp
value))
return 1;
}
+ if (mpp->dev_loss){
+ snprintf(value, 11, "%u", mpp->dev_loss);
+ if (sysfs_attr_set_value(attr_path, "dev_loss_tmo",
+ value))
+ return 1;
+ }
}
return 0;
}

View File

@ -1,157 +0,0 @@
---
libmultipath/alias.c | 14 ++++++++++----
libmultipath/callout.c | 5 ++++-
libmultipath/discovery.c | 7 +++++--
libmultipath/file.c | 14 ++++++++++----
libmultipath/finder.c | 7 +++++--
libmultipath/sysfs.c | 14 ++++++++++----
6 files changed, 44 insertions(+), 17 deletions(-)
Index: multipath-tools/libmultipath/callout.c
===================================================================
--- multipath-tools.orig/libmultipath/callout.c
+++ multipath-tools/libmultipath/callout.c
@@ -65,7 +65,10 @@ int execute_program(char *path, char *va
retval = pipe(fds);
if (retval != 0) {
- condlog(0, "error creating pipe for callout: %s", strerror(errno));
+ if (errno == EMFILE)
+ condlog(0, "out of file descriptors. set or increase max_fds in /etc/multipath.conf");
+ else
+ condlog(0, "error creating pipe for callout: %s", strerror(errno));
return -1;
}
Index: multipath-tools/libmultipath/discovery.c
===================================================================
--- multipath-tools.orig/libmultipath/discovery.c
+++ multipath-tools/libmultipath/discovery.c
@@ -945,8 +945,11 @@ pathinfo (struct path *pp, vector hwtabl
pp->fd = opennode(pp->dev, O_RDONLY);
if (pp->fd < 0) {
- condlog(4, "Couldn't open node for %s: %s",
- pp->dev, strerror(errno));
+ if (errno == EMFILE)
+ condlog(0, "out of file descriptors. set or increase max_fds in /etc/multipath.conf");
+ else
+ condlog(4, "Couldn't open node for %s: %s",
+ pp->dev, strerror(errno));
goto blank;
}
Index: multipath-tools/libmultipath/file.c
===================================================================
--- multipath-tools.orig/libmultipath/file.c
+++ multipath-tools/libmultipath/file.c
@@ -140,8 +140,11 @@ open_file(char *file, int *can_write, ch
}
}
else {
- condlog(0, "Cannot open file [%s] : %s", file,
- strerror(errno));
+ if (errno == EMFILE)
+ condlog(0, "out of file descriptors. set or increase max_fds in /etc/multipath.conf");
+ else
+ condlog(0, "Cannot open file [%s] : %s", file,
+ strerror(errno));
return -1;
}
}
@@ -186,8 +189,11 @@ int pidfile_check(const char *file)
if (fd < 0) {
if (errno == ENOENT)
return 0;
- condlog(0, "Cannot open pidfile, %s : %s", file,
- strerror(errno));
+ if (errno == EMFILE)
+ condlog(0, "out of file descriptors. set or increase max_fds in /etc/multipath.conf");
+ else
+ condlog(0, "Cannot open pidfile, %s : %s", file,
+ strerror(errno));
return -1;
}
lock.l_type = F_WRLCK;
Index: multipath-tools/libmultipath/sysfs.c
===================================================================
--- multipath-tools.orig/libmultipath/sysfs.c
+++ multipath-tools/libmultipath/sysfs.c
@@ -392,8 +392,11 @@ sysfs_attr_set_value(const char *devpath
fd = open(path_full, O_WRONLY);
if (fd < 0) {
- dbg("attribute '%s' can not be opened: %s",
- path_full, strerror(errno));
+ if (errno == EMFILE)
+ dbg("out of file descriptors. set or increase max_fds in /etc/multipath.conf");
+ else
+ dbg("attribute '%s' can not be opened: %s",
+ path_full, strerror(errno));
goto out;
}
value_len = strlen(value) + 1;
@@ -494,8 +497,11 @@ char *sysfs_attr_get_value(const char *d
/* read attribute value */
fd = open(path_full, O_RDONLY);
if (fd < 0) {
- dbg("attribute '%s' can not be opened: %s",
- path_full, strerror(errno));
+ if (errno == EMFILE)
+ dbg("out of file descriptors. set or increase max_fds in /etc/multipath.conf");
+ else
+ dbg("attribute '%s' can not be opened: %s",
+ path_full, strerror(errno));
goto out;
}
size = read(fd, value, sizeof(value));
Index: multipath-tools/libmultipath/alias.c
===================================================================
--- multipath-tools.orig/libmultipath/alias.c
+++ multipath-tools/libmultipath/alias.c
@@ -224,8 +224,11 @@ get_user_friendly_alias(char *wwid, char
scan_fd = dup(fd);
if (scan_fd < 0) {
- condlog(0, "Cannot dup bindings file descriptor : %s",
- strerror(errno));
+ if (errno == EMFILE)
+ condlog(0, "out of file descriptors. set or increase max_fds in /etc/multipath.conf");
+ else
+ condlog(0, "Cannot dup bindings file descriptor : %s",
+ strerror(errno));
close(fd);
return NULL;
}
@@ -274,8 +277,11 @@ get_user_friendly_wwid(char *alias, char
scan_fd = dup(fd);
if (scan_fd < 0) {
- condlog(0, "Cannot dup bindings file descriptor : %s",
- strerror(errno));
+ if (errno == EMFILE)
+ condlog(0, "out of file descriptors. set or increase max_fds in /etc/multipath.conf");
+ else
+ condlog(0, "Cannot dup bindings file descriptor : %s",
+ strerror(errno));
close(fd);
return NULL;
}
Index: multipath-tools/libmultipath/finder.c
===================================================================
--- multipath-tools.orig/libmultipath/finder.c
+++ multipath-tools/libmultipath/finder.c
@@ -89,8 +89,11 @@ check_wwids_file(char *wwid, int write_w
scan_fd = dup(fd);
if (scan_fd < 0) {
- condlog(0, "can't dup wwids file descriptor : %s",
- strerror(errno));
+ if (errno == EMFILE)
+ condlog(0, "out of file descriptors. set or increase max_fds in /etc/multipath.conf");
+ else
+ condlog(0, "can't dup wwids file descriptor : %s",
+ strerror(errno));
close(fd);
return -1;
}

View File

@ -1,31 +0,0 @@
---
multipathd/main.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -217,7 +217,7 @@ flush_map(struct multipath * mpp, struct
static int
uev_add_map (struct sysfs_device * dev, struct vectors * vecs)
{
- condlog(2, "%s: add map (uevent)", dev->kernel);
+ condlog(3, "%s: add map (uevent)", dev->kernel);
return ev_add_map(dev, vecs);
}
@@ -258,11 +258,12 @@ ev_add_map (struct sysfs_device * dev, s
* if we create a multipath mapped device as a result
* of uev_add_path
*/
- condlog(0, "%s: devmap already registered",
+ condlog(3, "%s: devmap already registered",
dev->kernel);
FREE(alias);
return 0;
}
+ condlog(0, "%s: adding map", dev->kernel);
/*
* now we can register the map

View File

@ -1,139 +0,0 @@
---
libmultipath/config.h | 1 +
libmultipath/dict.c | 27 +++++++++++++++++++++++++++
libmultipath/structs.h | 5 +++++
multipath/multipath.conf.5 | 9 +++++++++
multipathd/main.c | 13 ++++++++++---
5 files changed, 52 insertions(+), 3 deletions(-)
Index: multipath-tools/libmultipath/config.h
===================================================================
--- multipath-tools.orig/libmultipath/config.h
+++ multipath-tools/libmultipath/config.h
@@ -88,6 +88,7 @@ struct config {
unsigned int dev_loss;
int find_multipaths;
int allow_queueing;
+ int log_checker_err;
uid_t uid;
gid_t gid;
mode_t mode;
Index: multipath-tools/libmultipath/dict.c
===================================================================
--- multipath-tools.orig/libmultipath/dict.c
+++ multipath-tools/libmultipath/dict.c
@@ -490,6 +490,25 @@ def_find_multipaths_handler(vector strve
}
static int
+def_log_checker_err_handler(vector strvec)
+{
+ char * buff;
+
+ buff = set_value(strvec);
+
+ if (!buff)
+ return 1;
+
+ if (strlen(buff) == 4 && !strcmp(buff, "once"))
+ conf->log_checker_err = LOG_CHKR_ERR_ONCE;
+ else if (strlen(buff) == 6 && !strcmp(buff, "always"))
+ conf->log_checker_err = LOG_CHKR_ERR_ALWAYS;
+
+ free(buff);
+ return 0;
+}
+
+static int
names_handler(vector strvec)
{
char * buff;
@@ -2117,6 +2136,13 @@ snprint_def_find_multipaths (char * buff
return snprintf(buff, len, "yes");
}
+static int
+snprint_def_log_checker_err (char * buff, int len, void * data)
+{
+ if (conf->log_checker_err == LOG_CHKR_ERR_ONCE)
+ return snprintf(buff, len, "once");
+ return snprintf(buff, len, "always");
+}
static int
snprint_def_user_friendly_names (char * buff, int len, void * data)
@@ -2184,6 +2210,7 @@ init_keywords(void)
install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail);
install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss);
install_keyword("find_multipaths", &def_find_multipaths_handler, &snprint_def_find_multipaths);
+ install_keyword("log_checker_err", &def_log_checker_err_handler, &snprint_def_log_checker_err);
__deprecated install_keyword("default_selector", &def_selector_handler, NULL);
__deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
__deprecated install_keyword("default_getuid_callout", &def_getuid_callout_handler, NULL);
Index: multipath-tools/libmultipath/structs.h
===================================================================
--- multipath-tools.orig/libmultipath/structs.h
+++ multipath-tools/libmultipath/structs.h
@@ -88,6 +88,11 @@ enum flush_states {
FLUSH_IN_PROGRESS,
};
+enum log_checker_err_states {
+ LOG_CHKR_ERR_ALWAYS,
+ LOG_CHKR_ERR_ONCE,
+};
+
struct scsi_idlun {
int dev_id;
int host_unique_id;
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -63,7 +63,10 @@
#define CMDSIZE 160
#define LOG_MSG(a,b) \
- if (strlen(b)) condlog(a, "%s: %s - %s", pp->mpp->alias, pp->dev, b);
+do { \
+ if (strlen(b)) \
+ condlog(a, "%s: %s - %s", pp->mpp->alias, pp->dev, b); \
+} while(0)
pthread_cond_t exit_cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t exit_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -1090,8 +1093,12 @@ check_path (struct vectors * vecs, struc
condlog(4, "%s: delay next check %is",
pp->dev_t, pp->tick);
}
- else if (newstate == PATH_DOWN)
- LOG_MSG(2, checker_message(&pp->checker));
+ else if (newstate == PATH_DOWN) {
+ if (conf->log_checker_err == LOG_CHKR_ERR_ONCE)
+ LOG_MSG(3, checker_message(&pp->checker));
+ else
+ LOG_MSG(2, checker_message(&pp->checker));
+ }
pp->state = newstate;
Index: multipath-tools/multipath/multipath.conf.5
===================================================================
--- multipath-tools.orig/multipath/multipath.conf.5
+++ multipath-tools/multipath/multipath.conf.5
@@ -333,6 +333,15 @@ numeric or symbolic uid; default determi
.B gid
The group id to use for the mutipath device nodes. You may use either the
numeric or symbolic gid; default determined by the process.
+.TP
+.B log_checker_err
+If set to
+.I once
+, multipathd logs the first path checker error at logging level 2. Any later
+errors are logged at level 3 until the device is restored. If set to
+.I always
+, multipathd always logs the path checker error at logging level 2. Default is
+.I always
.
.SH "blacklist section"
The

View File

@ -1,18 +0,0 @@
---
multipath/multipath.conf.5 | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
Index: multipath-tools/multipath/multipath.conf.5
===================================================================
--- multipath-tools.orig/multipath/multipath.conf.5
+++ multipath-tools/multipath/multipath.conf.5
@@ -40,7 +40,8 @@ The following \fIsection\fP keywords are
.TP 17
.B defaults
This section defines default values for attributes which are used
-whenever no specific setting is given.
+whenever no specific setting is given in the appropriate device or
+multipath sections.
.TP
.B blacklist
This section defines which devices should be excluded from the

View File

@ -1,49 +0,0 @@
---
libmultipath/hwtable.c | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
Index: multipath-tools/libmultipath/hwtable.c
===================================================================
--- multipath-tools.orig/libmultipath/hwtable.c
+++ multipath-tools/libmultipath/hwtable.c
@@ -766,6 +766,40 @@ static struct hwentry default_hw[] = {
.prio_args = NULL,
},
{
+ /* IBM 3303 NVDISK */
+ .vendor = "IBM",
+ .product = "3303 NVDISK",
+ .getuid = DEFAULT_GETUID,
+ .features = DEFAULT_FEATURES,
+ .hwhandler = DEFAULT_HWHANDLER,
+ .selector = DEFAULT_SELECTOR,
+ .pgpolicy = FAILOVER,
+ .pgfailback = -FAILBACK_IMMEDIATE,
+ .rr_weight = RR_WEIGHT_NONE,
+ .no_path_retry = (300 / DEFAULT_CHECKINT),
+ .minio = DEFAULT_MINIO,
+ .checker_name = TUR,
+ .prio_name = DEFAULT_PRIO,
+ .prio_args = NULL,
+ },
+ {
+ /* AIX NVDISK */
+ .vendor = "AIX",
+ .product = "NVDISK",
+ .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 = (300 / DEFAULT_CHECKINT),
+ .minio = DEFAULT_MINIO,
+ .checker_name = TUR,
+ .prio_name = PRIO_ALUA,
+ .prio_args = NULL,
+ },
+ {
/* DELL MD3000 */
.vendor = "DELL",
.product = "MD3000",

View File

@ -1,248 +0,0 @@
---
libmultipath/dict.c | 16 +++++------
libmultipath/parser.c | 69 +++++++++++++++++++++++++++++++++++++++++++++-----
libmultipath/parser.h | 9 ++++--
3 files changed, 77 insertions(+), 17 deletions(-)
Index: multipath-tools/libmultipath/dict.c
===================================================================
--- multipath-tools.orig/libmultipath/dict.c
+++ multipath-tools/libmultipath/dict.c
@@ -2218,17 +2218,17 @@ init_keywords(void)
__deprecated install_keyword("default_path_checker", &def_path_checker_handler, NULL);
install_keyword_root("blacklist", &blacklist_handler);
- install_keyword("devnode", &ble_devnode_handler, &snprint_ble_simple);
- install_keyword("wwid", &ble_wwid_handler, &snprint_ble_simple);
- install_keyword("device", &ble_device_handler, NULL);
+ install_keyword_multi("devnode", &ble_devnode_handler, &snprint_ble_simple);
+ install_keyword_multi("wwid", &ble_wwid_handler, &snprint_ble_simple);
+ install_keyword_multi("device", &ble_device_handler, NULL);
install_sublevel();
install_keyword("vendor", &ble_vendor_handler, &snprint_bled_vendor);
install_keyword("product", &ble_product_handler, &snprint_bled_product);
install_sublevel_end();
install_keyword_root("blacklist_exceptions", &blacklist_exceptions_handler);
- install_keyword("devnode", &ble_except_devnode_handler, &snprint_ble_simple);
- install_keyword("wwid", &ble_except_wwid_handler, &snprint_ble_simple);
- install_keyword("device", &ble_except_device_handler, NULL);
+ install_keyword_multi("devnode", &ble_except_devnode_handler, &snprint_ble_simple);
+ install_keyword_multi("wwid", &ble_except_wwid_handler, &snprint_ble_simple);
+ install_keyword_multi("device", &ble_except_device_handler, NULL);
install_sublevel();
install_keyword("vendor", &ble_except_vendor_handler, &snprint_bled_vendor);
install_keyword("product", &ble_except_product_handler, &snprint_bled_product);
@@ -2246,7 +2246,7 @@ init_keywords(void)
#endif
install_keyword_root("devices", &devices_handler);
- install_keyword("device", &device_handler, NULL);
+ install_keyword_multi("device", &device_handler, NULL);
install_sublevel();
install_keyword("vendor", &vendor_handler, &snprint_hw_vendor);
install_keyword("product", &product_handler, &snprint_hw_product);
@@ -2271,7 +2271,7 @@ init_keywords(void)
install_sublevel_end();
install_keyword_root("multipaths", &multipaths_handler);
- install_keyword("multipath", &multipath_handler, NULL);
+ install_keyword_multi("multipath", &multipath_handler, NULL);
install_sublevel();
install_keyword("wwid", &wwid_handler, &snprint_mp_wwid);
install_keyword("alias", &alias_handler, &snprint_mp_alias);
Index: multipath-tools/libmultipath/parser.c
===================================================================
--- multipath-tools.orig/libmultipath/parser.c
+++ multipath-tools/libmultipath/parser.c
@@ -21,11 +21,13 @@
#include "parser.h"
#include "memory.h"
+#include "debug.h"
/* local vars */
static int sublevel = 0;
vector keywords = NULL;
vector *keywords_addr = NULL;
+static int line_nr;
void set_current_keywords (vector *k)
{
@@ -35,7 +37,7 @@ void set_current_keywords (vector *k)
int
keyword_alloc(vector keywords, char *string, int (*handler) (vector),
- int (*print) (char *, int, void *))
+ int (*print) (char *, int, void *), int unique)
{
struct keyword *keyword;
@@ -51,6 +53,7 @@ keyword_alloc(vector keywords, char *str
keyword->string = string;
keyword->handler = handler;
keyword->print = print;
+ keyword->unique = unique;
vector_set_slot(keywords, keyword);
@@ -60,7 +63,7 @@ keyword_alloc(vector keywords, char *str
int
install_keyword_root(char *string, int (*handler) (vector))
{
- int r = keyword_alloc(keywords, string, handler, NULL);
+ int r = keyword_alloc(keywords, string, handler, NULL, 1);
if (!r)
*keywords_addr = keywords;
return r;
@@ -79,8 +82,8 @@ install_sublevel_end(void)
}
int
-install_keyword(char *string, int (*handler) (vector),
- int (*print) (char *, int, void *))
+_install_keyword(char *string, int (*handler) (vector),
+ int (*print) (char *, int, void *), int unique)
{
int i = 0;
struct keyword *keyword;
@@ -101,7 +104,7 @@ install_keyword(char *string, int (*hand
return 1;
/* add new sub keyword */
- return keyword_alloc(keyword->sub, string, handler, print);
+ return keyword_alloc(keyword->sub, string, handler, print, unique);
}
void
@@ -419,6 +422,39 @@ set_value(vector strvec)
/* non-recursive configuration stream handler */
static int kw_level = 0;
+
+int warn_on_duplicates(vector uniques, char *str)
+{
+ char *tmp;
+ int i;
+
+ vector_foreach_slot(uniques, tmp, i) {
+ if (!strcmp(str, tmp)) {
+ condlog(1, "multipath.conf line %d, duplicate keyword: %s", line_nr, str);
+ return 0;
+ }
+ }
+ tmp = strdup(str);
+ if (!tmp)
+ return 1;
+ if (!vector_alloc_slot(uniques)) {
+ free(tmp);
+ return 1;
+ }
+ vector_set_slot(uniques, tmp);
+ return 0;
+}
+
+void free_uniques(vector uniques)
+{
+ char *tmp;
+ int i;
+
+ vector_foreach_slot(uniques, tmp, i)
+ free(tmp);
+ vector_free(uniques);
+}
+
int
process_stream(vector keywords)
{
@@ -428,13 +464,21 @@ process_stream(vector keywords)
char *str;
char *buf;
vector strvec;
+ vector uniques;
+
+ uniques = vector_alloc();
+ if (!uniques)
+ return 1;
buf = MALLOC(MAXBUF);
- if (!buf)
+ if (!buf) {
+ vector_free(uniques);
return 1;
+ }
while (read_line(buf, MAXBUF)) {
+ line_nr++;
strvec = alloc_strvec(buf);
memset(buf,0, MAXBUF);
@@ -452,6 +496,12 @@ process_stream(vector keywords)
keyword = VECTOR_SLOT(keywords, i);
if (!strcmp(keyword->string, str)) {
+ if (keyword->unique &&
+ warn_on_duplicates(uniques, str)) {
+ r = 1;
+ free_strvec(strvec);
+ goto out;
+ }
if (keyword->handler)
r += (*keyword->handler) (strvec);
@@ -463,11 +513,17 @@ process_stream(vector keywords)
break;
}
}
+ if (i >= VECTOR_SIZE(keywords))
+ condlog(1,
+ "multipath.conf line %d, invalid keyword: %s",
+ line_nr, str);
free_strvec(strvec);
}
+out:
FREE(buf);
+ free_uniques(uniques);
return r;
}
@@ -496,6 +552,7 @@ init_data(char *conf_file, void (*init_k
*/
/* Stream handling */
+ line_nr = 0;
r = process_stream(keywords);
fclose(stream);
//free_keywords(keywords);
Index: multipath-tools/libmultipath/parser.h
===================================================================
--- multipath-tools.orig/libmultipath/parser.h
+++ multipath-tools/libmultipath/parser.h
@@ -44,6 +44,7 @@ struct keyword {
int (*handler) (vector);
int (*print) (char *, int, void *);
vector sub;
+ int unique;
};
/* global var exported */
@@ -60,12 +61,14 @@ FILE *stream;
/* Prototypes */
extern int keyword_alloc(vector keywords, char *string, int (*handler) (vector),
- int (*print) (char *, int, void *));
+ int (*print) (char *, int, void *), int unique);
extern int install_keyword_root(char *string, int (*handler) (vector));
extern void install_sublevel(void);
extern void install_sublevel_end(void);
-extern int install_keyword(char *string, int (*handler) (vector),
- int (*print) (char *, int, void *));
+extern int _install_keyword(char *string, int (*handler) (vector),
+ int (*print) (char *, int, void *), int unique);
+#define install_keyword(str, vec, pri) _install_keyword(str, vec, pri, 1)
+#define install_keyword_multi(str, vec, pri) _install_keyword(str, vec, pri, 0)
extern void dump_keywords(vector keydump, int level);
extern void free_keywords(vector keywords);
extern vector alloc_strvec(char *string);

View File

@ -1,55 +0,0 @@
---
libmultipath/discovery.c | 19 ++++++++++++++++++-
libmultipath/structs.h | 2 +-
2 files changed, 19 insertions(+), 2 deletions(-)
Index: multipath-tools/libmultipath/discovery.c
===================================================================
--- multipath-tools.orig/libmultipath/discovery.c
+++ multipath-tools/libmultipath/discovery.c
@@ -212,6 +212,7 @@ sysfs_get_fc_nodename (struct sysfs_devi
unsigned int host, unsigned int channel,
unsigned int target)
{
+ unsigned int checkhost, session;
char attr_path[SYSFS_PATH_SIZE], *attr;
if (safe_sprintf(attr_path,
@@ -223,7 +224,23 @@ sysfs_get_fc_nodename (struct sysfs_devi
attr = sysfs_attr_get_value(attr_path, "node_name");
if (attr) {
- strlcpy(node, attr, strlen(attr));
+ strncpy(node, attr, strlen(attr));
+ return 0;
+ }
+
+ if (sscanf(dev->devpath, "/devices/platform/host%u/session%u/",
+ &checkhost, &session) != 2)
+ return 1;
+ if (checkhost != host)
+ return 1;
+ if (safe_sprintf(attr_path, "/devices/platform/host%u/session%u/iscsi_session/session%u", host, session, session)) {
+ condlog(0, "attr_path too small");
+ return 1;
+ }
+
+ attr = sysfs_attr_get_value(attr_path, "targetname");
+ if (attr) {
+ strncpy(node, attr, strlen(attr));
return 0;
}
Index: multipath-tools/libmultipath/structs.h
===================================================================
--- multipath-tools.orig/libmultipath/structs.h
+++ multipath-tools/libmultipath/structs.h
@@ -5,7 +5,7 @@
#define WWID_SIZE 128
#define SERIAL_SIZE 64
-#define NODE_NAME_SIZE 19
+#define NODE_NAME_SIZE 224
#define PATH_STR_SIZE 16
#define PARAMS_SIZE 1024
#define FILE_NAME_SIZE 256

View File

@ -1,31 +0,0 @@
---
libmultipath/parser.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
Index: multipath-tools/libmultipath/parser.c
===================================================================
--- multipath-tools.orig/libmultipath/parser.c
+++ multipath-tools/libmultipath/parser.c
@@ -386,13 +386,20 @@ alloc_value_block(vector strvec, void (*
void *
set_value(vector strvec)
{
- char *str = VECTOR_SLOT(strvec, 1);
- int size = strlen(str);
+ char *str;
+ int size;
int i = 0;
int len = 0;
char *alloc = NULL;
char *tmp;
+ str = VECTOR_SLOT(strvec, 1);
+ if (!str) {
+ str = VECTOR_SLOT(strvec, 0);
+ condlog(0, "option '%s' missing value\n", str);
+ return NULL;
+ }
+ size = strlen(str);
if (*str == '"') {
for (i = 2; i < VECTOR_SIZE(strvec); i++) {
str = VECTOR_SLOT(strvec, i);

View File

@ -1,376 +0,0 @@
---
libmultipath/discovery.c | 50 ++++++---------------
libmultipath/sysfs.c | 108 ++++++++++++++++++-----------------------------
libmultipath/sysfs.h | 3 -
multipathd/main.c | 7 +--
4 files changed, 62 insertions(+), 106 deletions(-)
Index: multipath-tools/libmultipath/discovery.c
===================================================================
--- multipath-tools.orig/libmultipath/discovery.c
+++ multipath-tools/libmultipath/discovery.c
@@ -129,13 +129,8 @@ path_discovery (vector pathvec, struct c
extern int \
sysfs_get_##fname (struct sysfs_device * dev, char * buff, size_t len) \
{ \
- char *attr; \
-\
- attr = sysfs_attr_get_value(dev->devpath, #fname); \
- if (!attr) \
+ if (sysfs_attr_get_value(dev->devpath, #fname, buff, len) != 0) \
return 1; \
- if (strlcpy(buff, attr, len) != strlen(attr)) \
- return 2; \
strchop(buff); \
return 0; \
}
@@ -150,24 +145,17 @@ declare_sysfs_get_str(state);
int
sysfs_get_dev (struct sysfs_device * dev, char * buff, size_t len)
{
- char *attr;
-
- attr = sysfs_attr_get_value(dev->devpath, "dev");
- if (!attr) {
+ if (sysfs_attr_get_value(dev->devpath, "dev", buff, len) != 0) {
condlog(3, "%s: no 'dev' attribute in sysfs", dev->kernel);
return 1;
}
- if (strlcpy(buff, attr, len) != strlen(attr)) {
- condlog(3, "%s: overflow in 'dev' attribute", dev->kernel);
- return 2;
- }
return 0;
}
int
sysfs_get_timeout(struct sysfs_device *dev, unsigned int *timeout)
{
- char *attr;
+ char buff[NAME_SIZE];
char attr_path[SYSFS_PATH_SIZE];
int r;
unsigned int t;
@@ -175,11 +163,10 @@ sysfs_get_timeout(struct sysfs_device *d
if (safe_sprintf(attr_path, "%s/device", dev->devpath))
return 1;
- attr = sysfs_attr_get_value(attr_path, "timeout");
- if (!attr)
+ if (sysfs_attr_get_value(attr_path, "timeout", buff, NAME_SIZE) != 0)
return 1;
- r = sscanf(attr, "%u\n", &t);
+ r = sscanf(buff, "%u\n", &t);
if (r != 1)
return 1;
@@ -192,14 +179,13 @@ sysfs_get_timeout(struct sysfs_device *d
int
sysfs_get_size (struct sysfs_device * dev, unsigned long long * size)
{
- char *attr;
+ char buff[NAME_SIZE];
int r;
- attr = sysfs_attr_get_value(dev->devpath, "size");
- if (!attr)
+ if (sysfs_attr_get_value(dev->devpath, "size", buff, NAME_SIZE) != 0)
return 1;
- r = sscanf(attr, "%llu\n", size);
+ r = sscanf(buff, "%llu\n", size);
if (r != 1)
return 1;
@@ -213,7 +199,7 @@ sysfs_get_fc_nodename (struct sysfs_devi
unsigned int target)
{
unsigned int checkhost, session;
- char attr_path[SYSFS_PATH_SIZE], *attr;
+ char attr_path[SYSFS_PATH_SIZE];
if (safe_sprintf(attr_path,
"/class/fc_transport/target%i:%i:%i",
@@ -222,11 +208,8 @@ sysfs_get_fc_nodename (struct sysfs_devi
return 1;
}
- attr = sysfs_attr_get_value(attr_path, "node_name");
- if (attr) {
- strncpy(node, attr, strlen(attr));
+ if (!sysfs_attr_get_value(attr_path, "node_name", node, NODE_NAME_SIZE))
return 0;
- }
if (sscanf(dev->devpath, "/devices/platform/host%u/session%u/",
&checkhost, &session) != 2)
@@ -238,11 +221,9 @@ sysfs_get_fc_nodename (struct sysfs_devi
return 1;
}
- attr = sysfs_attr_get_value(attr_path, "targetname");
- if (attr) {
- strncpy(node, attr, strlen(attr));
+ if (!sysfs_attr_get_value(attr_path, "targetname", node,
+ NODE_NAME_SIZE))
return 0;
- }
return 1;
}
@@ -670,14 +651,11 @@ cciss_sysfs_pathinfo (struct path * pp,
static int
common_sysfs_pathinfo (struct path * pp, struct sysfs_device *dev)
{
- char *attr;
-
- attr = sysfs_attr_get_value(dev->devpath, "dev");
- if (!attr) {
+ if (sysfs_attr_get_value(dev->devpath, "dev", pp->dev_t,
+ BLK_DEV_SIZE) != 0) {
condlog(3, "%s: no 'dev' attribute in sysfs", pp->dev);
return 1;
}
- strlcpy(pp->dev_t, attr, BLK_DEV_SIZE);
condlog(3, "%s: dev_t = %s", pp->dev, pp->dev_t);
Index: multipath-tools/libmultipath/sysfs.c
===================================================================
--- multipath-tools.orig/libmultipath/sysfs.c
+++ multipath-tools/libmultipath/sysfs.c
@@ -37,15 +37,6 @@
char sysfs_path[PATH_SIZE];
-/* attribute value cache */
-static LIST_HEAD(attr_list);
-struct sysfs_attr {
- struct list_head node;
- char path[PATH_SIZE];
- char *value; /* points to value_local if value is cached */
- char value_local[NAME_SIZE];
-};
-
/* list of sysfs devices */
static LIST_HEAD(sysfs_dev_list);
struct sysfs_dev {
@@ -62,24 +53,15 @@ int sysfs_init(char *path, size_t len)
strlcpy(sysfs_path, "/sys", sizeof(sysfs_path));
dbg("sysfs_path='%s'", sysfs_path);
- INIT_LIST_HEAD(&attr_list);
INIT_LIST_HEAD(&sysfs_dev_list);
return 0;
}
void sysfs_cleanup(void)
{
- struct sysfs_attr *attr_loop;
- struct sysfs_attr *attr_temp;
-
struct sysfs_dev *sysdev_loop;
struct sysfs_dev *sysdev_temp;
- list_for_each_entry_safe(attr_loop, attr_temp, &attr_list, node) {
- list_del(&attr_loop->node);
- free(attr_loop);
- }
-
list_for_each_entry_safe(sysdev_loop, sysdev_temp, &sysfs_dev_list, node) {
list_del(&sysdev_loop->node);
free(sysdev_loop);
@@ -343,6 +325,8 @@ void sysfs_device_put(struct sysfs_devic
list_for_each_entry(sysdev_loop, &sysfs_dev_list, node) {
if (&sysdev_loop->dev == dev) {
+ if (dev->parent)
+ sysfs_device_put(dev->parent);
dbg("removed dev '%s' from cache",
sysdev_loop->dev.devpath);
list_del(&sysdev_loop->node);
@@ -350,8 +334,7 @@ void sysfs_device_put(struct sysfs_devic
return;
}
}
- dbg("dev '%s' not found in cache",
- sysdev_loop->dev.devpath);
+ dbg("dev '%s' not found in cache", dev->devpath);
return;
}
@@ -416,17 +399,24 @@ out:
}
-char *sysfs_attr_get_value(const char *devpath, const char *attr_name)
+int sysfs_attr_get_value(const char *devpath, const char *attr_name,
+ char *buff, int len)
{
char path_full[PATH_SIZE];
const char *path;
char value[NAME_SIZE];
- struct sysfs_attr *attr_loop;
- struct sysfs_attr *attr = NULL;
struct stat statbuf;
int fd;
ssize_t size;
size_t sysfs_len;
+ int ret = -1;
+
+ if (buff == NULL) {
+ condlog(0, "no space to store sysfs attr value '%s'",
+ attr_name);
+ goto out;
+ }
+ memset(buff, 0, len);
dbg("open '%s'/'%s'", devpath, attr_name);
sysfs_len = strlcpy(path_full, sysfs_path, sizeof(path_full));
@@ -437,29 +427,6 @@ char *sysfs_attr_get_value(const char *d
strlcat(path_full, "/", sizeof(path_full));
strlcat(path_full, attr_name, sizeof(path_full));
- /* look for attribute in cache */
- list_for_each_entry(attr_loop, &attr_list, node) {
- if (strcmp(attr_loop->path, path) == 0) {
- dbg("found in cache '%s'", attr_loop->path);
- attr = attr_loop;
- }
- }
- if (!attr) {
- /* store attribute in cache */
- dbg("new uncached attribute '%s'", path_full);
- attr = malloc(sizeof(struct sysfs_attr));
- if (attr == NULL)
- return NULL;
- memset(attr, 0x00, sizeof(struct sysfs_attr));
- strlcpy(attr->path, path, sizeof(attr->path));
- dbg("add to cache '%s'", path_full);
- list_add(&attr->node, &attr_list);
- } else {
- /* clear old value */
- if(attr->value)
- memset(attr->value, 0x00, sizeof(attr->value));
- }
-
if (lstat(path_full, &statbuf) != 0) {
dbg("stat '%s' failed: %s", path_full, strerror(errno));
goto out;
@@ -467,20 +434,27 @@ char *sysfs_attr_get_value(const char *d
if (S_ISLNK(statbuf.st_mode)) {
/* links return the last element of the target path */
- char link_target[PATH_SIZE];
- int len;
+ int link_len;
const char *pos;
- len = readlink(path_full, link_target, sizeof(link_target));
- if (len > 0) {
- link_target[len] = '\0';
- pos = strrchr(link_target, '/');
+ link_len = readlink(path_full, value, sizeof(value));
+ if (link_len > 0) {
+ if (link_len >= sizeof(value)) {
+ condlog(0, "overflow in attribute '%s'",
+ path_full);
+ goto out;
+ }
+ value[link_len] = '\0';
+ pos = strrchr(value, '/');
if (pos != NULL) {
- dbg("cache '%s' with link value '%s'",
- path_full, value);
- strlcpy(attr->value_local, &pos[1],
- sizeof(attr->value_local));
- attr->value = attr->value_local;
+ pos++;
+ if (strlen(pos) >= len) {
+ condlog(0, "overflow in attribute '%s'",
+ path_full);
+ goto out;
+ }
+ strncpy(buff, pos, len - 1);
+ ret = 0;
}
}
goto out;
@@ -498,9 +472,9 @@ char *sysfs_attr_get_value(const char *d
fd = open(path_full, O_RDONLY);
if (fd < 0) {
if (errno == EMFILE)
- dbg("out of file descriptors. set or increase max_fds in /etc/multipath.conf");
+ condlog(0, "out of file descriptors. set or increase max_fds in /etc/multipath.conf");
else
- dbg("attribute '%s' can not be opened: %s",
+ condlog(0, "attribute '%s' can not be opened: %s",
path_full, strerror(errno));
goto out;
}
@@ -512,16 +486,18 @@ char *sysfs_attr_get_value(const char *d
dbg("overflow in attribute '%s', truncating", path_full);
size--;
}
-
- /* got a valid value, store and return it */
value[size] = '\0';
remove_trailing_chars(value, '\n');
- dbg("cache '%s' with attribute value '%s'", path_full, value);
- strlcpy(attr->value_local, value, sizeof(attr->value_local));
- attr->value = attr->value_local;
-
+ strchop(value);
+ if (strlen(value) >= len) {
+ condlog(0, "overflow in attribute '%s'", path_full);
+ goto out;
+ }
+ strncpy(buff, value, len - 1);
+ /* got a valid value, store and return it */
+ ret = 0;
out:
- return attr && attr->value && strlen(attr->value) ? attr->value : NULL;
+ return ret;
}
int sysfs_lookup_devpath_by_subsys_id(char *devpath_full, size_t len,
Index: multipath-tools/libmultipath/sysfs.h
===================================================================
--- multipath-tools.orig/libmultipath/sysfs.h
+++ multipath-tools/libmultipath/sysfs.h
@@ -19,7 +19,8 @@ struct sysfs_device *sysfs_device_get(co
struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev);
struct sysfs_device *sysfs_device_get_parent_with_subsystem(struct sysfs_device *dev, const char *subsystem);
void sysfs_device_put(struct sysfs_device *dev);
-char *sysfs_attr_get_value(const char *devpath, const char *attr_name);
+int sysfs_attr_get_value(const char *devpath, const char *attr_name,
+ char *buff, int len);
int sysfs_resolve_link(char *path, size_t size);
int sysfs_get_size (struct sysfs_device * dev, unsigned long long * size);
int sysfs_attr_set_value(const char *devpath, const char *attr_name,
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -228,16 +228,17 @@ int
ev_add_map (struct sysfs_device * dev, struct vectors * vecs)
{
char * alias;
- char *dev_t;
+ char dev_t[BLK_DEV_SIZE];
int major, minor;
char * refwwid;
struct multipath * mpp;
int map_present;
int r = 1;
- dev_t = sysfs_attr_get_value(dev->devpath, "dev");
+ if (sysfs_attr_get_value(dev->devpath, "dev", dev_t, BLK_DEV_SIZE) != 0)
+ return 1;
- if (!dev_t || sscanf(dev_t, "%d:%d", &major, &minor) != 2)
+ if (sscanf(dev_t, "%d:%d", &major, &minor) != 2)
return 1;
alias = dm_mapname(major, minor);

View File

@ -1,99 +0,0 @@
---
libmultipath/hwtable.c | 32 ++++++++++++++++++++++++++++++++
multipath.conf.defaults | 28 ++++++++++++++++++++++++++++
2 files changed, 60 insertions(+)
Index: multipath-tools/libmultipath/hwtable.c
===================================================================
--- multipath-tools.orig/libmultipath/hwtable.c
+++ multipath-tools/libmultipath/hwtable.c
@@ -239,6 +239,22 @@ static struct hwentry default_hw[] = {
.checker_name = TUR,
.prio_name = DEFAULT_PRIO,
},
+ {
+ /* HP P2000 family arrays */
+ .vendor = "HP",
+ .product = "P2000 G3 FC|P2000G3 FC/iSCSI|P2000 G3 SAS|P2000 G3 iSCSI",
+ .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,
+ },
/*
* DDN controller family
*
@@ -1118,6 +1134,22 @@ static struct hwentry default_hw[] = {
.checker_name = DEFAULT_CHECKER,
.prio_name = DEFAULT_PRIO,
},
+ /* NEC Storage M Series */
+ {
+ .vendor = "NEC",
+ .product = "DISK ARRAY",
+ .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 = NO_PATH_RETRY_UNDEF,
+ .minio = DEFAULT_MINIO,
+ .checker_name = TUR,
+ .prio_name = PRIO_ALUA,
+ },
/*
* EOL
*/
Index: multipath-tools/multipath.conf.defaults
===================================================================
--- multipath-tools.orig/multipath.conf.defaults
+++ multipath-tools/multipath.conf.defaults
@@ -180,6 +180,20 @@
# prio const
# }
# device {
+# vendor "HP"
+# product "P2000 G3 FC|P2000G3 FC/iSCSI|P2000 G3 SAS|P2000 G3 iSCS"
+# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
+# features "0"
+# hardware_handler "0"
+# path_selector "round-robin 0"
+# path_grouping_policy group_by_prio
+# rr_weight uniform
+# no_path_retry 18
+# rr_min_io 100
+# path_checker tur
+# prio alua
+# }
+# device {
# vendor "DDN"
# product "SAN DataDirector"
# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
@@ -659,4 +673,18 @@
# path_checker directio
# prio const
# }
+# device {
+# vendor "NEC"
+# product "DISK ARRAY"
+# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
+# features "0"
+# hardware_handler "1 alua"
+# path_selector "round-robin 0"
+# path_grouping_policy group_by_prio
+# failback immediate
+# rr_weight uniform
+# rr_min_io 1000
+# path_checker tur
+# prio alua
+# }
#}

View File

@ -1,160 +0,0 @@
From c2f3abecdb76c4e7b3ec3aa418625b4f1b942496 Mon Sep 17 00:00:00 2001
From: Malahal Naineni <malahal@us.ibm.com>
Date: Mon, 16 Aug 2010 15:57:02 -0700
Subject: [PATCH] option to multipath to not modify the bindinfs file
initramfs is mounted read-write causing multipath to update the
initramfs bindings file and name all multipath devices it finds using
friendly names. The actual changes to the file are thrown away as they
are only written to the memory image rather than to the disk image. This
may cause the in memory updated initramfs bindings file inconsistent
with the actual bindings file in the active root file system image when
devices are added or removed.
In other words, the boot time updated initramfs bindings file may have
'uuid1 map to mpatha' and 'uuid2 map to mpathb', but the active root fs
bindings file may have 'uuid1 map to mpathb' and 'uuid2 map to mpatha'
The option, -B, will not modify the bindings file. It will only use the
bindings file if needed. This option to multipath should be used when
invoked in the initramfs context to avoid the inconsistency.
Signed-off-by: Malahal Naineni (malahal@us.ibm.com)
---
libmultipath/alias.c | 4 ++--
libmultipath/alias.h | 2 +-
libmultipath/config.h | 1 +
libmultipath/propsel.c | 3 ++-
multipath/main.c | 5 ++++-
multipath/multipath.8 | 5 ++++-
multipathd/main.c | 5 ++++-
7 files changed, 18 insertions(+), 7 deletions(-)
Index: multipath-tools/libmultipath/alias.c
===================================================================
--- multipath-tools.orig/libmultipath/alias.c
+++ multipath-tools/libmultipath/alias.c
@@ -206,7 +206,7 @@ allocate_binding(int fd, char *wwid, int
}
char *
-get_user_friendly_alias(char *wwid, char *file)
+get_user_friendly_alias(char *wwid, char *file, int bindings_read_only)
{
char *alias;
int fd, scan_fd, id;
@@ -250,7 +250,7 @@ get_user_friendly_alias(char *wwid, char
return NULL;
}
- if (!alias && can_write)
+ if (!alias && can_write && !bindings_read_only)
alias = allocate_binding(fd, wwid, id);
fclose(f);
Index: multipath-tools/libmultipath/alias.h
===================================================================
--- multipath-tools.orig/libmultipath/alias.h
+++ multipath-tools/libmultipath/alias.h
@@ -7,5 +7,5 @@
"# alias wwid\n" \
"#\n"
-char *get_user_friendly_alias(char *wwid, char *file);
+char *get_user_friendly_alias(char *wwid, char *file, int bindings_readonly);
char *get_user_friendly_wwid(char *alias, char *file);
Index: multipath-tools/libmultipath/config.h
===================================================================
--- multipath-tools.orig/libmultipath/config.h
+++ multipath-tools/libmultipath/config.h
@@ -76,6 +76,7 @@ struct config {
int rr_weight;
int no_path_retry;
int user_friendly_names;
+ int bindings_read_only;
int pg_timeout;
int max_fds;
int force_reload;
Index: multipath-tools/libmultipath/propsel.c
===================================================================
--- multipath-tools.orig/libmultipath/propsel.c
+++ multipath-tools/libmultipath/propsel.c
@@ -219,7 +219,8 @@ select_alias (struct multipath * mp)
mp->alias = NULL;
if (conf->user_friendly_names)
mp->alias = get_user_friendly_alias(mp->wwid,
- conf->bindings_file);
+ conf->bindings_file,
+ conf->bindings_read_only);
if (mp->alias == NULL){
char *alias;
if ((alias = MALLOC(WWID_SIZE)) != NULL){
Index: multipath-tools/multipath/main.c
===================================================================
--- multipath-tools.orig/multipath/main.c
+++ multipath-tools/multipath/main.c
@@ -383,7 +383,7 @@ main (int argc, char *argv[])
condlog(0, "multipath tools need sysfs mounted");
exit(1);
}
- while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:rq")) != EOF ) {
+ while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:Brq")) != EOF ) {
switch(arg) {
case 1: printf("optarg : %s\n",optarg);
break;
@@ -403,6 +403,9 @@ main (int argc, char *argv[])
case 'q':
conf->allow_queueing = 1;
break;
+ case 'B':
+ conf->bindings_read_only = 1;
+ break;
case 'd':
if (!conf->dry_run)
conf->dry_run = 1;
Index: multipath-tools/multipath/multipath.8
===================================================================
--- multipath-tools.orig/multipath/multipath.8
+++ multipath-tools/multipath/multipath.8
@@ -6,7 +6,7 @@ multipath \- Device mapper target autoco
.RB [\| \-v\ \c
.IR verbosity \|]
.RB [\| \-d \|]
-.RB [\| \-h | \-l | \-ll | \-f | \-F \|]
+.RB [\| \-h | \-l | \-ll | \-f | \-F | \-B \|]
.RB [\| \-p\ \c
.BR failover | multibus | group_by_serial | group_by_prio | group_by_node_name \|]
.RB [\| device \|]
@@ -47,6 +47,9 @@ flush a multipath device map specified a
.B \-F
flush all unused multipath device maps
.TP
+.B \-B
+treat the bindings file as read only
+.TP
.BI \-p " policy"
force maps to specified policy:
.RS 1.2i
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -1640,7 +1640,7 @@ main (int argc, char *argv[])
if (!conf)
exit(1);
- while ((arg = getopt(argc, argv, ":dv:k::")) != EOF ) {
+ while ((arg = getopt(argc, argv, ":dv:k::B")) != EOF ) {
switch(arg) {
case 'd':
logsink = 0;
@@ -1653,6 +1653,9 @@ main (int argc, char *argv[])
conf->verbosity = atoi(optarg);
break;
+ case 'B':
+ conf->bindings_read_only = 1;
+ break;
case 'k':
uxclnt(optarg);
exit(0);

View File

@ -1,17 +0,0 @@
---
libmultipath/discovery.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: multipath-tools/libmultipath/discovery.c
===================================================================
--- multipath-tools.orig/libmultipath/discovery.c
+++ multipath-tools/libmultipath/discovery.c
@@ -711,7 +711,7 @@ path_offline (struct path * pp)
char buff[SCSI_STATE_SIZE];
if (path_state(pp, buff))
- return 1;
+ return 0;
if (!strncmp(buff, "offline", 7)) {
pp->offline = 1;

View File

@ -1,92 +0,0 @@
---
multipathd/cli_handlers.c | 2 +-
multipathd/main.c | 20 +++++++++++++-------
multipathd/main.h | 2 +-
3 files changed, 15 insertions(+), 9 deletions(-)
Index: multipath-tools/multipathd/cli_handlers.c
===================================================================
--- multipath-tools.orig/multipathd/cli_handlers.c
+++ multipath-tools/multipathd/cli_handlers.c
@@ -416,7 +416,7 @@ cli_del_path (void * v, char ** reply, i
condlog(2, "%s: remove path (operator)", param);
- return ev_remove_path(param, vecs);
+ return ev_remove_path(param, vecs, NULL);
}
int
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -496,23 +496,25 @@ fail:
static int
uev_remove_path (struct sysfs_device * dev, struct vectors * vecs)
{
- int retval;
+ int retval, del_sysdev;
condlog(2, "%s: remove path (uevent)", dev->kernel);
- retval = ev_remove_path(dev->kernel, vecs);
- if (!retval)
+ retval = ev_remove_path(dev->kernel, vecs, &del_sysdev);
+ if (del_sysdev)
sysfs_device_put(dev);
return retval;
}
int
-ev_remove_path (char * devname, struct vectors * vecs)
+ev_remove_path (char * devname, struct vectors * vecs, int *del_sysdev)
{
struct multipath * mpp;
struct path * pp;
int i, retval = 0;
+ if (del_sysdev)
+ *del_sysdev = 0;
pp = find_path_by_dev(vecs->pathvec, devname);
if (!pp) {
@@ -599,6 +601,10 @@ out:
if ((i = find_slot(vecs->pathvec, (void *)pp)) != -1)
vector_del_slot(vecs->pathvec, i);
+ if (pp->sysdev)
+ sysfs_device_put(pp->sysdev);
+ else if (del_sysdev)
+ *del_sysdev = 1;
free_path(pp);
return retval;
@@ -689,11 +695,11 @@ uev_trigger (struct uevent * uev, void *
if (uev_discard(uev->devpath))
return 0;
+ lock(vecs->lock);
+
sysdev = sysfs_device_get(uev->devpath);
if(!sysdev)
- return 0;
-
- lock(vecs->lock);
+ goto out;
/*
* device map event
Index: multipath-tools/multipathd/main.h
===================================================================
--- multipath-tools.orig/multipathd/main.h
+++ multipath-tools/multipathd/main.h
@@ -5,7 +5,7 @@
int reconfigure (struct vectors *);
int ev_add_path (char *, struct vectors *);
-int ev_remove_path (char *, struct vectors *);
+int ev_remove_path (char *, struct vectors *, int *);
int ev_add_map (struct sysfs_device *, struct vectors *);
int ev_remove_map (char *, struct vectors *);
void sync_map_state (struct multipath *);

View File

@ -1,19 +0,0 @@
---
libmultipath/discovery.c | 4 ++++
1 file changed, 4 insertions(+)
Index: multipath-tools/libmultipath/discovery.c
===================================================================
--- multipath-tools.orig/libmultipath/discovery.c
+++ multipath-tools/libmultipath/discovery.c
@@ -859,6 +859,10 @@ get_state (struct path * pp, int daemon)
return PATH_PENDING;
checker_set_async(c);
}
+ if (!pp->sysdev) {
+ condlog(2, "%s: no sysfs information", pp->dev);
+ return PATH_DOWN;
+ }
if (!conf->checker_timeout)
sysfs_get_timeout(pp->sysdev, &(c->timeout));
state = checker_check(c);

View File

@ -1,29 +0,0 @@
---
multipathd/main.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -957,15 +957,16 @@ retry_count_tick(vector mpvec)
int update_prio(struct path *pp, int refresh_all)
{
int oldpriority;
+ struct path *pp1;
struct pathgroup * pgp;
int i, j, changed = 0;
if (refresh_all) {
vector_foreach_slot (pp->mpp->pg, pgp, i) {
- vector_foreach_slot (pgp->paths, pp, j) {
- oldpriority = pp->priority;
- pathinfo(pp, conf->hwtable, DI_PRIO);
- if (pp->priority != oldpriority)
+ vector_foreach_slot (pgp->paths, pp1, j) {
+ oldpriority = pp1->priority;
+ pathinfo(pp1, conf->hwtable, DI_PRIO);
+ if (pp1->priority != oldpriority)
changed = 1;
}
}

View File

@ -1,58 +0,0 @@
---
libmultipath/hwtable.c | 16 ++++++++++++++++
multipath.conf.defaults | 15 +++++++++++++++
2 files changed, 31 insertions(+)
Index: multipath-tools/libmultipath/hwtable.c
===================================================================
--- multipath-tools.orig/libmultipath/hwtable.c
+++ multipath-tools/libmultipath/hwtable.c
@@ -725,6 +725,22 @@ static struct hwentry default_hw[] = {
.checker_name = TUR,
.prio_name = PRIO_ALUA,
},
+ {
+ /* IBM RSSM */
+ .vendor = "IBM",
+ .product = "1820N00",
+ .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 = NO_PATH_RETRY_QUEUE,
+ .minio = 100,
+ .checker_name = TUR,
+ .prio_name = PRIO_ALUA,
+ },
/*
* IBM Power Virtual SCSI Devices
*
Index: multipath-tools/multipath.conf.defaults
===================================================================
--- multipath-tools.orig/multipath.conf.defaults
+++ multipath-tools/multipath.conf.defaults
@@ -491,6 +491,21 @@
# prio ontap
# }
# device {
+# vendor "IBM"
+# product "1820N00"
+# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"
+# features "0"
+# hardware_handler "0"
+# path_selector "round-robin 0"
+# path_grouping_policy group_by_prio
+# failback immediate
+# rr_weight uniform
+# rr_min_io 100
+# path_checker tur
+# prio alua
+# no_path_retry queue
+# }
+# device {
# vendor "Pillar"
# product "Axiom.*"
# getuid_callout "/lib/udev/scsi_id --whitelisted --device=/dev/%n"

View File

@ -1,17 +0,0 @@
---
libmultipath/configure.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: multipath-tools/libmultipath/configure.c
===================================================================
--- multipath-tools.orig/libmultipath/configure.c
+++ multipath-tools/libmultipath/configure.c
@@ -90,7 +90,7 @@ setup_map (struct multipath * mpp)
if (mpp->pgpolicyfn && mpp->pgpolicyfn(mpp))
return 1;
- mpp->nr_active = pathcount(mpp, PATH_UP);
+ mpp->nr_active = pathcount(mpp, PATH_UP) + pathcount(mpp, PATH_GHOST);
/*
* ponders each path group and determine highest prio pg

View File

@ -1,51 +0,0 @@
---
multipath/multipath.conf.5 | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
Index: multipath-tools/multipath/multipath.conf.5
===================================================================
--- multipath-tools.orig/multipath/multipath.conf.5
+++ multipath-tools/multipath/multipath.conf.5
@@ -39,9 +39,8 @@ section in which they occor.
The following \fIsection\fP keywords are recognized:
.TP 17
.B defaults
-This section defines default values for attributes which are used
-whenever no specific setting is given in the appropriate device or
-multipath sections.
+This section defines default settings for devices-mapper-multipath. These
+values can be overwritten by the devices and multipaths sections.
.TP
.B blacklist
This section defines which devices should be excluded from the
@@ -54,13 +53,26 @@ multipath topology discovery, despite be
section.
.TP
.B multipaths
-This section defines the multipath topologies. They are indexed by a
-\fIWorld Wide Identifier\fR(wwid), which is the result of the
-\fIgetuid_callout\fR program.
+This section defines the settings for individual multipath devices.
+These values overwrite what is specified in the defaults and devices
+section of the configuration file.
+The devices are identified by the \fIwwid\fR keyword, which is a regular
+expression that must match the result of the \fIgetuid_callout\fR program.
.TP
.B devices
-This section defines the device-specific settings.
+This section defines the settings for individual storage controller types.
+These value overwrite what is specified in the defaults section of the
+configuration file.
+These controller types are identified by the \fIvendor\fR, \fIproduct\fR, and
+\fIrevision\fR keywords, which are regular expressions that must match the
+sysfs information about this device.
+If you are using a storage array that is not supported by default, you may need
+to create a devices subsection for your array.
.RE
+.P
+The priority of configuration in multipath.conf is:
+.br
+\fImultipaths\fR is greater than \fIdevices\fR is greater that \fIdefaults\fR
.LP
.SH "defaults section"
The

View File

@ -1,64 +0,0 @@
From patchwork Tue Mar 1 19:08:24 2011
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: multipath: Retry host transient errors for rdac checker
Date: Tue, 01 Mar 2011 19:08:24 -0000
From: Moger, Babu <Babu.Moger@lsi.com>
X-Patchwork-Id: 600411
Message-Id: <E463DF2B2E584B4A82673F53D62C2EF4FF7DC637@cosmail01.lsi.com>
To: "dm-devel@redhat.com" <dm-devel@redhat.com>
Sometimes if the host is in transient state, we need to wait till the devloss timeout to
expire before switching path group. We have seen in some cases path group switch happens
even before the devloss timeout expire. This patch fixes the problem for rdac checker..
Signed-off-by: Babu Moger <babu.moger@lsi.com>
---
--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
---
libmultipath/checkers/rdac.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
Index: multipath-tools/libmultipath/checkers/rdac.c
===================================================================
--- multipath-tools.orig/libmultipath/checkers/rdac.c
+++ multipath-tools/libmultipath/checkers/rdac.c
@@ -48,7 +48,9 @@ do_inq(int sg_fd, unsigned int pg_op, vo
unsigned char inqCmdBlk[INQUIRY_CMDLEN] = { INQUIRY_CMD, 1, 0, 0, 0, 0 };
unsigned char sense_b[SENSE_BUFF_LEN];
struct sg_io_hdr io_hdr;
+ int retry_rdac = 5;
+retry:
inqCmdBlk[2] = (unsigned char) pg_op;
inqCmdBlk[4] = (unsigned char) (mx_resp_len & 0xff);
memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
@@ -72,6 +74,22 @@ do_inq(int sg_fd, unsigned int pg_op, vo
if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
(0 == io_hdr.driver_status))
return 0;
+
+ /* check if we need to retry this error */
+ if (io_hdr.info & SG_INFO_OK_MASK) {
+ switch (io_hdr.host_status) {
+ case DID_BUS_BUSY:
+ case DID_ERROR:
+ case DID_TRANSPORT_DISRUPTED:
+ /* Transport error, retry */
+ if (--retry_rdac)
+ goto retry;
+ break;
+ default:
+ break;
+ }
+ }
+
if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
(SCSI_COMMAND_TERMINATED == io_hdr.status) ||
(SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {

View File

@ -1,18 +0,0 @@
---
multipathd/main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -883,7 +883,8 @@ mpvec_garbage_collector (struct vectors
return;
vector_foreach_slot (vecs->mpvec, mpp, i) {
- if (mpp && mpp->alias && !dm_map_present(mpp->alias)) {
+ if (mpp && mpp->alias && !dm_map_present(mpp->alias) &&
+ errno != ENOMEM) {
condlog(2, "%s: remove dead map", mpp->alias);
remove_map_and_stop_waiter(mpp, vecs, 1);
i--;

Some files were not shown because too many files have changed in this diff Show More