From b0ec4a42c85b8a4962352eddffcba84132a2eb78 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Fri, 15 Jul 2011 12:25:48 -0500 Subject: [PATCH] =?UTF-8?q?Modify=200012-RH-udev-sync-support.patch=20Modi?= =?UTF-8?q?fy=200021-RHBZ-548874-add-find-multipaths.patch=20Modify=200022?= =?UTF-8?q?-RHBZ-557845-RHEL5-style-partitions.patch=20Add=200025-RHBZ-508?= =?UTF-8?q?827-update-multipathd-manpage.patch=20through=20=20=20=20=20010?= =?UTF-8?q?1-RHBZ-631009-disable-udev-disk-rules-on-reload.patch=20=20=20*?= =?UTF-8?q?=20sync=20with=20current=20state=20of=20RHEL6.=20Next=20release?= =?UTF-8?q?=20should=20include=20a=20updated=20=20=20=20=20source=20tarbal?= =?UTF-8?q?l=20with=20most=20of=20these=20fixes=20rolled=20in.=20Add=20010?= =?UTF-8?q?2-RHBZ-690828-systemd-unit-file.patch=20=20=20*=20Add=20J=C3=B3?= =?UTF-8?q?hann=20B.=20Gu=C3=B0mundsson's=20unit=20file=20for=20systemd.?= =?UTF-8?q?=20=20=20*=20Add=20sub-package=20sysvinit=20for=20SysV=20init?= =?UTF-8?q?=20script.=20Resolves:=20bz=20#690828?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 0012-RH-udev-sync-support.patch | 22 +- 0021-RHBZ-548874-add-find-multipaths.patch | 94 +-- 0022-RHBZ-557845-RHEL5-style-partitions.patch | 8 +- ...HBZ-508827-update-multipathd-manpage.patch | 68 ++ 0026-RHBZ-549636-default-path-selector.patch | 98 +++ 0027-RHBZ-509443-enhance-show-config.patch | 442 +++++++++++++ 0028-RHBZ-452617-add-revision-parameter.patch | 57 ++ ...67219-recalculate-pgs-in-checkerloop.patch | 68 ++ ...-558636-check-if-multipath-owns-path.patch | 146 +++++ 0031-RHBZ-570546-display-avg-pg-prio.patch | 23 + 0032-RHBZ-575767-ontap_prio.patch | 617 ++++++++++++++++++ 0033-RHBZ-573715-eurologic-config.patch | 53 ++ 0034-RHBZ-579575-add-q-multipath-option.patch | 135 ++++ 0035-RHBZ-467709-add-followover.patch | 141 ++++ 0036-RH-clear-messages.patch | 46 ++ 0037-RH-adopt-paths.patch | 31 + 0038-RHBZ-587201-IBM-SGI.patch | 61 ++ 0039-RHBZ-589153-manpage-update.patch | 251 +++++++ 0040-RHBZ-587695-add-checker-msg-alias.patch | 17 + 0041-RHBZ-587695-add-rdac-message.patch | 54 ++ 0042-RHBZ-590038-fix-fast-io-fail-tmo.patch | 17 + 0043-RHBZ-590028-close-sysfs_attr_fd.patch | 16 + 0044-RHBZ-591940-dont-clear-daemon.patch | 16 + 0045-RHBZ-593379-dont-add-unknown-paths.patch | 25 + 0046-RHBZ-593426-move-adopt-path.patch | 24 + 0047-RHBZ-591608-only-switch-pgs-once.patch | 52 ++ 0048-RHBZ-592494-fix-user-configs.patch | 114 ++++ 0049-RHBZ-591644-enhance-mpathconf.patch | 228 +++++++ 0050-RHBZ-595400-fix-checker-tmo.patch | 17 + 0051-RHBZ-596156-mpathconf-man-page.patch | 154 +++++ 0052-RHBZ-601247-fix-path-adoption.patch | 115 ++++ 0053-RHBZ-596323-remember_more_wwids.patch | 16 + 0054-RHBZ-596319-rules-cleanup.patch | 41 ++ ...-RHBZ-602257-update-on-show-topology.patch | 142 ++++ 0056-RHBZ-603812-better-type-check.patch | 91 +++ 0057-RHBZ-607869-fix-resize.patch | 35 + 0058-RHBZ-601665-assemble-features.patch | 66 ++ 0059-RHBZ-607874-handle-offlined-paths.patch | 68 ++ 0060-RHBZ-606420-fix-remove-map.patch | 16 + 0061-RHBZ-620479-find-rport.patch | 77 +++ 0062-RHBZ-592998-hpsc-config.patch | 17 + 0063-RHBZ-595719-udev_link_priority.patch | 19 + 0064-RHBZ-612173-fix-reverse-lookup.patch | 13 + 0065-RHBZ-635088-update-priority.patch | 79 +++ ...RHBZ-636071-mpathconf-variable_names.patch | 35 + 0067-RHBZ-622569-symmetrix-config.patch | 36 + 0068-RHBZ-632734-nvdisk-config.patch | 89 +++ 0069-RHBZ-636246-hp-open-config.patch | 74 +++ 0070-RHBZ-639037-hitachi-open-config.patch | 30 + 0071-RHBZ-611779-fix-whitespace-crash.patch | 20 + 0072-RHBZ-651389-change-scsi-tmo-order.patch | 34 + 0073-RHBZ-650664-clarify-error-msg.patch | 157 +++++ 0074-RHBZ-602883-dont-print-change.patch | 31 + 0075-RHBZ-576919-log-checker-err.patch | 139 ++++ 0076-RHBZ-599690-update-multipath-conf.patch | 18 + 0077-RHBZ-622608-nvdisk-config.patch | 49 ++ 0078-RHBZ-628095-config-warnings.patch | 248 +++++++ 0079-RHBZ-650797-display-iscsi-tgt-name.patch | 55 ++ ...-662731-fix-no-config-value-segfault.patch | 31 + 0081-RHBZ-623644-fix-sysfs-caching.patch | 376 +++++++++++ 0083-RHBZ-636213-633643-new-configs.patch | 99 +++ 0084-RHBZ-644111-read-only-bindings.patch | 160 +++++ 0085-RHBZ-645605-fix-offline-check.patch | 17 + 0086-RHBZ-681144-sysfs-device-cleanup.patch | 92 +++ 0087-RHBZ-680480-skip-if-no-sysdev.patch | 19 + 0088-RHBZ-693524-fix-prio-segfault.patch | 29 + 0089-RHBZ-694602-RSSM-config.patch | 58 ++ 0090-RHBZ-700169-fix-nr-active.patch | 17 + 0091-RHBZ-699577-manpage-clarification.patch | 51 ++ 0092-RHBZ-689504-rdac-retry.patch | 64 ++ ...HBZ-677449-dont-remove-map-on-enomem.patch | 18 + 0094-RHBZ-707560-check-return-value.patch | 18 + 0095-RHBZ-678673-no-path-groups.patch | 30 + 0096-RHBZ-683616-ioship-support.patch | 151 +++++ 0097-RHBZ-697386-fix-shutdown-crash.patch | 17 + ...HBZ-706555-dont-update-pgs-in-manual.patch | 18 + ...RHBZ-705854-warn-on-bad-dev-loss-tmo.patch | 17 + 0100-RHBZ-710478-deprecate-uid-gid-mode.patch | 162 +++++ ...09-disable-udev-disk-rules-on-reload.patch | 173 +++++ 0102-RHBZ-690828-systemd-unit-file.patch | 58 ++ device-mapper-multipath.spec | 222 ++++++- 81 files changed, 6741 insertions(+), 61 deletions(-) create mode 100644 0025-RHBZ-508827-update-multipathd-manpage.patch create mode 100644 0026-RHBZ-549636-default-path-selector.patch create mode 100644 0027-RHBZ-509443-enhance-show-config.patch create mode 100644 0028-RHBZ-452617-add-revision-parameter.patch create mode 100644 0029-RHBZ-567219-recalculate-pgs-in-checkerloop.patch create mode 100644 0030-RHBZ-558636-check-if-multipath-owns-path.patch create mode 100644 0031-RHBZ-570546-display-avg-pg-prio.patch create mode 100644 0032-RHBZ-575767-ontap_prio.patch create mode 100644 0033-RHBZ-573715-eurologic-config.patch create mode 100644 0034-RHBZ-579575-add-q-multipath-option.patch create mode 100644 0035-RHBZ-467709-add-followover.patch create mode 100644 0036-RH-clear-messages.patch create mode 100644 0037-RH-adopt-paths.patch create mode 100644 0038-RHBZ-587201-IBM-SGI.patch create mode 100644 0039-RHBZ-589153-manpage-update.patch create mode 100644 0040-RHBZ-587695-add-checker-msg-alias.patch create mode 100644 0041-RHBZ-587695-add-rdac-message.patch create mode 100644 0042-RHBZ-590038-fix-fast-io-fail-tmo.patch create mode 100644 0043-RHBZ-590028-close-sysfs_attr_fd.patch create mode 100644 0044-RHBZ-591940-dont-clear-daemon.patch create mode 100644 0045-RHBZ-593379-dont-add-unknown-paths.patch create mode 100644 0046-RHBZ-593426-move-adopt-path.patch create mode 100644 0047-RHBZ-591608-only-switch-pgs-once.patch create mode 100644 0048-RHBZ-592494-fix-user-configs.patch create mode 100644 0049-RHBZ-591644-enhance-mpathconf.patch create mode 100644 0050-RHBZ-595400-fix-checker-tmo.patch create mode 100644 0051-RHBZ-596156-mpathconf-man-page.patch create mode 100644 0052-RHBZ-601247-fix-path-adoption.patch create mode 100644 0053-RHBZ-596323-remember_more_wwids.patch create mode 100644 0054-RHBZ-596319-rules-cleanup.patch create mode 100644 0055-RHBZ-602257-update-on-show-topology.patch create mode 100644 0056-RHBZ-603812-better-type-check.patch create mode 100644 0057-RHBZ-607869-fix-resize.patch create mode 100644 0058-RHBZ-601665-assemble-features.patch create mode 100644 0059-RHBZ-607874-handle-offlined-paths.patch create mode 100644 0060-RHBZ-606420-fix-remove-map.patch create mode 100644 0061-RHBZ-620479-find-rport.patch create mode 100644 0062-RHBZ-592998-hpsc-config.patch create mode 100644 0063-RHBZ-595719-udev_link_priority.patch create mode 100644 0064-RHBZ-612173-fix-reverse-lookup.patch create mode 100644 0065-RHBZ-635088-update-priority.patch create mode 100644 0066-RHBZ-636071-mpathconf-variable_names.patch create mode 100644 0067-RHBZ-622569-symmetrix-config.patch create mode 100644 0068-RHBZ-632734-nvdisk-config.patch create mode 100644 0069-RHBZ-636246-hp-open-config.patch create mode 100644 0070-RHBZ-639037-hitachi-open-config.patch create mode 100644 0071-RHBZ-611779-fix-whitespace-crash.patch create mode 100644 0072-RHBZ-651389-change-scsi-tmo-order.patch create mode 100644 0073-RHBZ-650664-clarify-error-msg.patch create mode 100644 0074-RHBZ-602883-dont-print-change.patch create mode 100644 0075-RHBZ-576919-log-checker-err.patch create mode 100644 0076-RHBZ-599690-update-multipath-conf.patch create mode 100644 0077-RHBZ-622608-nvdisk-config.patch create mode 100644 0078-RHBZ-628095-config-warnings.patch create mode 100644 0079-RHBZ-650797-display-iscsi-tgt-name.patch create mode 100644 0080-RHBZ-662731-fix-no-config-value-segfault.patch create mode 100644 0081-RHBZ-623644-fix-sysfs-caching.patch create mode 100644 0083-RHBZ-636213-633643-new-configs.patch create mode 100644 0084-RHBZ-644111-read-only-bindings.patch create mode 100644 0085-RHBZ-645605-fix-offline-check.patch create mode 100644 0086-RHBZ-681144-sysfs-device-cleanup.patch create mode 100644 0087-RHBZ-680480-skip-if-no-sysdev.patch create mode 100644 0088-RHBZ-693524-fix-prio-segfault.patch create mode 100644 0089-RHBZ-694602-RSSM-config.patch create mode 100644 0090-RHBZ-700169-fix-nr-active.patch create mode 100644 0091-RHBZ-699577-manpage-clarification.patch create mode 100644 0092-RHBZ-689504-rdac-retry.patch create mode 100644 0093-RHBZ-677449-dont-remove-map-on-enomem.patch create mode 100644 0094-RHBZ-707560-check-return-value.patch create mode 100644 0095-RHBZ-678673-no-path-groups.patch create mode 100644 0096-RHBZ-683616-ioship-support.patch create mode 100644 0097-RHBZ-697386-fix-shutdown-crash.patch create mode 100644 0098-RHBZ-706555-dont-update-pgs-in-manual.patch create mode 100644 0099-RHBZ-705854-warn-on-bad-dev-loss-tmo.patch create mode 100644 0100-RHBZ-710478-deprecate-uid-gid-mode.patch create mode 100644 0101-RHBZ-631009-disable-udev-disk-rules-on-reload.patch create mode 100644 0102-RHBZ-690828-systemd-unit-file.patch diff --git a/0012-RH-udev-sync-support.patch b/0012-RH-udev-sync-support.patch index b30828c..6450985 100644 --- a/0012-RH-udev-sync-support.patch +++ b/0012-RH-udev-sync-support.patch @@ -1,14 +1,14 @@ --- kpartx/devmapper.c | 10 ++++++++-- kpartx/devmapper.h | 4 ++-- - kpartx/kpartx.c | 22 ++++++++++++++++------ + kpartx/kpartx.c | 28 ++++++++++++++++++++-------- libmultipath/config.h | 2 ++ libmultipath/configure.c | 2 +- libmultipath/devmapper.c | 29 +++++++++++++++++++---------- libmultipath/devmapper.h | 8 +++++--- multipath/main.c | 1 + multipathd/main.c | 1 + - 9 files changed, 55 insertions(+), 24 deletions(-) + 9 files changed, 59 insertions(+), 26 deletions(-) Index: multipath-tools/kpartx/devmapper.c =================================================================== @@ -131,7 +131,23 @@ Index: multipath-tools/kpartx/kpartx.c fprintf(stderr, "resume failed on %s\n", partname); 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) break; } diff --git a/0021-RHBZ-548874-add-find-multipaths.patch b/0021-RHBZ-548874-add-find-multipaths.patch index 12ec02c..e1229a7 100644 --- a/0021-RHBZ-548874-add-find-multipaths.patch +++ b/0021-RHBZ-548874-add-find-multipaths.patch @@ -4,18 +4,18 @@ libmultipath/alias.h | 1 libmultipath/config.c | 5 - libmultipath/config.h | 1 - libmultipath/configure.c | 23 ++++ + libmultipath/configure.c | 22 ++++ libmultipath/defaults.h | 2 libmultipath/dict.c | 34 ++++++ libmultipath/file.c | 178 +++++++++++++++++++++++++++++++++++ libmultipath/file.h | 11 ++ - libmultipath/finder.c | 150 ++++++++++++++++++++++++++++++ + libmultipath/finder.c | 165 +++++++++++++++++++++++++++++++++ libmultipath/finder.h | 18 +++ multipath/Makefile | 2 multipath/main.c | 2 multipath/mpathconf | 234 +++++++++++++++++++++++++++++++++++++++++++++++ - multipathd/main.c | 27 +++-- - 16 files changed, 679 insertions(+), 163 deletions(-) + multipathd/main.c | 24 +++- + 16 files changed, 690 insertions(+), 163 deletions(-) Index: multipath-tools/libmultipath/alias.c =================================================================== @@ -240,7 +240,7 @@ Index: multipath-tools/libmultipath/config.c condlog(0, "/usr/share/doc/device-mapper-multipath-%d.%d.%d/multipath.conf", MULTIPATH_VERSION(VERSION_CODE)); -+ condlog(0, ++ condlog(0, +"You can run /sbin/mpathconf to create or modify /etc/multipath.conf"); conf->blist_devnode = vector_alloc(); if (!conf->blist_devnode) { @@ -269,7 +269,16 @@ Index: multipath-tools/libmultipath/configure.c extern int 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); @@ -280,7 +289,7 @@ Index: multipath-tools/libmultipath/configure.c if (force_reload) { vector_foreach_slot (pathvec, pp1, k) { 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 */ if (memcmp(empty_buff, pp1->wwid, WWID_SIZE) == 0 || @@ -306,13 +315,10 @@ Index: multipath-tools/libmultipath/configure.c continue; + /* If find_multipaths was selected check if the path is valid */ -+ if (conf->find_multipaths){ -+ if (refwwid || should_multipath(pp1, pathvec)) -+ remember_wwid(pp1->wwid); -+ else { -+ orphan_path(pp1); -+ continue; -+ } ++ if (conf->find_multipaths && !refwwid && ++ !should_multipath(pp1, pathvec)){ ++ orphan_path(pp1); ++ continue; + } + /* @@ -599,7 +605,7 @@ Index: multipath-tools/libmultipath/finder.c =================================================================== --- /dev/null +++ multipath-tools/libmultipath/finder.c -@@ -0,0 +1,150 @@ +@@ -0,0 +1,165 @@ +#include +#include +#include @@ -622,18 +628,33 @@ Index: multipath-tools/libmultipath/finder.c + +static int +lookup_wwid(FILE *f, char *wwid) { ++ int c; + char buf[LINE_MAX]; ++ int count; + -+ while (fgets(buf, LINE_MAX, f)) { -+ char *c; -+ -+ c = strpbrk(buf, "#\n\r"); -+ if (c) -+ *c = '\0'; -+ if (*buf == '\0') -+ continue; -+ if (strncmp(wwid, buf, WWID_SIZE) == 0) ++ while ((c = fgetc(f)) != EOF){ ++ if (c != '/') { ++ if (fgets(buf, LINE_MAX, f) == NULL) ++ return 0; ++ else ++ continue; ++ } ++ count = 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; ++next: ++ if (fgets(buf, LINE_MAX, f) == NULL) ++ return 0; + } + return 0; +} @@ -642,10 +663,10 @@ Index: multipath-tools/libmultipath/finder.c +write_out_wwid(int fd, char *wwid) { + int ret; + off_t offset; -+ char buf[WWID_SIZE + 1]; ++ char buf[WWID_SIZE + 3]; + -+ ret = snprintf(buf, WWID_SIZE + 1, "%s\n", wwid); -+ if (ret > WWID_SIZE || ret < 0){ ++ ret = snprintf(buf, WWID_SIZE + 3, "/%s/\n", wwid); ++ if (ret >= (WWID_SIZE + 3) || ret < 0){ + condlog(0, "can't format wwid for writing (%d) : %s", + ret, strerror(errno)); + return -1; @@ -807,7 +828,7 @@ Index: multipath-tools/multipathd/main.c } if (filter_path(conf, pp) > 0){ 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", mpp->alias, pp->dev); if (adopt_paths(vecs->pathvec, mpp)) @@ -819,13 +840,10 @@ Index: multipath-tools/multipathd/main.c mpp->action = ACT_RELOAD; } else { -+ if (conf->find_multipaths) { -+ if (should_multipath(pp, vecs->pathvec)) -+ remember_wwid(pp->wwid); -+ else { -+ orphan_path(pp); -+ return 0; -+ } ++ if (conf->find_multipaths && ++ !should_multipath(pp, vecs->pathvec)) { ++ orphan_path(pp); ++ return 0; + } condlog(4,"%s: creating new map", pp->dev); 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)) { condlog(0, "%s: failed to setup map for addition of new " "path %s", mpp->alias, devname); @@ -845,7 +863,7 @@ Index: multipath-tools/multipathd/main.c } /* * reload the map for the multipath mapped device -@@ -450,7 +459,7 @@ rescan: +@@ -450,7 +456,7 @@ rescan: goto rescan; } else @@ -854,7 +872,7 @@ Index: multipath-tools/multipathd/main.c } dm_lib_release(); -@@ -458,19 +467,21 @@ rescan: +@@ -458,19 +464,21 @@ rescan: * update our state from kernel regardless of create or reload */ if (setup_multipath(vecs, mpp)) diff --git a/0022-RHBZ-557845-RHEL5-style-partitions.patch b/0022-RHBZ-557845-RHEL5-style-partitions.patch index 95488b8..8c87256 100644 --- a/0022-RHBZ-557845-RHEL5-style-partitions.patch +++ b/0022-RHBZ-557845-RHEL5-style-partitions.patch @@ -187,7 +187,7 @@ Index: multipath-tools/kpartx/kpartx.c if (safe_sprintf(partname, "%s%s%d", mapname, delim, j+1)) { 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, DM_TARGET, params); } @@ -236,11 +236,13 @@ Index: multipath-tools/kpartx/kpartx.c - 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); diff --git a/0025-RHBZ-508827-update-multipathd-manpage.patch b/0025-RHBZ-508827-update-multipathd-manpage.patch new file mode 100644 index 0000000..27d787a --- /dev/null +++ b/0025-RHBZ-508827-update-multipathd-manpage.patch @@ -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) diff --git a/0026-RHBZ-549636-default-path-selector.patch b/0026-RHBZ-549636-default-path-selector.patch new file mode 100644 index 0000000..4b7b460 --- /dev/null +++ b/0026-RHBZ-549636-default-path-selector.patch @@ -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 diff --git a/0027-RHBZ-509443-enhance-show-config.patch b/0027-RHBZ-509443-enhance-show-config.patch new file mode 100644 index 0000000..df93d36 --- /dev/null +++ b/0027-RHBZ-509443-enhance-show-config.patch @@ -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); diff --git a/0028-RHBZ-452617-add-revision-parameter.patch b/0028-RHBZ-452617-add-revision-parameter.patch new file mode 100644 index 0000000..fa244be --- /dev/null +++ b/0028-RHBZ-452617-add-revision-parameter.patch @@ -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); diff --git a/0029-RHBZ-567219-recalculate-pgs-in-checkerloop.patch b/0029-RHBZ-567219-recalculate-pgs-in-checkerloop.patch new file mode 100644 index 0000000..f7ec7b0 --- /dev/null +++ b/0029-RHBZ-567219-recalculate-pgs-in-checkerloop.patch @@ -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 + #include + #include ++#include + + #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 = diff --git a/0030-RHBZ-558636-check-if-multipath-owns-path.patch b/0030-RHBZ-558636-check-if-multipath-owns-path.patch new file mode 100644 index 0000000..94d4c12 --- /dev/null +++ b/0030-RHBZ-558636-check-if-multipath-owns-path.patch @@ -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 + #include + #include ++#include + + 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" diff --git a/0031-RHBZ-570546-display-avg-pg-prio.patch b/0031-RHBZ-570546-display-avg-pg-prio.patch new file mode 100644 index 0000000..4643ad5 --- /dev/null +++ b/0031-RHBZ-570546-display-avg-pg-prio.patch @@ -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 diff --git a/0032-RHBZ-575767-ontap_prio.patch b/0032-RHBZ-575767-ontap_prio.patch new file mode 100644 index 0000000..d06f042 --- /dev/null +++ b/0032-RHBZ-575767-ontap_prio.patch @@ -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 +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-#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; imasked_status, +- io_hdr->host_status, io_hdr->driver_status); +- if (io_hdr->sb_len_wr > 0) { +- condlog(0, "- SCSI sense data: "); +- for (i=0; isb_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 ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#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; imasked_status, ++ io_hdr->host_status, io_hdr->driver_status); ++ if (io_hdr->sb_len_wr > 0) { ++ condlog(0, "- SCSI sense data: "); ++ for (i=0; isb_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 diff --git a/0033-RHBZ-573715-eurologic-config.patch b/0033-RHBZ-573715-eurologic-config.patch new file mode 100644 index 0000000..fc6b65d --- /dev/null +++ b/0033-RHBZ-573715-eurologic-config.patch @@ -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 ++# } + #} diff --git a/0034-RHBZ-579575-add-q-multipath-option.patch b/0034-RHBZ-579575-add-q-multipath-option.patch new file mode 100644 index 0000000..7d85678 --- /dev/null +++ b/0034-RHBZ-579575-add-q-multipath-option.patch @@ -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 */ diff --git a/0035-RHBZ-467709-add-followover.patch b/0035-RHBZ-467709-add-followover.patch new file mode 100644 index 0000000..0d79c3a --- /dev/null +++ b/0035-RHBZ-467709-add-followover.patch @@ -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); + + /* diff --git a/0036-RH-clear-messages.patch b/0036-RH-clear-messages.patch new file mode 100644 index 0000000..fdae141 --- /dev/null +++ b/0036-RH-clear-messages.patch @@ -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 */ diff --git a/0037-RH-adopt-paths.patch b/0037-RH-adopt-paths.patch new file mode 100644 index 0000000..279487e --- /dev/null +++ b/0037-RH-adopt-paths.patch @@ -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) { diff --git a/0038-RHBZ-587201-IBM-SGI.patch b/0038-RHBZ-587201-IBM-SGI.patch new file mode 100644 index 0000000..49f53a7 --- /dev/null +++ b/0038-RHBZ-587201-IBM-SGI.patch @@ -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, diff --git a/0039-RHBZ-589153-manpage-update.patch b/0039-RHBZ-589153-manpage-update.patch new file mode 100644 index 0000000..93e63b2 --- /dev/null +++ b/0039-RHBZ-589153-manpage-update.patch @@ -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/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 diff --git a/0040-RHBZ-587695-add-checker-msg-alias.patch b/0040-RHBZ-587695-add-checker-msg-alias.patch new file mode 100644 index 0000000..42544c0 --- /dev/null +++ b/0040-RHBZ-587695-add-checker-msg-alias.patch @@ -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; diff --git a/0041-RHBZ-587695-add-rdac-message.patch b/0041-RHBZ-587695-add-rdac-message.patch new file mode 100644 index 0000000..880dee0 --- /dev/null +++ b/0041-RHBZ-587695-add-rdac-message.patch @@ -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; + } diff --git a/0042-RHBZ-590038-fix-fast-io-fail-tmo.patch b/0042-RHBZ-590038-fix-fast-io-fail-tmo.patch new file mode 100644 index 0000000..f3ea001 --- /dev/null +++ b/0042-RHBZ-590038-fix-fast-io-fail-tmo.patch @@ -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; + } diff --git a/0043-RHBZ-590028-close-sysfs_attr_fd.patch b/0043-RHBZ-590028-close-sysfs_attr_fd.patch new file mode 100644 index 0000000..890436f --- /dev/null +++ b/0043-RHBZ-590028-close-sysfs_attr_fd.patch @@ -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; + } diff --git a/0044-RHBZ-591940-dont-clear-daemon.patch b/0044-RHBZ-591940-dont-clear-daemon.patch new file mode 100644 index 0000000..761e38a --- /dev/null +++ b/0044-RHBZ-591940-dont-clear-daemon.patch @@ -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; diff --git a/0045-RHBZ-593379-dont-add-unknown-paths.patch b/0045-RHBZ-593379-dont-add-unknown-paths.patch new file mode 100644 index 0000000..629f315 --- /dev/null +++ b/0045-RHBZ-593379-dont-add-unknown-paths.patch @@ -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); diff --git a/0046-RHBZ-593426-move-adopt-path.patch b/0046-RHBZ-593426-move-adopt-path.patch new file mode 100644 index 0000000..5a3c7b6 --- /dev/null +++ b/0046-RHBZ-593426-move-adopt-path.patch @@ -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 + */ diff --git a/0047-RHBZ-591608-only-switch-pgs-once.patch b/0047-RHBZ-591608-only-switch-pgs-once.patch new file mode 100644 index 0000000..001226a --- /dev/null +++ b/0047-RHBZ-591608-only-switch-pgs-once.patch @@ -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); + } + } diff --git a/0048-RHBZ-592494-fix-user-configs.patch b/0048-RHBZ-592494-fix-user-configs.patch new file mode 100644 index 0000000..1f89d1f --- /dev/null +++ b/0048-RHBZ-592494-fix-user-configs.patch @@ -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 diff --git a/0049-RHBZ-591644-enhance-mpathconf.patch b/0049-RHBZ-591644-enhance-mpathconf.patch new file mode 100644 index 0000000..e028456 --- /dev/null +++ b/0049-RHBZ-591644-enhance-mpathconf.patch @@ -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 " + echo "" + echo "Commands:" +- echo "Enable: --enable [--user_friendly_names ] [--find_multipaths " ++ echo "Enable: --enable " + echo "Disable: --disable" +- echo "Set user_friendly_names: --user_friendly_names " +- echo "Set find_multipaths: --find_multipaths " ++ echo "Set user_friendly_names (Default n): --user_friendly_names " ++ echo "Set find_multipaths (Default n): --find_multipaths " ++ echo "Load the dm-multipath modules on enable (Default y): --with_module " ++ echo "start/stop/reload multipathd (Default n): --with_multipathd " ++ echo "chkconfig on/off multipathd (Default y): --with_chkconfig " + 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()) { diff --git a/0050-RHBZ-595400-fix-checker-tmo.patch b/0050-RHBZ-595400-fix-checker-tmo.patch new file mode 100644 index 0000000..d0c7308 --- /dev/null +++ b/0050-RHBZ-595400-fix-checker-tmo.patch @@ -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; + diff --git a/0051-RHBZ-596156-mpathconf-man-page.patch b/0051-RHBZ-596156-mpathconf-man-page.patch new file mode 100644 index 0000000..a758035 --- /dev/null +++ b/0051-RHBZ-596156-mpathconf-man-page.patch @@ -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 +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 diff --git a/0052-RHBZ-601247-fix-path-adoption.patch b/0052-RHBZ-601247-fix-path-adoption.patch new file mode 100644 index 0000000..12fe73d --- /dev/null +++ b/0052-RHBZ-601247-fix-path-adoption.patch @@ -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); + diff --git a/0053-RHBZ-596323-remember_more_wwids.patch b/0053-RHBZ-596323-remember_more_wwids.patch new file mode 100644 index 0000000..ecf8952 --- /dev/null +++ b/0053-RHBZ-596323-remember_more_wwids.patch @@ -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; + } diff --git a/0054-RHBZ-596319-rules-cleanup.patch b/0054-RHBZ-596319-rules-cleanup.patch new file mode 100644 index 0000000..adf45c1 --- /dev/null +++ b/0054-RHBZ-596319-rules-cleanup.patch @@ -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" diff --git a/0055-RHBZ-602257-update-on-show-topology.patch b/0055-RHBZ-602257-update-on-show-topology.patch new file mode 100644 index 0000000..6fe45fb --- /dev/null +++ b/0055-RHBZ-602257-update-on-show-topology.patch @@ -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) { diff --git a/0056-RHBZ-603812-better-type-check.patch b/0056-RHBZ-603812-better-type-check.patch new file mode 100644 index 0000000..239058a --- /dev/null +++ b/0056-RHBZ-603812-better-type-check.patch @@ -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 ++#include + #include + #include + #include +@@ -52,6 +54,7 @@ + #include + #include + #include ++#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)) diff --git a/0057-RHBZ-607869-fix-resize.patch b/0057-RHBZ-607869-fix-resize.patch new file mode 100644 index 0000000..2180cf7 --- /dev/null +++ b/0057-RHBZ-607869-fix-resize.patch @@ -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 diff --git a/0058-RHBZ-601665-assemble-features.patch b/0058-RHBZ-601665-assemble-features.patch new file mode 100644 index 0000000..aecd845 --- /dev/null +++ b/0058-RHBZ-601665-assemble-features.patch @@ -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 + #include + #include ++#include + + #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) { diff --git a/0059-RHBZ-607874-handle-offlined-paths.patch b/0059-RHBZ-607874-handle-offlined-paths.patch new file mode 100644 index 0000000..75bf35a --- /dev/null +++ b/0059-RHBZ-607874-handle-offlined-paths.patch @@ -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); diff --git a/0060-RHBZ-606420-fix-remove-map.patch b/0060-RHBZ-606420-fix-remove-map.patch new file mode 100644 index 0000000..5670011 --- /dev/null +++ b/0060-RHBZ-606420-fix-remove-map.patch @@ -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 diff --git a/0061-RHBZ-620479-find-rport.patch b/0061-RHBZ-620479-find-rport.patch new file mode 100644 index 0000000..e238dae --- /dev/null +++ b/0061-RHBZ-620479-find-rport.patch @@ -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 + #include + #include ++#include + + #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){ diff --git a/0062-RHBZ-592998-hpsc-config.patch b/0062-RHBZ-592998-hpsc-config.patch new file mode 100644 index 0000000..d6bfb20 --- /dev/null +++ b/0062-RHBZ-592998-hpsc-config.patch @@ -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, + }, + /* diff --git a/0063-RHBZ-595719-udev_link_priority.patch b/0063-RHBZ-595719-udev_link_priority.patch new file mode 100644 index 0000000..06a5849 --- /dev/null +++ b/0063-RHBZ-595719-udev_link_priority.patch @@ -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" diff --git a/0064-RHBZ-612173-fix-reverse-lookup.patch b/0064-RHBZ-612173-fix-reverse-lookup.patch new file mode 100644 index 0000000..7799dee --- /dev/null +++ b/0064-RHBZ-612173-fix-reverse-lookup.patch @@ -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", diff --git a/0065-RHBZ-635088-update-priority.patch b/0065-RHBZ-635088-update-priority.patch new file mode 100644 index 0000000..7c594dc --- /dev/null +++ b/0065-RHBZ-635088-update-priority.patch @@ -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 = diff --git a/0066-RHBZ-636071-mpathconf-variable_names.patch b/0066-RHBZ-636071-mpathconf-variable_names.patch new file mode 100644 index 0000000..1df1527 --- /dev/null +++ b/0066-RHBZ-636071-mpathconf-variable_names.patch @@ -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 diff --git a/0067-RHBZ-622569-symmetrix-config.patch b/0067-RHBZ-622569-symmetrix-config.patch new file mode 100644 index 0000000..a6a8967 --- /dev/null +++ b/0067-RHBZ-622569-symmetrix-config.patch @@ -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 { diff --git a/0068-RHBZ-632734-nvdisk-config.patch b/0068-RHBZ-632734-nvdisk-config.patch new file mode 100644 index 0000000..3338935 --- /dev/null +++ b/0068-RHBZ-632734-nvdisk-config.patch @@ -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" diff --git a/0069-RHBZ-636246-hp-open-config.patch b/0069-RHBZ-636246-hp-open-config.patch new file mode 100644 index 0000000..d94c66b --- /dev/null +++ b/0069-RHBZ-636246-hp-open-config.patch @@ -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" diff --git a/0070-RHBZ-639037-hitachi-open-config.patch b/0070-RHBZ-639037-hitachi-open-config.patch new file mode 100644 index 0000000..07a5bee --- /dev/null +++ b/0070-RHBZ-639037-hitachi-open-config.patch @@ -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 diff --git a/0071-RHBZ-611779-fix-whitespace-crash.patch b/0071-RHBZ-611779-fix-whitespace-crash.patch new file mode 100644 index 0000000..3c6374a --- /dev/null +++ b/0071-RHBZ-611779-fix-whitespace-crash.patch @@ -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; diff --git a/0072-RHBZ-651389-change-scsi-tmo-order.patch b/0072-RHBZ-651389-change-scsi-tmo-order.patch new file mode 100644 index 0000000..e0998d3 --- /dev/null +++ b/0072-RHBZ-651389-change-scsi-tmo-order.patch @@ -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; + } diff --git a/0073-RHBZ-650664-clarify-error-msg.patch b/0073-RHBZ-650664-clarify-error-msg.patch new file mode 100644 index 0000000..57ca0aa --- /dev/null +++ b/0073-RHBZ-650664-clarify-error-msg.patch @@ -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; + } diff --git a/0074-RHBZ-602883-dont-print-change.patch b/0074-RHBZ-602883-dont-print-change.patch new file mode 100644 index 0000000..1d06744 --- /dev/null +++ b/0074-RHBZ-602883-dont-print-change.patch @@ -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 diff --git a/0075-RHBZ-576919-log-checker-err.patch b/0075-RHBZ-576919-log-checker-err.patch new file mode 100644 index 0000000..f654261 --- /dev/null +++ b/0075-RHBZ-576919-log-checker-err.patch @@ -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 diff --git a/0076-RHBZ-599690-update-multipath-conf.patch b/0076-RHBZ-599690-update-multipath-conf.patch new file mode 100644 index 0000000..8c41b72 --- /dev/null +++ b/0076-RHBZ-599690-update-multipath-conf.patch @@ -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 diff --git a/0077-RHBZ-622608-nvdisk-config.patch b/0077-RHBZ-622608-nvdisk-config.patch new file mode 100644 index 0000000..131b83f --- /dev/null +++ b/0077-RHBZ-622608-nvdisk-config.patch @@ -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", diff --git a/0078-RHBZ-628095-config-warnings.patch b/0078-RHBZ-628095-config-warnings.patch new file mode 100644 index 0000000..06cb6ad --- /dev/null +++ b/0078-RHBZ-628095-config-warnings.patch @@ -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); diff --git a/0079-RHBZ-650797-display-iscsi-tgt-name.patch b/0079-RHBZ-650797-display-iscsi-tgt-name.patch new file mode 100644 index 0000000..f7e06de --- /dev/null +++ b/0079-RHBZ-650797-display-iscsi-tgt-name.patch @@ -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 diff --git a/0080-RHBZ-662731-fix-no-config-value-segfault.patch b/0080-RHBZ-662731-fix-no-config-value-segfault.patch new file mode 100644 index 0000000..72189bc --- /dev/null +++ b/0080-RHBZ-662731-fix-no-config-value-segfault.patch @@ -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); diff --git a/0081-RHBZ-623644-fix-sysfs-caching.patch b/0081-RHBZ-623644-fix-sysfs-caching.patch new file mode 100644 index 0000000..b85f6c6 --- /dev/null +++ b/0081-RHBZ-623644-fix-sysfs-caching.patch @@ -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); diff --git a/0083-RHBZ-636213-633643-new-configs.patch b/0083-RHBZ-636213-633643-new-configs.patch new file mode 100644 index 0000000..6f81a18 --- /dev/null +++ b/0083-RHBZ-636213-633643-new-configs.patch @@ -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 ++# } + #} diff --git a/0084-RHBZ-644111-read-only-bindings.patch b/0084-RHBZ-644111-read-only-bindings.patch new file mode 100644 index 0000000..23fce2a --- /dev/null +++ b/0084-RHBZ-644111-read-only-bindings.patch @@ -0,0 +1,160 @@ +From c2f3abecdb76c4e7b3ec3aa418625b4f1b942496 Mon Sep 17 00:00:00 2001 +From: Malahal Naineni +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); diff --git a/0085-RHBZ-645605-fix-offline-check.patch b/0085-RHBZ-645605-fix-offline-check.patch new file mode 100644 index 0000000..7ae7e8c --- /dev/null +++ b/0085-RHBZ-645605-fix-offline-check.patch @@ -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; diff --git a/0086-RHBZ-681144-sysfs-device-cleanup.patch b/0086-RHBZ-681144-sysfs-device-cleanup.patch new file mode 100644 index 0000000..3158892 --- /dev/null +++ b/0086-RHBZ-681144-sysfs-device-cleanup.patch @@ -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 *); diff --git a/0087-RHBZ-680480-skip-if-no-sysdev.patch b/0087-RHBZ-680480-skip-if-no-sysdev.patch new file mode 100644 index 0000000..f076c0e --- /dev/null +++ b/0087-RHBZ-680480-skip-if-no-sysdev.patch @@ -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); diff --git a/0088-RHBZ-693524-fix-prio-segfault.patch b/0088-RHBZ-693524-fix-prio-segfault.patch new file mode 100644 index 0000000..b0357aa --- /dev/null +++ b/0088-RHBZ-693524-fix-prio-segfault.patch @@ -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; + } + } diff --git a/0089-RHBZ-694602-RSSM-config.patch b/0089-RHBZ-694602-RSSM-config.patch new file mode 100644 index 0000000..5432320 --- /dev/null +++ b/0089-RHBZ-694602-RSSM-config.patch @@ -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" diff --git a/0090-RHBZ-700169-fix-nr-active.patch b/0090-RHBZ-700169-fix-nr-active.patch new file mode 100644 index 0000000..ee93e1a --- /dev/null +++ b/0090-RHBZ-700169-fix-nr-active.patch @@ -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 diff --git a/0091-RHBZ-699577-manpage-clarification.patch b/0091-RHBZ-699577-manpage-clarification.patch new file mode 100644 index 0000000..a1143b9 --- /dev/null +++ b/0091-RHBZ-699577-manpage-clarification.patch @@ -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 diff --git a/0092-RHBZ-689504-rdac-retry.patch b/0092-RHBZ-689504-rdac-retry.patch new file mode 100644 index 0000000..f10eeae --- /dev/null +++ b/0092-RHBZ-689504-rdac-retry.patch @@ -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 +X-Patchwork-Id: 600411 +Message-Id: +To: "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 + +--- +-- +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))) { diff --git a/0093-RHBZ-677449-dont-remove-map-on-enomem.patch b/0093-RHBZ-677449-dont-remove-map-on-enomem.patch new file mode 100644 index 0000000..bf8e76c --- /dev/null +++ b/0093-RHBZ-677449-dont-remove-map-on-enomem.patch @@ -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--; diff --git a/0094-RHBZ-707560-check-return-value.patch b/0094-RHBZ-707560-check-return-value.patch new file mode 100644 index 0000000..4b6becf --- /dev/null +++ b/0094-RHBZ-707560-check-return-value.patch @@ -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; diff --git a/0095-RHBZ-678673-no-path-groups.patch b/0095-RHBZ-678673-no-path-groups.patch new file mode 100644 index 0000000..dde39ac --- /dev/null +++ b/0095-RHBZ-678673-no-path-groups.patch @@ -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"); diff --git a/0096-RHBZ-683616-ioship-support.patch b/0096-RHBZ-683616-ioship-support.patch new file mode 100644 index 0000000..42383b5 --- /dev/null +++ b/0096-RHBZ-683616-ioship-support.patch @@ -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 + + #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(¤t, 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 = ¤t; ++ 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 = ¤t; ++ ++ 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); + } diff --git a/0097-RHBZ-697386-fix-shutdown-crash.patch b/0097-RHBZ-697386-fix-shutdown-crash.patch new file mode 100644 index 0000000..7faa7a9 --- /dev/null +++ b/0097-RHBZ-697386-fix-shutdown-crash.patch @@ -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) { diff --git a/0098-RHBZ-706555-dont-update-pgs-in-manual.patch b/0098-RHBZ-706555-dont-update-pgs-in-manual.patch new file mode 100644 index 0000000..3ae8a54 --- /dev/null +++ b/0098-RHBZ-706555-dont-update-pgs-in-manual.patch @@ -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 && diff --git a/0099-RHBZ-705854-warn-on-bad-dev-loss-tmo.patch b/0099-RHBZ-705854-warn-on-bad-dev-loss-tmo.patch new file mode 100644 index 0000000..a82e64c --- /dev/null +++ b/0099-RHBZ-705854-warn-on-bad-dev-loss-tmo.patch @@ -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)) diff --git a/0100-RHBZ-710478-deprecate-uid-gid-mode.patch b/0100-RHBZ-710478-deprecate-uid-gid-mode.patch new file mode 100644 index 0000000..d7373b6 --- /dev/null +++ b/0100-RHBZ-710478-deprecate-uid-gid-mode.patch @@ -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 : +-# # 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 : +-# # 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 : +-# # 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 : +-# # 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 diff --git a/0101-RHBZ-631009-disable-udev-disk-rules-on-reload.patch b/0101-RHBZ-631009-disable-udev-disk-rules-on-reload.patch new file mode 100644 index 0000000..3903cb3 --- /dev/null +++ b/0101-RHBZ-631009-disable-udev-disk-rules-on-reload.patch @@ -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 ':': diff --git a/0102-RHBZ-690828-systemd-unit-file.patch b/0102-RHBZ-690828-systemd-unit-file.patch new file mode 100644 index 0000000..0c6aaa3 --- /dev/null +++ b/0102-RHBZ-690828-systemd-unit-file.patch @@ -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 diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index 067b898..496e270 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,7 +1,7 @@ Summary: Tools to manage multipath devices using device-mapper Name: device-mapper-multipath Version: 0.4.9 -Release: 15%{?dist} +Release: 16%{?dist} License: GPL+ Group: System Environment/Base 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 Patch1023: 0023-RHBZ-557810-emc-invista-config.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 Requires: %{name}-libs = %{version}-%{release} Requires: kpartx = %{version}-%{release} Requires: device-mapper >= 1.02.39-1 -Requires(post): chkconfig -Requires(preun): chkconfig -Requires(preun): initscripts -Requires(postun): initscripts +Requires: udev initscripts +Requires(post): systemd-units systemd-sysv chkconfig +Requires(preun): systemd-units +Requires(postun): systemd-units # build/setup BuildRequires: libaio-devel, device-mapper-devel >= 1.02.39-1 BuildRequires: libselinux-devel, libsepol-devel BuildRequires: readline-devel, ncurses-devel +BuildRequires: systemd-units 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, 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 Summary: Partition device manager for device-mapper devices Group: System Environment/Base @@ -107,6 +193,83 @@ kpartx manages partition creation and removal for device-mapper devices. %patch1022 -p1 %patch1023 -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} . %build @@ -123,7 +286,8 @@ make install \ bindir=%{_sbindir} \ syslibdir=%{_libdir} \ libdir=%{_libmpathdir} \ - rcdir=%{_initrddir} + rcdir=%{_initrddir} \ + unitdir=%{_unitdir} # tree fix up # install -m 0644 %{SOURCE1} %{buildroot}/etc/multipath.conf @@ -133,34 +297,42 @@ install -d %{buildroot}/etc/multipath rm -rf %{buildroot} %post -/sbin/chkconfig --add multipathd -if [ "$1" -gt "1" -a ! -e /etc/multipath/bindings -a \ - -f /var/lib/multipath/bindings ]; then - mv /var/lib/multipath/bindings /etc/multipath/bindings - ln -s /etc/multipath/bindings /var/lib/multipath/bindings +if [ $1 -eq 1 ] ; then + /bin/systemctl enable multipathd.service >/dev/null 2>&1 || : fi %preun -if [ "$1" = 0 ]; then - /sbin/service multipathd stop /dev/null 2>&1 - /sbin/chkconfig --del multipathd +if [ $1 -eq 0 ] ; then + /bin/systemctl --no-reload disable multipathd.service > /dev/null 2>&1 || : + bin/systemctl stop multipathd.service > /dev/null 2>&1 || : fi %postun -if [ "$1" -ge "1" ]; then - /sbin/service multipathd condrestart >/dev/null 2>&1 || : +/bin/systemctl daemon-reload >/dev/null 2>&1 || : +if [ $1 -ge 1 ] ; then + /bin/systemctl try-restart multipathd.service >/dev/null 2>&1 || : 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 %defattr(-,root,root,-) %{_sbindir}/multipath %{_sbindir}/multipathd %{_sbindir}/cciss_id %{_sbindir}/mpathconf -%{_initrddir}/multipathd +%{_unitdir}/multipathd.service %{_mandir}/man5/multipath.conf.5.gz %{_mandir}/man8/multipath.8.gz %{_mandir}/man8/multipathd.8.gz +%{_mandir}/man8/mpathconf.8.gz %config /lib/udev/rules.d/40-multipath.rules %doc AUTHOR COPYING FAQ %doc multipath.conf multipath.conf.annotated @@ -178,12 +350,28 @@ fi %postun libs -p /sbin/ldconfig +%files sysvinit +%{_initrddir}/multipathd + %files -n kpartx %defattr(-,root,root,-) /sbin/kpartx %{_mandir}/man8/kpartx.8.gz %changelog +* Fri Jul 15 2011 Benjamin Marzinski -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 - 0.4.9-15 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild