Modify 0012-RH-udev-sync-support.patch

Modify 0021-RHBZ-548874-add-find-multipaths.patch
Modify 0022-RHBZ-557845-RHEL5-style-partitions.patch
Add 0025-RHBZ-508827-update-multipathd-manpage.patch through
    0101-RHBZ-631009-disable-udev-disk-rules-on-reload.patch
  * sync with current state of RHEL6. Next release should include a updated
    source tarball with most of these fixes rolled in.
Add 0102-RHBZ-690828-systemd-unit-file.patch
  * Add Jóhann B. Guðmundsson's unit file for systemd.
  * Add sub-package sysvinit for SysV init script.
Resolves: bz #690828
This commit is contained in:
Benjamin Marzinski 2011-07-15 12:25:48 -05:00
parent 032bbf0df7
commit b0ec4a42c8
81 changed files with 6741 additions and 61 deletions

View File

@ -1,14 +1,14 @@
--- ---
kpartx/devmapper.c | 10 ++++++++-- kpartx/devmapper.c | 10 ++++++++--
kpartx/devmapper.h | 4 ++-- kpartx/devmapper.h | 4 ++--
kpartx/kpartx.c | 22 ++++++++++++++++------ kpartx/kpartx.c | 28 ++++++++++++++++++++--------
libmultipath/config.h | 2 ++ libmultipath/config.h | 2 ++
libmultipath/configure.c | 2 +- libmultipath/configure.c | 2 +-
libmultipath/devmapper.c | 29 +++++++++++++++++++---------- libmultipath/devmapper.c | 29 +++++++++++++++++++----------
libmultipath/devmapper.h | 8 +++++--- libmultipath/devmapper.h | 8 +++++---
multipath/main.c | 1 + multipath/main.c | 1 +
multipathd/main.c | 1 + multipathd/main.c | 1 +
9 files changed, 55 insertions(+), 24 deletions(-) 9 files changed, 59 insertions(+), 26 deletions(-)
Index: multipath-tools/kpartx/devmapper.c Index: multipath-tools/kpartx/devmapper.c
=================================================================== ===================================================================
@ -131,7 +131,23 @@ Index: multipath-tools/kpartx/kpartx.c
fprintf(stderr, "resume failed on %s\n", fprintf(stderr, "resume failed on %s\n",
partname); partname);
r++; r++;
@@ -557,6 +566,7 @@ main(int argc, char **argv){ @@ -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) if (n > 0)
break; break;
} }

View File

@ -4,18 +4,18 @@
libmultipath/alias.h | 1 libmultipath/alias.h | 1
libmultipath/config.c | 5 - libmultipath/config.c | 5 -
libmultipath/config.h | 1 libmultipath/config.h | 1
libmultipath/configure.c | 23 ++++ libmultipath/configure.c | 22 ++++
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 | 150 ++++++++++++++++++++++++++++++ libmultipath/finder.c | 165 +++++++++++++++++++++++++++++++++
libmultipath/finder.h | 18 +++ libmultipath/finder.h | 18 +++
multipath/Makefile | 2 multipath/Makefile | 2
multipath/main.c | 2 multipath/main.c | 2
multipath/mpathconf | 234 +++++++++++++++++++++++++++++++++++++++++++++++ multipath/mpathconf | 234 +++++++++++++++++++++++++++++++++++++++++++++++
multipathd/main.c | 27 +++-- multipathd/main.c | 24 +++-
16 files changed, 679 insertions(+), 163 deletions(-) 16 files changed, 690 insertions(+), 163 deletions(-)
Index: multipath-tools/libmultipath/alias.c Index: multipath-tools/libmultipath/alias.c
=================================================================== ===================================================================
@ -269,7 +269,16 @@ Index: multipath-tools/libmultipath/configure.c
extern int extern int
setup_map (struct multipath * mpp) setup_map (struct multipath * mpp)
@@ -462,6 +463,10 @@ coalesce_paths (struct vectors * vecs, v @@ -403,6 +404,8 @@ domap (struct multipath * mpp)
* DM_DEVICE_CREATE, DM_DEVICE_RENAME, or DM_DEVICE_RELOAD
* succeeded
*/
+ if (mpp->action == ACT_CREATE)
+ remember_wwid(mpp->wwid);
if (!conf->daemon) {
/* multipath client mode */
dm_switchgroup(mpp->alias, mpp->bestpg);
@@ -462,6 +465,10 @@ coalesce_paths (struct vectors * vecs, v
memset(empty_buff, 0, WWID_SIZE); memset(empty_buff, 0, WWID_SIZE);
@ -280,7 +289,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 +477,35 @@ coalesce_paths (struct vectors * vecs, v @@ -472,21 +479,32 @@ coalesce_paths (struct vectors * vecs, v
/* 1. if path has no unique id or wwid blacklisted */ /* 1. if path has no unique id or wwid blacklisted */
if (memcmp(empty_buff, pp1->wwid, WWID_SIZE) == 0 || if (memcmp(empty_buff, pp1->wwid, WWID_SIZE) == 0 ||
@ -306,13 +315,10 @@ Index: multipath-tools/libmultipath/configure.c
continue; continue;
+ /* If find_multipaths was selected check if the path is valid */ + /* If find_multipaths was selected check if the path is valid */
+ if (conf->find_multipaths){ + if (conf->find_multipaths && !refwwid &&
+ if (refwwid || should_multipath(pp1, pathvec)) + !should_multipath(pp1, pathvec)){
+ remember_wwid(pp1->wwid); + orphan_path(pp1);
+ else { + continue;
+ orphan_path(pp1);
+ continue;
+ }
+ } + }
+ +
/* /*
@ -599,7 +605,7 @@ Index: multipath-tools/libmultipath/finder.c
=================================================================== ===================================================================
--- /dev/null --- /dev/null
+++ multipath-tools/libmultipath/finder.c +++ multipath-tools/libmultipath/finder.c
@@ -0,0 +1,150 @@ @@ -0,0 +1,165 @@
+#include <stdlib.h> +#include <stdlib.h>
+#include <errno.h> +#include <errno.h>
+#include <unistd.h> +#include <unistd.h>
@ -622,18 +628,33 @@ Index: multipath-tools/libmultipath/finder.c
+ +
+static int +static int
+lookup_wwid(FILE *f, char *wwid) { +lookup_wwid(FILE *f, char *wwid) {
+ int c;
+ char buf[LINE_MAX]; + char buf[LINE_MAX];
+ int count;
+ +
+ while (fgets(buf, LINE_MAX, f)) { + while ((c = fgetc(f)) != EOF){
+ char *c; + if (c != '/') {
+ + if (fgets(buf, LINE_MAX, f) == NULL)
+ c = strpbrk(buf, "#\n\r"); + return 0;
+ if (c) + else
+ *c = '\0'; + continue;
+ if (*buf == '\0') + }
+ continue; + count = 0;
+ if (strncmp(wwid, buf, WWID_SIZE) == 0) + while ((c = fgetc(f)) != '/') {
+ if (c == EOF)
+ return 0;
+ if (count >= WWID_SIZE - 1)
+ goto next;
+ if (wwid[count] == '\0')
+ goto next;
+ if (c != wwid[count++])
+ goto next;
+ }
+ if (wwid[count] == '\0')
+ return 1; + return 1;
+next:
+ if (fgets(buf, LINE_MAX, f) == NULL)
+ return 0;
+ } + }
+ return 0; + return 0;
+} +}
@ -642,10 +663,10 @@ Index: multipath-tools/libmultipath/finder.c
+write_out_wwid(int fd, char *wwid) { +write_out_wwid(int fd, char *wwid) {
+ int ret; + int ret;
+ off_t offset; + off_t offset;
+ char buf[WWID_SIZE + 1]; + char buf[WWID_SIZE + 3];
+ +
+ ret = snprintf(buf, WWID_SIZE + 1, "%s\n", wwid); + ret = snprintf(buf, WWID_SIZE + 3, "/%s/\n", wwid);
+ if (ret > WWID_SIZE || ret < 0){ + if (ret >= (WWID_SIZE + 3) || ret < 0){
+ condlog(0, "can't format wwid for writing (%d) : %s", + condlog(0, "can't format wwid for writing (%d) : %s",
+ ret, strerror(errno)); + ret, strerror(errno));
+ return -1; + return -1;
@ -807,7 +828,7 @@ Index: multipath-tools/multipathd/main.c
} }
if (filter_path(conf, pp) > 0){ if (filter_path(conf, pp) > 0){
int i = find_slot(vecs->pathvec, (void *)pp); int i = find_slot(vecs->pathvec, (void *)pp);
@@ -412,18 +413,26 @@ rescan: @@ -412,18 +413,23 @@ rescan:
condlog(4,"%s: adopting all paths for path %s", condlog(4,"%s: adopting all paths for path %s",
mpp->alias, pp->dev); mpp->alias, pp->dev);
if (adopt_paths(vecs->pathvec, mpp)) if (adopt_paths(vecs->pathvec, mpp))
@ -819,13 +840,10 @@ Index: multipath-tools/multipathd/main.c
mpp->action = ACT_RELOAD; mpp->action = ACT_RELOAD;
} }
else { else {
+ if (conf->find_multipaths) { + if (conf->find_multipaths &&
+ if (should_multipath(pp, vecs->pathvec)) + !should_multipath(pp, vecs->pathvec)) {
+ remember_wwid(pp->wwid); + orphan_path(pp);
+ else { + return 0;
+ orphan_path(pp);
+ 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)))
@ -836,7 +854,7 @@ Index: multipath-tools/multipathd/main.c
} }
/* /*
@@ -432,7 +441,7 @@ rescan: @@ -432,7 +438,7 @@ rescan:
if (setup_map(mpp)) { if (setup_map(mpp)) {
condlog(0, "%s: failed to setup map for addition of new " condlog(0, "%s: failed to setup map for addition of new "
"path %s", mpp->alias, devname); "path %s", mpp->alias, devname);
@ -845,7 +863,7 @@ Index: multipath-tools/multipathd/main.c
} }
/* /*
* reload the map for the multipath mapped device * reload the map for the multipath mapped device
@@ -450,7 +459,7 @@ rescan: @@ -450,7 +456,7 @@ rescan:
goto rescan; goto rescan;
} }
else else
@ -854,7 +872,7 @@ Index: multipath-tools/multipathd/main.c
} }
dm_lib_release(); dm_lib_release();
@@ -458,19 +467,21 @@ rescan: @@ -458,19 +464,21 @@ rescan:
* update our state from kernel regardless of create or reload * update our state from kernel regardless of create or reload
*/ */
if (setup_multipath(vecs, mpp)) if (setup_multipath(vecs, mpp))

View File

@ -187,7 +187,7 @@ Index: multipath-tools/kpartx/kpartx.c
if (safe_sprintf(partname, "%s%s%d", if (safe_sprintf(partname, "%s%s%d",
mapname, delim, j+1)) { mapname, delim, j+1)) {
fprintf(stderr, "partname too small\n"); fprintf(stderr, "partname too small\n");
@@ -493,70 +468,6 @@ main(int argc, char **argv){ @@ -493,72 +468,6 @@ main(int argc, char **argv){
slices[j].minor, slices[j].size, slices[j].minor, slices[j].size,
DM_TARGET, params); DM_TARGET, params);
} }
@ -236,11 +236,13 @@ Index: multipath-tools/kpartx/kpartx.c
- dm_addmap(op, partname, DM_TARGET, params, - dm_addmap(op, partname, DM_TARGET, params,
- slices[j].size, uuid, j+1, - slices[j].size, uuid, j+1,
- buf.st_mode & 0777, - buf.st_mode & 0777,
- buf.st_uid, buf.st_gid); - buf.st_uid, buf.st_gid,
- &cookie);
- -
- if (op == DM_DEVICE_RELOAD) - if (op == DM_DEVICE_RELOAD)
- dm_simplecmd(DM_DEVICE_RESUME, - dm_simplecmd(DM_DEVICE_RESUME,
- partname, 1); - partname, 1,
- &cookie);
- -
- dm_devn(partname, &slices[j].major, - dm_devn(partname, &slices[j].major,
- &slices[j].minor); - &slices[j].minor);

View File

@ -0,0 +1,68 @@
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

@ -0,0 +1,98 @@
---
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

@ -0,0 +1,442 @@
---
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

@ -0,0 +1,57 @@
---
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

@ -0,0 +1,68 @@
---
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

@ -0,0 +1,146 @@
---
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

@ -0,0 +1,23 @@
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

@ -0,0 +1,617 @@
---
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

@ -0,0 +1,53 @@
---
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

@ -0,0 +1,135 @@
---
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

@ -0,0 +1,141 @@
---
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

@ -0,0 +1,46 @@
---
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 */

31
0037-RH-adopt-paths.patch Normal file
View File

@ -0,0 +1,31 @@
---
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

@ -0,0 +1,61 @@
---
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

@ -0,0 +1,251 @@
---
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

@ -0,0 +1,17 @@
---
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

@ -0,0 +1,54 @@
---
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

@ -0,0 +1,17 @@
---
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

@ -0,0 +1,16 @@
---
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

@ -0,0 +1,16 @@
---
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

@ -0,0 +1,25 @@
---
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

@ -0,0 +1,24 @@
---
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

@ -0,0 +1,52 @@
---
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

@ -0,0 +1,114 @@
---
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

@ -0,0 +1,228 @@
---
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

@ -0,0 +1,17 @@
---
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

@ -0,0 +1,154 @@
---
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

@ -0,0 +1,115 @@
---
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

@ -0,0 +1,16 @@
---
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

@ -0,0 +1,41 @@
---
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

@ -0,0 +1,142 @@
---
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

@ -0,0 +1,91 @@
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

@ -0,0 +1,35 @@
---
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

@ -0,0 +1,66 @@
---
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

@ -0,0 +1,68 @@
---
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

@ -0,0 +1,16 @@
--- 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

@ -0,0 +1,77 @@
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

@ -0,0 +1,17 @@
---
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

@ -0,0 +1,19 @@
---
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

@ -0,0 +1,13 @@
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

@ -0,0 +1,79 @@
---
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

@ -0,0 +1,35 @@
---
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

@ -0,0 +1,36 @@
---
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

@ -0,0 +1,89 @@
---
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

@ -0,0 +1,74 @@
---
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

@ -0,0 +1,30 @@
---
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

@ -0,0 +1,20 @@
---
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

@ -0,0 +1,34 @@
---
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

@ -0,0 +1,157 @@
---
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

@ -0,0 +1,31 @@
---
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

@ -0,0 +1,139 @@
---
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

@ -0,0 +1,18 @@
---
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

@ -0,0 +1,49 @@
---
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

@ -0,0 +1,248 @@
---
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

@ -0,0 +1,55 @@
---
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

@ -0,0 +1,31 @@
---
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

@ -0,0 +1,376 @@
---
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

@ -0,0 +1,99 @@
---
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

@ -0,0 +1,160 @@
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

@ -0,0 +1,17 @@
---
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

@ -0,0 +1,92 @@
---
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

@ -0,0 +1,19 @@
---
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

@ -0,0 +1,29 @@
---
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

@ -0,0 +1,58 @@
---
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

@ -0,0 +1,17 @@
---
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

@ -0,0 +1,51 @@
---
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

@ -0,0 +1,64 @@
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

@ -0,0 +1,18 @@
---
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--;

View File

@ -0,0 +1,18 @@
---
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
@@ -999,7 +999,8 @@ int update_path_groups(struct multipath
return 1;
}
dm_lib_release();
- setup_multipath(vecs, mpp);
+ if (setup_multipath(vecs, mpp) != 0)
+ return 1;
sync_map_state(mpp);
return 0;

View File

@ -0,0 +1,30 @@
---
libmultipath/dmparser.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
Index: multipath-tools/libmultipath/dmparser.c
===================================================================
--- multipath-tools.orig/libmultipath/dmparser.c
+++ multipath-tools/libmultipath/dmparser.c
@@ -88,6 +88,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;
@@ -96,9 +97,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",
assemble_features(mp), mp->hwhandler,
- VECTOR_SIZE(mp->pg), mp->bestpg);
+ nr_priority_groups, initial_pg_nr);
if (shift >= freechar) {
fprintf(stderr, "mp->params too small\n");

View File

@ -0,0 +1,151 @@
---
libmultipath/checkers/rdac.c | 92 ++++++++++++++++++++++++++++++++++++++-
libmultipath/prioritizers/rdac.c | 4 +
2 files changed, 95 insertions(+), 1 deletion(-)
Index: multipath-tools/libmultipath/checkers/rdac.c
===================================================================
--- multipath-tools.orig/libmultipath/checkers/rdac.c
+++ multipath-tools/libmultipath/checkers/rdac.c
@@ -12,27 +12,113 @@
#include <errno.h>
#include "checkers.h"
+#include "debug.h"
#include "../libmultipath/sg_include.h"
#define INQUIRY_CMDLEN 6
#define INQUIRY_CMD 0x12
+#define MODE_SENSE_CMD 0x5a
+#define MODE_SELECT_CMD 0x55
+#define MODE_SEN_SEL_CMDLEN 10
#define SENSE_BUFF_LEN 32
#define SCSI_CHECK_CONDITION 0x2
#define SCSI_COMMAND_TERMINATED 0x22
#define SG_ERR_DRIVER_SENSE 0x08
#define RECOVERED_ERROR 0x01
+
+#define CURRENT_PAGE_CODE_VALUES 0
+#define CHANGEABLE_PAGE_CODE_VALUES 1
+
#define MSG_RDAC_UP "rdac checker reports path is up"
#define MSG_RDAC_DOWN "rdac checker reports path is down"
#define MSG_RDAC_GHOST "rdac checker reports path is ghost"
+struct control_mode_page {
+ unsigned char header[8];
+ unsigned char page_code;
+ unsigned char page_len;
+ unsigned char dontcare0[3];
+ unsigned char tas_bit;
+ unsigned char dontcare1[6];
+};
+
struct rdac_checker_context {
void * dummy;
};
int libcheck_init (struct checker * c)
{
+ unsigned char cmd[MODE_SEN_SEL_CMDLEN];
+ unsigned char sense_b[SENSE_BUFF_LEN];
+ struct sg_io_hdr io_hdr;
+ struct control_mode_page current, changeable;
+ int set = 0;
+
+ memset(cmd, 0, MODE_SEN_SEL_CMDLEN);
+ cmd[0] = MODE_SENSE_CMD;
+ cmd[1] = 0x08; /* DBD bit on */
+ cmd[2] = 0xA + (CURRENT_PAGE_CODE_VALUES << 6);
+ cmd[8] = (sizeof(struct control_mode_page) & 0xff);
+
+ memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
+ memset(sense_b, 0, SENSE_BUFF_LEN);
+ memset(&current, 0, sizeof(struct control_mode_page));
+
+ io_hdr.interface_id = 'S';
+ io_hdr.cmd_len = MODE_SEN_SEL_CMDLEN;
+ io_hdr.mx_sb_len = sizeof(sense_b);
+ io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
+ io_hdr.dxfer_len = (sizeof(struct control_mode_page) & 0xff);
+ io_hdr.dxferp = &current;
+ io_hdr.cmdp = cmd;
+ io_hdr.sbp = sense_b;
+ io_hdr.timeout = c->timeout;
+
+ if (ioctl(c->fd, SG_IO, &io_hdr) < 0)
+ goto out;
+
+ /* check the TAS bit to see if it is already set */
+ if ((current.tas_bit >> 6) & 0x1) {
+ set = 1;
+ goto out;
+ }
+
+ /* get the changeble values */
+ cmd[2] = 0xA + (CHANGEABLE_PAGE_CODE_VALUES << 6);
+ io_hdr.dxferp = &changeable;
+ memset(&changeable, 0, sizeof(struct control_mode_page));
+
+ if (ioctl(c->fd, SG_IO, &io_hdr) < 0)
+ goto out;
+
+ /* if TAS bit is not settable exit */
+ if (((changeable.tas_bit >> 6) & 0x1) == 0)
+ goto out;
+
+ /* Now go ahead and set it */
+ memset(cmd, 0, MODE_SEN_SEL_CMDLEN);
+ cmd[0] = MODE_SELECT_CMD;
+ cmd[1] = 0x1; /* set SP bit on */
+ cmd[8] = (sizeof(struct control_mode_page) & 0xff);
+
+ /* use the same buffer as current, only set the tas bit */
+ current.page_code = 0xA;
+ current.page_len = 0xA;
+ current.tas_bit |= (1 << 6);
+
+ io_hdr.dxfer_direction = SG_DXFER_TO_DEV;
+ io_hdr.dxferp = &current;
+
+ if (ioctl(c->fd, SG_IO, &io_hdr) < 0)
+ goto out;
+
+ /* Success */
+ set = 1;
+out:
+ if (set == 0)
+ condlog(0, "rdac checker failed to set TAS bit");
return 0;
}
@@ -132,7 +218,11 @@ libcheck_check (struct checker * c)
goto done;
}
- ret = ((inq.avtcvp & 0x1) ? PATH_UP : PATH_GHOST);
+ /* If owner set or ioship mode is enabled return PATH_UP always */
+ if ((inq.avtcvp & 0x1) || ((inq.avtcvp >> 5) & 0x1))
+ ret = PATH_UP;
+ else
+ ret = PATH_GHOST;
done:
switch (ret) {
Index: multipath-tools/libmultipath/prioritizers/rdac.c
===================================================================
--- multipath-tools.orig/libmultipath/prioritizers/rdac.c
+++ multipath-tools/libmultipath/prioritizers/rdac.c
@@ -81,6 +81,10 @@ int rdac_prio(const char *dev, int fd)
break;
}
+ /* For ioship mode set the bit 3 (00001000) */
+ if ((sense_buffer[8] >> 5) & 0x01)
+ ret |= 0x08;
+
out:
return(ret);
}

View File

@ -0,0 +1,17 @@
---
multipathd/main.c | 2 ++
1 file changed, 2 insertions(+)
Index: multipath-tools/multipathd/main.c
===================================================================
--- multipath-tools.orig/multipathd/main.c
+++ multipath-tools/multipathd/main.c
@@ -1155,6 +1155,8 @@ checkerloop (void *ap)
block_signal(SIGHUP, &old);
pthread_cleanup_push(cleanup_lock, &vecs->lock);
lock(vecs->lock);
+ /* check to see if we are exiting */
+ pthread_testcancel();
condlog(4, "tick");
if (vecs->pathvec) {

View File

@ -0,0 +1,18 @@
---
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
@@ -1118,7 +1118,8 @@ check_path (struct vectors * vecs, struc
condlog(4, "path prio refresh");
if (update_prio(pp, new_path_up) &&
pp->mpp->pgpolicyfn == (pgpolicyfn *)group_by_prio &&
- pp->mpp->pgfailback != -FAILBACK_FOLLOWOVER)
+ (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE ||
+ pp->mpp->pgfailback > 0))
update_path_groups(pp->mpp, vecs, !new_path_up);
else if (need_switch_pathgroup(pp->mpp, 0)) {
if (pp->mpp->pgfailback > 0 &&

View File

@ -0,0 +1,17 @@
---
libmultipath/discovery.c | 2 ++
1 file changed, 2 insertions(+)
Index: multipath-tools/libmultipath/discovery.c
===================================================================
--- multipath-tools.orig/libmultipath/discovery.c
+++ multipath-tools/libmultipath/discovery.c
@@ -297,6 +297,8 @@ sysfs_set_scsi_tmo (struct multipath *mp
return 1;
}
if (mpp->dev_loss){
+ if (mpp->dev_loss > 600 && mpp->fast_io_fail <= 0)
+ condlog(2, "you must enable fast_io_fail_tmo in order to set dev_loss_tmo greater than 600");
snprintf(value, 11, "%u", mpp->dev_loss);
if (sysfs_attr_set_value(attr_path, "dev_loss_tmo",
value))

View File

@ -0,0 +1,162 @@
---
libmultipath/dict.c | 12 +++++-----
multipath.conf.annotated | 53 ---------------------------------------------
multipath.conf.synthetic | 3 --
multipath/multipath.conf.5 | 18 ---------------
4 files changed, 6 insertions(+), 80 deletions(-)
Index: multipath-tools/libmultipath/dict.c
===================================================================
--- multipath-tools.orig/libmultipath/dict.c
+++ multipath-tools/libmultipath/dict.c
@@ -2204,13 +2204,13 @@ init_keywords(void)
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);
- 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);
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("mode", &def_mode_handler, &snprint_def_mode);
+ __deprecated install_keyword("uid", &def_uid_handler, &snprint_def_uid);
+ __deprecated install_keyword("gid", &def_gid_handler, &snprint_def_gid);
__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);
@@ -2283,9 +2283,9 @@ init_keywords(void)
install_keyword("rr_min_io", &mp_minio_handler, &snprint_mp_rr_min_io);
install_keyword("pg_timeout", &mp_pg_timeout_handler, &snprint_mp_pg_timeout);
install_keyword("flush_on_last_del", &mp_flush_on_last_del_handler, &snprint_mp_flush_on_last_del);
- 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);
+ __deprecated install_keyword("mode", &mp_mode_handler, &snprint_mp_mode);
+ __deprecated install_keyword("uid", &mp_uid_handler, &snprint_mp_uid);
+ __deprecated install_keyword("gid", &mp_gid_handler, &snprint_mp_gid);
install_keyword("prio", &mp_prio_handler, &snprint_mp_prio);
install_sublevel_end();
}
Index: multipath-tools/multipath.conf.annotated
===================================================================
--- multipath-tools.orig/multipath.conf.annotated
+++ multipath-tools/multipath.conf.annotated
@@ -176,32 +176,6 @@
# user_friendly_names no
#
# #
-# # name : mode
-# # scope : multipath
-# # desc : The mode to use for the multipath device nodes, in octal.
-# # values : 0000 - 0777
-# # default : determined by the process
-# mode 0644
-#
-# #
-# # name : uid
-# # scope : multipath
-# # desc : The user id to use for the multipath device nodes. You
-# # may use either the numeric or symbolic uid
-# # values : <user_id>
-# # default : determined by the process
-# uid 0
-#
-# #
-# # name : gid
-# # scope : multipath
-# # desc : The group id to user for the multipath device nodes. You
-# # may use either the numeric or symbolic gid
-# # values : <group_id>
-# # default : determined by the process
-# gid disk
-#
-# #
# # name : checker_timeout
# # scope : multipath & multipathd
# # desc : The timeout to use for path checkers that issue scsi
@@ -369,33 +343,6 @@
# #
# flush_on_last_del yes
#
-# #
-# # name : mode
-# # scope : multipath
-# # desc : The mode to use for the multipath device nodes, in
-# # octal.
-# # values : 0000 - 0777
-# # default : determined by the process
-# mode 0644
-#
-# #
-# # name : uid
-# # scope : multipath
-# # desc : The user id to use for the multipath device nodes.
-# # You may use either the numeric or symbolic uid
-# # values : <user_id>
-# # default : determined by the process
-# uid 0
-#
-# #
-# # name : gid
-# # scope : multipath
-# # desc : The group id to user for the multipath device nodes.
-# # You may use either the numeric or symbolic gid
-# # values : <group_id>
-# # default : determined by the process
-# gid 0
-#
# }
# multipath {
# wwid 1DEC_____321816758474
Index: multipath-tools/multipath.conf.synthetic
===================================================================
--- multipath-tools.orig/multipath.conf.synthetic
+++ multipath-tools/multipath.conf.synthetic
@@ -18,9 +18,6 @@
# no_path_retry fail
# queue_without_daemon no
# user_friendly_names no
-# mode 644
-# uid 0
-# gid disk
#}
#blacklist {
# wwid 26353900f02796769
Index: multipath-tools/multipath/multipath.conf.5
===================================================================
--- multipath-tools.orig/multipath/multipath.conf.5
+++ multipath-tools/multipath/multipath.conf.5
@@ -335,18 +335,6 @@ will disable the timeout.
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.
-.TP
.B log_checker_err
If set to
.I once
@@ -446,12 +434,6 @@ section:
.B rr_weight
.TP
.B flush_on_last_del
-.TP
-.B mode
-.TP
-.B uid
-.TP
-.B gid
.RE
.PD
.LP

View File

@ -0,0 +1,173 @@
---
kpartx/devmapper.c | 14 +++++++++++---
kpartx/devmapper.h | 2 +-
kpartx/kpartx.c | 15 +++++++++++----
libmultipath/config.h | 1 +
libmultipath/devmapper.c | 12 ++++++++++--
multipath/main.c | 5 ++++-
6 files changed, 38 insertions(+), 11 deletions(-)
Index: multipath-tools/kpartx/devmapper.c
===================================================================
--- multipath-tools.orig/kpartx/devmapper.c
+++ multipath-tools/kpartx/devmapper.c
@@ -52,7 +52,8 @@ dm_prereq (char * str, int x, int y, int
}
extern int
-dm_simplecmd (int task, const char *name, int no_flush, uint32_t *cookie) {
+dm_simplecmd (int task, const char *name, int no_flush, uint32_t *cookie,
+ int force_udev_rules) {
int r = 0;
int udev_wait_flag = (task == DM_DEVICE_RESUME ||
task == DM_DEVICE_REMOVE);
@@ -70,8 +71,15 @@ 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;
+ if (udev_wait_flag) {
+ if (!dm_task_set_cookie(dmt, cookie, (force_udev_rules)? 0 :
+ DM_UDEV_DISABLE_DISK_RULES_FLAG))
+ goto out;
+ }
+ else if (task == DM_DEVICE_RESUME && dm_cookie_supported() &&
+ !force_udev_rules)
+ dm_task_set_event_nr(dmt, DM_UDEV_DISABLE_DISK_RULES_FLAG <<
+ DM_UDEV_FLAGS_SHIFT);
r = dm_task_run(dmt);
out:
Index: multipath-tools/kpartx/devmapper.h
===================================================================
--- multipath-tools.orig/kpartx/devmapper.h
+++ multipath-tools/kpartx/devmapper.h
@@ -3,7 +3,7 @@
#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, uint32_t *);
+int dm_simplecmd (int, const char *, int, uint32_t *, int);
int dm_addmap (int, const char *, const char *, const char *, uint64_t,
const char *, int, mode_t, uid_t, gid_t, uint32_t *);
int dm_map_present (char *);
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:s";
+static char short_opts[] = "ladgvp:t:su";
/* Used in gpt.c */
int force_gpt=0;
@@ -184,7 +184,8 @@ get_hotplug_device(void)
}
int
-main(int argc, char **argv){
+main(int argc, char **argv)
+{
int fd, i, j, k, n, op, off, arg;
struct slice all;
struct pt *ptp;
@@ -202,6 +203,7 @@ main(int argc, char **argv){
int sync = 0;
struct stat buf;
uint32_t cookie = 0;
+ int force_udev_rules = 0;
initpts();
init_crc32();
@@ -257,6 +259,9 @@ main(int argc, char **argv){
case 's':
sync = 1;
break;
+ case 'u':
+ force_udev_rules = 1;
+ break;
default:
usage();
exit(1);
@@ -404,7 +409,8 @@ main(int argc, char **argv){
continue;
if (!dm_simplecmd(DM_DEVICE_REMOVE, partname,
- 0, &cookie)) {
+ 0, &cookie,
+ force_udev_rules)) {
r++;
continue;
}
@@ -454,7 +460,8 @@ main(int argc, char **argv){
}
if (op == DM_DEVICE_RELOAD &&
!dm_simplecmd(DM_DEVICE_RESUME, partname,
- 1, &cookie)) {
+ 1, &cookie,
+ force_udev_rules)) {
fprintf(stderr, "resume failed on %s\n",
partname);
r++;
Index: multipath-tools/libmultipath/config.h
===================================================================
--- multipath-tools.orig/libmultipath/config.h
+++ multipath-tools/libmultipath/config.h
@@ -90,6 +90,7 @@ struct config {
int find_multipaths;
int allow_queueing;
int log_checker_err;
+ int force_udev_rules;
uid_t uid;
gid_t gid;
mode_t mode;
Index: multipath-tools/libmultipath/devmapper.c
===================================================================
--- multipath-tools.orig/libmultipath/devmapper.c
+++ multipath-tools/libmultipath/devmapper.c
@@ -168,8 +168,16 @@ 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;
+ if (udev_wait_flag) {
+ if (!dm_task_set_cookie(dmt, &conf->cookie,
+ (conf->force_udev_rules)? 0 :
+ DM_UDEV_DISABLE_DISK_RULES_FLAG))
+ goto out;
+ }
+ else if (task == DM_DEVICE_RESUME && dm_cookie_supported() &&
+ !conf->force_udev_rules)
+ dm_task_set_event_nr(dmt, DM_UDEV_DISABLE_DISK_RULES_FLAG <<
+ DM_UDEV_FLAGS_SHIFT);
r = dm_task_run (dmt);
out:
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:Brq")) != EOF ) {
+ while ((arg = getopt(argc, argv, ":dchl::FfM:v:p:b:Brqu")) != EOF ) {
switch(arg) {
case 1: printf("optarg : %s\n",optarg);
break;
@@ -439,6 +439,9 @@ main (int argc, char *argv[])
case 'r':
conf->force_reload = 1;
break;
+ case 'u':
+ conf->force_udev_rules = 1;
+ break;
case 'h':
usage(argv[0]);
case ':':

View File

@ -0,0 +1,58 @@
---
Makefile.inc | 1 +
multipathd/Makefile | 2 ++
multipathd/multipathd.service | 14 ++++++++++++++
3 files changed, 17 insertions(+)
Index: multipath-tools/Makefile.inc
===================================================================
--- multipath-tools.orig/Makefile.inc
+++ multipath-tools/Makefile.inc
@@ -31,6 +31,7 @@ man5dir = $(prefix)/usr/share/man/ma
rcdir = $(prefix)/etc/rc.d/init.d
syslibdir = $(prefix)/$(LIB)
libdir = $(prefix)/$(LIB)/multipath
+unitdir = $(prefix)/lib/systemd/system
GZIP = /bin/gzip -9 -c
INSTALL_PROGRAM = install
Index: multipath-tools/multipathd/Makefile
===================================================================
--- multipath-tools.orig/multipathd/Makefile
+++ multipath-tools/multipathd/Makefile
@@ -36,6 +36,8 @@ install:
$(INSTALL_PROGRAM) -m 755 $(EXEC) $(DESTDIR)$(bindir)
$(INSTALL_PROGRAM) -d $(DESTDIR)$(rcdir)
$(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) -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir)
@@ -43,6 +45,7 @@ uninstall:
rm -f $(DESTDIR)$(bindir)/$(EXEC)
rm -f $(DESTDIR)$(rcdir)/$(EXEC)
rm -f $(DESTDIR)$(mandir)/$(EXEC).8.gz
+ rm -f $(DESTDIR)$(unitdir)/$(EXEC).service
clean:
rm -f core *.o $(EXEC) *.gz
Index: multipath-tools/multipathd/multipathd.service
===================================================================
--- /dev/null
+++ multipath-tools/multipathd/multipathd.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Device-Mapper Multipath Device Controller
+Before=iscsi.service iscsid.service
+After=syslog.target
+
+[Service]
+Type=forking
+PIDFile=/var/run/multipathd.pid
+ExecStart=/sbin/multipathd
+ExecReload=/bin/kill -HUP $MAINPID
+#ExecStop=/path/to/scrip delete-me if not necessary
+
+[Install]
+WantedBy=multi-user.target

View File

@ -1,7 +1,7 @@
Summary: Tools to manage multipath devices using device-mapper Summary: Tools to manage multipath devices using device-mapper
Name: device-mapper-multipath Name: device-mapper-multipath
Version: 0.4.9 Version: 0.4.9
Release: 15%{?dist} Release: 16%{?dist}
License: GPL+ License: GPL+
Group: System Environment/Base Group: System Environment/Base
URL: http://christophe.varoqui.free.fr/ URL: http://christophe.varoqui.free.fr/
@ -37,20 +37,98 @@ Patch1021: 0021-RHBZ-548874-add-find-multipaths.patch
Patch1022: 0022-RHBZ-557845-RHEL5-style-partitions.patch Patch1022: 0022-RHBZ-557845-RHEL5-style-partitions.patch
Patch1023: 0023-RHBZ-557810-emc-invista-config.patch Patch1023: 0023-RHBZ-557810-emc-invista-config.patch
Patch1024: 0024-RHBZ-565933-checker-timeout.patch Patch1024: 0024-RHBZ-565933-checker-timeout.patch
Patch1025: 0025-RHBZ-508827-update-multipathd-manpage.patch
Patch1026: 0026-RHBZ-549636-default-path-selector.patch
Patch1027: 0027-RHBZ-509443-enhance-show-config.patch
Patch1028: 0028-RHBZ-452617-add-revision-parameter.patch
Patch1029: 0029-RHBZ-567219-recalculate-pgs-in-checkerloop.patch
Patch1030: 0030-RHBZ-558636-check-if-multipath-owns-path.patch
Patch1031: 0031-RHBZ-570546-display-avg-pg-prio.patch
Patch1032: 0032-RHBZ-575767-ontap_prio.patch
Patch1033: 0033-RHBZ-573715-eurologic-config.patch
Patch1034: 0034-RHBZ-579575-add-q-multipath-option.patch
Patch1035: 0035-RHBZ-467709-add-followover.patch
Patch1036: 0036-RH-clear-messages.patch
Patch1037: 0037-RH-adopt-paths.patch
Patch1038: 0038-RHBZ-587201-IBM-SGI.patch
Patch1039: 0039-RHBZ-589153-manpage-update.patch
Patch1040: 0040-RHBZ-587695-add-checker-msg-alias.patch
Patch1041: 0041-RHBZ-587695-add-rdac-message.patch
Patch1042: 0042-RHBZ-590038-fix-fast-io-fail-tmo.patch
Patch1043: 0043-RHBZ-590028-close-sysfs_attr_fd.patch
Patch1044: 0044-RHBZ-591940-dont-clear-daemon.patch
Patch1045: 0045-RHBZ-593379-dont-add-unknown-paths.patch
Patch1046: 0046-RHBZ-593426-move-adopt-path.patch
Patch1047: 0047-RHBZ-591608-only-switch-pgs-once.patch
Patch1048: 0048-RHBZ-592494-fix-user-configs.patch
Patch1049: 0049-RHBZ-591644-enhance-mpathconf.patch
Patch1050: 0050-RHBZ-595400-fix-checker-tmo.patch
Patch1051: 0051-RHBZ-596156-mpathconf-man-page.patch
Patch1052: 0052-RHBZ-601247-fix-path-adoption.patch
Patch1053: 0053-RHBZ-596323-remember_more_wwids.patch
Patch1054: 0054-RHBZ-596319-rules-cleanup.patch
Patch1055: 0055-RHBZ-602257-update-on-show-topology.patch
Patch1056: 0056-RHBZ-603812-better-type-check.patch
Patch1057: 0057-RHBZ-607869-fix-resize.patch
Patch1058: 0058-RHBZ-601665-assemble-features.patch
Patch1059: 0059-RHBZ-607874-handle-offlined-paths.patch
Patch1060: 0060-RHBZ-606420-fix-remove-map.patch
Patch1061: 0061-RHBZ-620479-find-rport.patch
Patch1062: 0062-RHBZ-592998-hpsc-config.patch
Patch1063: 0063-RHBZ-595719-udev_link_priority.patch
Patch1064: 0064-RHBZ-612173-fix-reverse-lookup.patch
Patch1065: 0065-RHBZ-635088-update-priority.patch
Patch1066: 0066-RHBZ-636071-mpathconf-variable_names.patch
Patch1067: 0067-RHBZ-622569-symmetrix-config.patch
Patch1068: 0068-RHBZ-632734-nvdisk-config.patch
Patch1069: 0069-RHBZ-636246-hp-open-config.patch
Patch1070: 0070-RHBZ-639037-hitachi-open-config.patch
Patch1071: 0071-RHBZ-611779-fix-whitespace-crash.patch
Patch1072: 0072-RHBZ-651389-change-scsi-tmo-order.patch
Patch1073: 0073-RHBZ-650664-clarify-error-msg.patch
Patch1074: 0074-RHBZ-602883-dont-print-change.patch
Patch1075: 0075-RHBZ-576919-log-checker-err.patch
Patch1076: 0076-RHBZ-599690-update-multipath-conf.patch
Patch1077: 0077-RHBZ-622608-nvdisk-config.patch
Patch1078: 0078-RHBZ-628095-config-warnings.patch
Patch1079: 0079-RHBZ-650797-display-iscsi-tgt-name.patch
Patch1080: 0080-RHBZ-662731-fix-no-config-value-segfault.patch
Patch1081: 0081-RHBZ-623644-fix-sysfs-caching.patch
Patch1083: 0083-RHBZ-636213-633643-new-configs.patch
Patch1084: 0084-RHBZ-644111-read-only-bindings.patch
Patch1085: 0085-RHBZ-645605-fix-offline-check.patch
Patch1086: 0086-RHBZ-681144-sysfs-device-cleanup.patch
Patch1087: 0087-RHBZ-680480-skip-if-no-sysdev.patch
Patch1088: 0088-RHBZ-693524-fix-prio-segfault.patch
Patch1089: 0089-RHBZ-694602-RSSM-config.patch
Patch1090: 0090-RHBZ-700169-fix-nr-active.patch
Patch1091: 0091-RHBZ-699577-manpage-clarification.patch
Patch1092: 0092-RHBZ-689504-rdac-retry.patch
Patch1093: 0093-RHBZ-677449-dont-remove-map-on-enomem.patch
Patch1094: 0094-RHBZ-707560-check-return-value.patch
Patch1095: 0095-RHBZ-678673-no-path-groups.patch
Patch1096: 0096-RHBZ-683616-ioship-support.patch
Patch1097: 0097-RHBZ-697386-fix-shutdown-crash.patch
Patch1098: 0098-RHBZ-706555-dont-update-pgs-in-manual.patch
Patch1099: 0099-RHBZ-705854-warn-on-bad-dev-loss-tmo.patch
Patch1100: 0100-RHBZ-710478-deprecate-uid-gid-mode.patch
Patch1101: 0101-RHBZ-631009-disable-udev-disk-rules-on-reload.patch
Patch1102: 0102-RHBZ-690828-systemd-unit-file.patch
# runtime # runtime
Requires: %{name}-libs = %{version}-%{release} Requires: %{name}-libs = %{version}-%{release}
Requires: kpartx = %{version}-%{release} Requires: kpartx = %{version}-%{release}
Requires: device-mapper >= 1.02.39-1 Requires: device-mapper >= 1.02.39-1
Requires(post): chkconfig Requires: udev initscripts
Requires(preun): chkconfig Requires(post): systemd-units systemd-sysv chkconfig
Requires(preun): initscripts Requires(preun): systemd-units
Requires(postun): initscripts Requires(postun): systemd-units
# build/setup # build/setup
BuildRequires: libaio-devel, device-mapper-devel >= 1.02.39-1 BuildRequires: libaio-devel, device-mapper-devel >= 1.02.39-1
BuildRequires: libselinux-devel, libsepol-devel BuildRequires: libselinux-devel, libsepol-devel
BuildRequires: readline-devel, ncurses-devel BuildRequires: readline-devel, ncurses-devel
BuildRequires: systemd-units
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
@ -71,6 +149,14 @@ The %{name}-libs provides the path checker
and prioritizer modules. It also contains the multipath shared library, and prioritizer modules. It also contains the multipath shared library,
libmultipath. libmultipath.
%package sysvinit
Summary: SysV init script for device-mapper-multipath
Group: System Environment/Libraries
%description sysvinit
SysV style init script for device-mapper-multipth. It needs to be
installed only if systemd is not used as the system init process.
%package -n kpartx %package -n kpartx
Summary: Partition device manager for device-mapper devices Summary: Partition device manager for device-mapper devices
Group: System Environment/Base Group: System Environment/Base
@ -107,6 +193,83 @@ kpartx manages partition creation and removal for device-mapper devices.
%patch1022 -p1 %patch1022 -p1
%patch1023 -p1 %patch1023 -p1
%patch1024 -p1 %patch1024 -p1
%patch1025 -p1
%patch1026 -p1
%patch1027 -p1
%patch1028 -p1
%patch1029 -p1
%patch1030 -p1
%patch1031 -p1
%patch1032 -p1
%patch1033 -p1
%patch1034 -p1
%patch1035 -p1
%patch1036 -p1
%patch1037 -p1
%patch1038 -p1
%patch1039 -p1
%patch1040 -p1
%patch1041 -p1
%patch1042 -p1
%patch1043 -p1
%patch1044 -p1
%patch1045 -p1
%patch1046 -p1
%patch1047 -p1
%patch1048 -p1
%patch1049 -p1
%patch1050 -p1
%patch1051 -p1
%patch1052 -p1
%patch1053 -p1
%patch1054 -p1
%patch1055 -p1
%patch1056 -p1
%patch1057 -p1
%patch1058 -p1
%patch1059 -p1
%patch1060 -p1
%patch1061 -p1
%patch1062 -p1
%patch1063 -p1
%patch1064 -p1
%patch1065 -p1
%patch1066 -p1
%patch1067 -p1
%patch1068 -p1
%patch1069 -p1
%patch1070 -p1
%patch1071 -p1
%patch1072 -p1
%patch1073 -p1
%patch1074 -p1
%patch1075 -p1
%patch1076 -p1
%patch1077 -p1
%patch1078 -p1
%patch1079 -p1
%patch1080 -p1
%patch1081 -p1
%patch1083 -p1
%patch1084 -p1
%patch1085 -p1
%patch1086 -p1
%patch1087 -p1
%patch1088 -p1
%patch1089 -p1
%patch1090 -p1
%patch1091 -p1
%patch1092 -p1
%patch1093 -p1
%patch1094 -p1
%patch1095 -p1
%patch1096 -p1
%patch1097 -p1
%patch1098 -p1
%patch1099 -p1
%patch1100 -p1
%patch1101 -p1
%patch1102 -p1
cp %{SOURCE1} . cp %{SOURCE1} .
%build %build
@ -123,7 +286,8 @@ make install \
bindir=%{_sbindir} \ bindir=%{_sbindir} \
syslibdir=%{_libdir} \ syslibdir=%{_libdir} \
libdir=%{_libmpathdir} \ libdir=%{_libmpathdir} \
rcdir=%{_initrddir} rcdir=%{_initrddir} \
unitdir=%{_unitdir}
# tree fix up # tree fix up
# install -m 0644 %{SOURCE1} %{buildroot}/etc/multipath.conf # install -m 0644 %{SOURCE1} %{buildroot}/etc/multipath.conf
@ -133,34 +297,42 @@ install -d %{buildroot}/etc/multipath
rm -rf %{buildroot} rm -rf %{buildroot}
%post %post
/sbin/chkconfig --add multipathd if [ $1 -eq 1 ] ; then
if [ "$1" -gt "1" -a ! -e /etc/multipath/bindings -a \ /bin/systemctl enable multipathd.service >/dev/null 2>&1 || :
-f /var/lib/multipath/bindings ]; then
mv /var/lib/multipath/bindings /etc/multipath/bindings
ln -s /etc/multipath/bindings /var/lib/multipath/bindings
fi fi
%preun %preun
if [ "$1" = 0 ]; then if [ $1 -eq 0 ] ; then
/sbin/service multipathd stop /dev/null 2>&1 /bin/systemctl --no-reload disable multipathd.service > /dev/null 2>&1 || :
/sbin/chkconfig --del multipathd bin/systemctl stop multipathd.service > /dev/null 2>&1 || :
fi fi
%postun %postun
if [ "$1" -ge "1" ]; then /bin/systemctl daemon-reload >/dev/null 2>&1 || :
/sbin/service multipathd condrestart >/dev/null 2>&1 || : if [ $1 -ge 1 ] ; then
/bin/systemctl try-restart multipathd.service >/dev/null 2>&1 || :
fi fi
%triggerun -- %{name} < 0.4.9-16
%{_bindir}/systemd-sysv-convert --save multipathd >/dev/null 2>&1 ||:
bin/systemctl --no-reload enable multipathd.service >/dev/null 2>&1 ||:
/sbin/chkconfig --del multipathd >/dev/null 2>&1 || :
/bin/systemctl try-restart multipathd.service >/dev/null 2>&1 || :
%triggerpostun -n %{name}-sysvinit -- %{name} < 0.4.9-16
/sbin/chkconfig --add mdmonitor >/dev/null 2>&1 || :
%files %files
%defattr(-,root,root,-) %defattr(-,root,root,-)
%{_sbindir}/multipath %{_sbindir}/multipath
%{_sbindir}/multipathd %{_sbindir}/multipathd
%{_sbindir}/cciss_id %{_sbindir}/cciss_id
%{_sbindir}/mpathconf %{_sbindir}/mpathconf
%{_initrddir}/multipathd %{_unitdir}/multipathd.service
%{_mandir}/man5/multipath.conf.5.gz %{_mandir}/man5/multipath.conf.5.gz
%{_mandir}/man8/multipath.8.gz %{_mandir}/man8/multipath.8.gz
%{_mandir}/man8/multipathd.8.gz %{_mandir}/man8/multipathd.8.gz
%{_mandir}/man8/mpathconf.8.gz
%config /lib/udev/rules.d/40-multipath.rules %config /lib/udev/rules.d/40-multipath.rules
%doc AUTHOR COPYING FAQ %doc AUTHOR COPYING FAQ
%doc multipath.conf multipath.conf.annotated %doc multipath.conf multipath.conf.annotated
@ -178,12 +350,28 @@ fi
%postun libs -p /sbin/ldconfig %postun libs -p /sbin/ldconfig
%files sysvinit
%{_initrddir}/multipathd
%files -n kpartx %files -n kpartx
%defattr(-,root,root,-) %defattr(-,root,root,-)
/sbin/kpartx /sbin/kpartx
%{_mandir}/man8/kpartx.8.gz %{_mandir}/man8/kpartx.8.gz
%changelog %changelog
* Fri Jul 15 2011 Benjamin Marzinski <bmarzins@redhat.com> -0.4.9-16
- Modify 0012-RH-udev-sync-support.patch
- Modify 0021-RHBZ-548874-add-find-multipaths.patch
- Modify 0022-RHBZ-557845-RHEL5-style-partitions.patch
- Add 0025-RHBZ-508827-update-multipathd-manpage.patch through
0101-RHBZ-631009-disable-udev-disk-rules-on-reload.patch
* sync with current state of RHEL6. Next release should include a updated
source tarball with most of these fixes rolled in.
- Add 0102-RHBZ-690828-systemd-unit-file.patch
* Add Jóhann B. Guðmundsson's unit file for systemd.
* Add sub-package sysvinit for SysV init script.
- Resolves: bz #690828
* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.9-15 * Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.9-15
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild