aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2011-05-02 12:03:21 +0200
committerHannes Reinecke <hare@suse.de>2011-05-02 12:03:21 +0200
commite9c80c211b56dbbcfcecde091ea3af21a86ef3f8 (patch)
treef3ef92c48b6faf10e30366ecb40d7b86ac82ea9b
parent2c617f3533564d0ce3c7bb3d844febfd84201856 (diff)
parent50192396d7bd3d802d9529550e0229d9beaa9afc (diff)
downloadmultipath-tools-e9c80c211b56dbbcfcecde091ea3af21a86ef3f8.tar.gz
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/storage/multipath-tools/
-rw-r--r--libmultipath/checkers.c5
-rw-r--r--libmultipath/checkers.h1
-rw-r--r--libmultipath/discovery.c1
-rw-r--r--libmultipath/dmparser.c6
-rw-r--r--libmultipath/hwtable.c22
-rw-r--r--libmultipath/prio.h2
-rw-r--r--libmultipath/prioritizers/Makefile2
-rw-r--r--libmultipath/prioritizers/ontap.c (renamed from libmultipath/prioritizers/netapp.c)44
-rw-r--r--multipath.conf.defaults18
-rw-r--r--multipath/multipath.conf.52
-rw-r--r--multipathd/main.c62
11 files changed, 112 insertions, 53 deletions
diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c
index 19d0781..5cc31d2 100644
--- a/libmultipath/checkers.c
+++ b/libmultipath/checkers.c
@@ -183,6 +183,11 @@ char * checker_message (struct checker * c)
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);
diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h
index 272cd8f..e61280d 100644
--- a/libmultipath/checkers.h
+++ b/libmultipath/checkers.h
@@ -114,6 +114,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 */
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index 3b443e2..aa25cc4 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -848,6 +848,7 @@ get_state (struct path * pp, int daemon)
return PATH_UNCHECKED;
}
}
+ checker_clear_message(c);
state = path_offline(pp);
if (state != PATH_UP) {
condlog(3, "%s: path inaccessible", pp->dev);
diff --git a/libmultipath/dmparser.c b/libmultipath/dmparser.c
index 1ef3aad..0803bec 100644
--- a/libmultipath/dmparser.c
+++ b/libmultipath/dmparser.c
@@ -52,6 +52,7 @@ assemble_map (struct multipath * mp)
int i, j;
int shift, freechar;
int minio;
+ int nr_priority_groups, initial_pg_nr;
char * p;
struct pathgroup * pgp;
struct path * pp;
@@ -60,9 +61,12 @@ assemble_map (struct multipath * mp)
p = mp->params;
freechar = sizeof(mp->params);
+ nr_priority_groups = VECTOR_SIZE(mp->pg);
+ initial_pg_nr = (nr_priority_groups ? mp->bestpg : 0);
+
shift = snprintf(p, freechar, "%s %s %i %i",
mp->features, mp->hwhandler,
- VECTOR_SIZE(mp->pg), mp->bestpg);
+ nr_priority_groups, initial_pg_nr);
if (shift >= freechar) {
fprintf(stderr, "mp->params too small\n");
diff --git a/libmultipath/hwtable.c b/libmultipath/hwtable.c
index 9e6888e..b298a03 100644
--- a/libmultipath/hwtable.c
+++ b/libmultipath/hwtable.c
@@ -903,7 +903,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,
.prio_args = NULL,
},
/*
@@ -947,7 +947,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,
.prio_args = NULL,
},
/*
@@ -1031,6 +1031,24 @@ static struct hwentry default_hw[] = {
.prio_name = PRIO_RDAC,
.prio_args = NULL,
},
+ /* 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,
+ .minio_rq = DEFAULT_MINIO_RQ,
+ .checker_name = TUR,
+ .prio_name = PRIO_ALUA,
+ .prio_args = NULL,
+ },
/*
* STK arrays
*
diff --git a/libmultipath/prio.h b/libmultipath/prio.h
index fd4a326..d9ed7f3 100644
--- a/libmultipath/prio.h
+++ b/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_DATACORE "datacore"
diff --git a/libmultipath/prioritizers/Makefile b/libmultipath/prioritizers/Makefile
index 6e28ab7..bb7d536 100644
--- a/libmultipath/prioritizers/Makefile
+++ b/libmultipath/prioritizers/Makefile
@@ -11,7 +11,7 @@ LIBS = \
libprioemc.so \
libpriordac.so \
libprioalua.so \
- libprionetapp.so \
+ libprioontap.so \
libpriodatacore.so \
libpriohds.so
diff --git a/libmultipath/prioritizers/netapp.c b/libmultipath/prioritizers/ontap.c
index c695cd3..6e6e3d3 100644
--- a/libmultipath/prioritizers/netapp.c
+++ b/libmultipath/prioritizers/ontap.c
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright 2005 Network Appliance, Inc., All Rights Reserved
* Author: David Wysochanski available at davidw@netapp.com
*
@@ -7,7 +7,7 @@
* 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
+ * 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.
*/
@@ -27,17 +27,17 @@
#define INQUIRY_CMDLEN 6
#define DEFAULT_PRIOVAL 10
#define RESULTS_MAX 256
-#define SG_TIMEOUT 30000
+#define SG_TIMEOUT 60000
-#define pp_netapp_log(prio, fmt, args...) \
- condlog(prio, "%s: netapp prio: " fmt, dev, ##args)
+#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]);
@@ -50,7 +50,7 @@ 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);
@@ -90,12 +90,12 @@ static int send_gva(const char *dev, int fd, unsigned char pg,
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);
+ 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_netapp_log(0, "SCSI error");
+ pp_ontap_log(0, "SCSI error");
dump_cdb(cdb, sizeof(cdb));
process_sg_error(&io_hdr);
goto out;
@@ -104,8 +104,8 @@ static int send_gva(const char *dev, int fd, unsigned char pg,
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",
+ 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;
}
@@ -142,13 +142,13 @@ static int get_proxy(const char *dev, int fd)
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, "
+ 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_netapp_log(0, "SCSI error");
+ pp_ontap_log(0, "SCSI error");
dump_cdb(cdb, sizeof(cdb));
process_sg_error(&io_hdr);
goto out;
@@ -158,8 +158,8 @@ static int get_proxy(const char *dev, int fd)
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 "
+ 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]);
@@ -180,7 +180,7 @@ static int get_proxy(const char *dev, int fd)
* 2: iSCSI software
* 1: FCP proxy
*/
-static int netapp_prio(const char *dev, int fd)
+static int ontap_prio(const char *dev, int fd)
{
unsigned char results[RESULTS_MAX];
int results_size=RESULTS_MAX;
@@ -194,14 +194,14 @@ static int netapp_prio(const char *dev, int fd)
memset(&results, 0, sizeof (results));
rc = send_gva(dev, fd, 0x41, results, &results_size);
- if (rc == 0) {
+ 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 - "
+ pp_ontap_log(0, "GVA page 0x41 error - "
"results[8] = 0x%x", results[8]);
goto try_fcp_proxy;
}
@@ -214,9 +214,11 @@ static int netapp_prio(const char *dev, int fd)
is_iscsi_hardware = 1;
goto prio_select;
}
+ } else {
+ return 0;
}
-
- try_fcp_proxy:
+
+ try_fcp_proxy:
rc = get_proxy(dev, fd);
if (rc >= 0) {
is_proxy = rc;
@@ -239,5 +241,5 @@ static int netapp_prio(const char *dev, int fd)
int getprio (struct path * pp, char * args)
{
- return netapp_prio(pp->dev, pp->fd);
+ return ontap_prio(pp->dev, pp->fd);
}
diff --git a/multipath.conf.defaults b/multipath.conf.defaults
index f8ca0a2..676ac62 100644
--- a/multipath.conf.defaults
+++ b/multipath.conf.defaults
@@ -503,7 +503,7 @@
# rr_weight uniform
# rr_min_io 128
# path_checker directio
-# prio netapp
+# prio ontap
# prio_args ""
# }
# device {
@@ -534,7 +534,7 @@
# rr_weight uniform
# rr_min_io 128
# path_checker directio
-# prio netapp
+# prio ontap
# prio_args ""
# }
# device {
@@ -743,4 +743,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
+# }
#}
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
index 5056414..27e1b53 100644
--- a/multipath/multipath.conf.5
+++ b/multipath/multipath.conf.5
@@ -150,7 +150,7 @@ Generate the path priority for EMC arrays
.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
diff --git a/multipathd/main.c b/multipathd/main.c
index bf104a1..e8eee9e 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -920,19 +920,47 @@ 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 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, pp1, j) {
+ oldpriority = pp1->priority;
+ pathinfo(pp1, conf->hwtable, DI_PRIO);
+ if (pp1->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) {
condlog(0, "%s: failed to update map : %s", mpp->alias,
- strerror(errno));
+ strerror(errno));
return 1;
}
dm_lib_release();
@@ -946,7 +974,7 @@ void
check_path (struct vectors * vecs, struct path * pp)
{
int newstate;
- int oldpriority;
+ int new_path_up = 0;
if (!pp->mpp)
return;
@@ -1015,15 +1043,7 @@ check_path (struct vectors * vecs, struct path * pp)
else
reinstate_path(pp, 0);
- /*
- * schedule [defered] failback
- */
- 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))
- switch_pathgroup(pp->mpp);
+ new_path_up = 1;
/*
* if at least one path is up in a group, and
@@ -1056,22 +1076,16 @@ check_path (struct vectors * vecs, struct path * pp)
* path prio refreshing
*/
condlog(4, "path prio refresh");
- oldpriority = pp->priority;
- pathinfo(pp, conf->hwtable, DI_PRIO);
- /*
- * pathgroup failback policy
- */
- if (pp->priority != oldpriority &&
+ if (update_prio(pp, new_path_up) &&
pp->mpp->pgpolicyfn == (pgpolicyfn *)group_by_prio)
- update_path_groups(pp->mpp, vecs);
+ update_path_groups(pp->mpp, vecs, !new_path_up);
else if (need_switch_pathgroup(pp->mpp, 0)) {
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)
switch_pathgroup(pp->mpp);
}
}