summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Marzinski <bmarzins@redhat.com>2012-02-10 09:34:20 -0600
committerBenjamin Marzinski <bmarzins@redhat.com>2012-02-10 09:34:20 -0600
commit5fe519f23fd8007c3fac68b50ea4bb764dac4ba9 (patch)
tree6ea19c3bcc8c6c994cd377eb9c6ae2aa1789a35f
parenta1478bc1bcf95fdd3feae2e0405b135ff4cc7954 (diff)
downloaddevice-mapper-multipath-5fe519f23fd8007c3fac68b50ea4bb764dac4ba9.tar.gz
device-mapper-multipath-5fe519f23fd8007c3fac68b50ea4bb764dac4ba9.tar.xz
device-mapper-multipath-5fe519f23fd8007c3fac68b50ea4bb764dac4ba9.zip
Add back missing patches
Add 0012-RH-update-on-show-topology.patch Add 0013-RH-manpage-update.patch Add 0014-RH-RHEL5-style-partitions.patch Add 0015-RH-add-followover.patch Add 0016-RH-dont-remove-map-on-enomem.patch Add 0017-RH-fix-shutdown-crash.patch Add 0018-RH-warn-on-bad-dev-loss-tmo.patch Add 0019-RH-deprecate-uid-gid-mode.patch Add 0020-RH-dont-remove-map-twice.patch Add 0021-RH-validate-guid-partitions.patch Add 0022-RH-adjust-messages.patch Add 0023-RH-manpage-update.patch
-rw-r--r--0012-RH-update-on-show-topology.patch141
-rw-r--r--0013-RH-manpage-update.patch169
-rw-r--r--0014-RH-RHEL5-style-partitions.patch327
-rw-r--r--0015-RH-add-followover.patch156
-rw-r--r--0016-RH-dont-remove-map-on-enomem.patch18
-rw-r--r--0017-RH-fix-shutdown-crash.patch69
-rw-r--r--0018-RH-warn-on-bad-dev-loss-tmo.patch68
-rw-r--r--0019-RH-deprecate-uid-gid-mode.patch90
-rw-r--r--0020-RH-dont-remove-map-twice.patch17
-rw-r--r--0021-RH-validate-guid-partitions.patch24
-rw-r--r--0022-RH-adjust-messages.patch32
-rw-r--r--0023-RH-manpage-update.patch19
-rw-r--r--device-mapper-multipath.spec40
13 files changed, 1169 insertions, 1 deletions
diff --git a/0012-RH-update-on-show-topology.patch b/0012-RH-update-on-show-topology.patch
new file mode 100644
index 0000000..24cc6de
--- /dev/null
+++ b/0012-RH-update-on-show-topology.patch
@@ -0,0 +1,141 @@
+---
+ 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-120123/multipathd/cli_handlers.c
+===================================================================
+--- multipath-tools-120123.orig/multipathd/cli_handlers.c
++++ multipath-tools-120123/multipathd/cli_handlers.c
+@@ -68,13 +68,16 @@ 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;
+ unsigned int maxlen = INITIAL_REPLY_LEN;
+ int again = 1;
+
++ if (update_multipath(vecs, mpp->alias, 0))
++ return 1;
+ reply = MALLOC(maxlen);
+
+ while (again) {
+@@ -112,9 +115,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));
+
+@@ -232,7 +240,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-120123/libmultipath/structs_vec.c
+===================================================================
+--- multipath-tools-120123.orig/libmultipath/structs_vec.c
++++ multipath-tools-120123/libmultipath/structs_vec.c
+@@ -324,7 +324,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)
+ {
+ if (dm_get_info(mpp->alias, &mpp->dmi)) {
+ /* Error accessing table */
+@@ -353,11 +353,13 @@ setup_multipath (struct vectors * vecs,
+ 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:
+@@ -479,7 +481,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;
+@@ -496,7 +498,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-120123/libmultipath/structs_vec.h
+===================================================================
+--- multipath-tools-120123.orig/libmultipath/structs_vec.h
++++ multipath-tools-120123/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);
+@@ -32,7 +34,7 @@ void remove_maps_and_stop_waiters (struc
+ struct multipath * add_map_without_path (struct vectors * vecs, 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-120123/libmultipath/waiter.c
+===================================================================
+--- multipath-tools-120123.orig/libmultipath/waiter.c
++++ multipath-tools-120123/libmultipath/waiter.c
+@@ -157,7 +157,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/0013-RH-manpage-update.patch b/0013-RH-manpage-update.patch
new file mode 100644
index 0000000..dbcc408
--- /dev/null
+++ b/0013-RH-manpage-update.patch
@@ -0,0 +1,169 @@
+---
+ multipath/multipath.conf.5 | 79 ++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 64 insertions(+), 15 deletions(-)
+
+Index: multipath-tools-120123/multipath/multipath.conf.5
+===================================================================
+--- multipath-tools-120123.orig/multipath/multipath.conf.5
++++ multipath-tools-120123/multipath/multipath.conf.5
+@@ -82,6 +82,11 @@ maximal interval between two path checks
+ 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 verbosity
+ default verbosity. Higher values increase the verbosity level. Valid
+ levels are between 0 and 6; default is
+@@ -141,7 +146,7 @@ Default value is \fImultibus\fR.
+ The default program and args to callout to obtain a unique path
+ identifier. Should be specified with an absolute path. Default value
+ is
+-.I /lib/udev/scsi_id --whitelisted --device=/dev/%n
++.I /lib/udev/scsi_id --whitelisted --replace-whitespace --device=/dev/%n
+ .TP
+ .B prio
+ The name of the path priority routine. The specified routine
+@@ -177,17 +182,22 @@ Generate the path priority for Hitachi H
+ .B random
+ Generate a random priority between 1 and 10.
+ .TP 12
+-.B weightedpath <hbtl|devname> <regex1> <prio1> <regex2> <prio2> ...
+-.I hbtl
+-regex can be of SCSI H:B:T:L format Ex: 1:0:.:. , *:0:0:.
+-.I devname
+-regex can be of device name format Ex: sda , sd.e
++.B weightedpath
+ Generate the path priority based on the regular expression and the
+-priority provided as argument.
++priority provided as argument. requires prio_args keyword.
+ .TP
+ Default value is \fBnone\fR.
+ .RE
+ .TP
++.B prio_args
++Arguments to pass to to the prio function. Currently only used with
++.I weighted, which needs a value of the form
++.I "<hbtl|devname> <regex1> <prio1> <regex2> <prio2> ..."
++.I hbtl
++regex can be of SCSI H:B:T:L format Ex: 1:0:.:. , *:0:0:.
++.I devname
++regex can be of device name format Ex: sda , sd.e
++.TP
+ .B features
+ Specify any device-mapper features to be used. Syntax is
+ .I num list
+@@ -238,19 +248,33 @@ Default value is \fIdirectio\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 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
+-the same path group. Default is
++the same path group. This is only for BIO based multipath. Default is
+ .I 1000
+ .TP
++.B rr_min_io_q
++The number of IO requests to route to a path before switching to the
++next in the same path group. This is only for request based multipath.
++Default is
++.I 1
++.TP
+ .B rr_weight
+ If set to \fIpriorities\fR the multipath configurator will assign
+ path weights as "path prio * rr_min_io". Possible values are
+@@ -280,6 +304,13 @@ be overriden by any specific aliases in
+ Default is
+ .I no
+ .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
+@@ -413,12 +444,20 @@ section:
+ .TP
+ .B prio
+ .TP
++.B prio_args
++.TP
+ .B failback
+ .TP
++.B rr_weight
++.TP
++.B flush_on_last_del
++.TP
+ .B no_path_retry
+ .TP
+ .B rr_min_io
+ .TP
++.B rr_min_io_q
++.TP
+ .B features
+ .RE
+ .PD
+@@ -446,6 +485,10 @@ subsection recognizes the following attr
+ .B product_blacklist
+ (Optional) Product strings to blacklist for this vendor
+ .TP
++.B alias_prefix
++(Optional) The user_friendly_names prefix to use for this
++device type, instead of the default "mpath"
++.TP
+ .B hardware_handler
+ (Optional) The hardware handler to use for this device type.
+ The following hardware handler are implemented:
+@@ -483,6 +526,8 @@ section:
+ .TP
+ .B prio
+ .TP
++.B prio_args
++.TP
+ .B features
+ .TP
+ .B failback
+@@ -493,9 +538,13 @@ section:
+ .TP
+ .B rr_min_io
+ .TP
++.B rr_min_io_rq
++.TP
+ .B fast_io_fail_tmo
+ .TP
+ .B dev_loss_tmo
++.TP
++.B flush_on_last_del
+ .RE
+ .PD
+ .LP
diff --git a/0014-RH-RHEL5-style-partitions.patch b/0014-RH-RHEL5-style-partitions.patch
new file mode 100644
index 0000000..47fa725
--- /dev/null
+++ b/0014-RH-RHEL5-style-partitions.patch
@@ -0,0 +1,327 @@
+---
+ kpartx/bsd.c | 35 ---------------
+ kpartx/dos.c | 7 +--
+ kpartx/kpartx.c | 123 +++++++-------------------------------------------------
+ kpartx/kpartx.h | 1
+ kpartx/sun.c | 35 ---------------
+ 5 files changed, 24 insertions(+), 177 deletions(-)
+
+Index: multipath-tools-120123/kpartx/bsd.c
+===================================================================
+--- multipath-tools-120123.orig/kpartx/bsd.c
++++ multipath-tools-120123/kpartx/bsd.c
+@@ -50,10 +50,10 @@ int
+ read_bsd_pt(int fd, struct slice all, struct slice *sp, int ns) {
+ struct bsd_disklabel *l;
+ struct bsd_partition *p;
+- unsigned int offset = all.start, end;
++ unsigned int offset = all.start;
+ int max_partitions;
+ char *bp;
+- int n = 0, i, j;
++ int n = 0;
+
+ bp = getblock(fd, offset+1); /* 1 sector suffices */
+ if (bp == NULL)
+@@ -79,36 +79,5 @@ read_bsd_pt(int fd, struct slice all, st
+ break;
+ }
+ }
+- /*
+- * Convention has it that the bsd disklabel will always have
+- * the 'c' partition spanning the entire disk.
+- * So we have to check for contained slices.
+- */
+- for(i = 0; i < n; i++) {
+- if (sp[i].size == 0)
+- continue;
+-
+- end = sp[i].start + sp[i].size;
+- for(j = 0; j < n; j ++) {
+- if ( i == j )
+- continue;
+- if (sp[j].size == 0)
+- continue;
+-
+- if (sp[i].start < sp[j].start) {
+- if (end > sp[j].start &&
+- end < sp[j].start + sp[j].size) {
+- /* Invalid slice */
+- fprintf(stderr,
+- "bsd_disklabel: slice %d overlaps with %d\n", i , j);
+- sp[i].size = 0;
+- }
+- } else {
+- if (end <= sp[j].start + sp[j].size) {
+- sp[i].container = j + 1;
+- }
+- }
+- }
+- }
+ return n;
+ }
+Index: multipath-tools-120123/kpartx/dos.c
+===================================================================
+--- multipath-tools-120123.orig/kpartx/dos.c
++++ multipath-tools-120123/kpartx/dos.c
+@@ -16,7 +16,7 @@ is_extended(int type) {
+ }
+
+ static int
+-read_extended_partition(int fd, struct partition *ep, int en,
++read_extended_partition(int fd, struct partition *ep,
+ struct slice *sp, int ns)
+ {
+ struct partition p;
+@@ -53,7 +53,6 @@ read_extended_partition(int fd, struct p
+ if (n < ns) {
+ sp[n].start = here + le32_to_cpu(p.start_sect);
+ sp[n].size = le32_to_cpu(p.nr_sects);
+- sp[n].container = en + 1;
+ n++;
+ } else {
+ fprintf(stderr,
+@@ -98,7 +97,9 @@ read_dos_pt(int fd, struct slice all, st
+ break;
+ }
+ if (is_extended(p.sys_type)) {
+- n += read_extended_partition(fd, &p, i, sp+n, ns-n);
++ n += read_extended_partition(fd, &p, sp+n, ns-n);
++ /* hide the extended partition itself */
++ sp[i].size = 2;
+ }
+ }
+ return n;
+Index: multipath-tools-120123/kpartx/kpartx.c
+===================================================================
+--- multipath-tools-120123.orig/kpartx/kpartx.c
++++ multipath-tools-120123/kpartx/kpartx.c
+@@ -190,7 +190,7 @@ get_hotplug_device(void)
+
+ int
+ main(int argc, char **argv){
+- int i, j, m, n, op, off, arg, c, d, ro=0;
++ int i, j, m, n, op, off, arg, ro=0;
+ int fd = -1;
+ struct slice all;
+ struct pt *ptp;
+@@ -380,49 +380,30 @@ main(int argc, char **argv){
+ else
+ continue;
+
++ /*
++ * test for overlap, as in the case of an extended partition
++ * zero their size to avoid mapping
++ */
++ for (j = 0; j < n; j++) {
++ for (m = j + 1; m < n; m++) {
++ if (slices[m].start > slices[j].start &&
++ slices[m].start < slices[j].start +
++ slices[j].size)
++ slices[j].size = 0;
++ }
++ }
++
+ switch(what) {
+ case LIST:
+- for (j = 0, c = 0, m = 0; j < n; j++) {
++ for (j = 0; j < n; j++) {
+ if (slices[j].size == 0)
+ continue;
+- if (slices[j].container > 0) {
+- c++;
+- continue;
+- }
+-
+- slices[j].minor = m++;
+
+ printf("%s%s%d : 0 %" PRIu64 " %s %" PRIu64"\n",
+ mapname, delim, j+1,
+ slices[j].size, device,
+ slices[j].start);
+ }
+- /* Loop to resolve contained slices */
+- d = c;
+- while (c) {
+- for (j = 0; j < n; j++) {
+- uint64_t start;
+- int k = slices[j].container - 1;
+-
+- if (slices[j].size == 0)
+- continue;
+- if (slices[j].minor > 0)
+- continue;
+- if (slices[j].container == 0)
+- continue;
+- slices[j].minor = m++;
+-
+- start = slices[j].start - slices[k].start;
+- printf("%s%s%d : 0 %" PRIu64 " /dev/dm-%d %" PRIu64 "\n",
+- mapname, delim, j+1,
+- slices[j].size,
+- slices[k].minor, start);
+- c--;
+- }
+- /* Terminate loop if nothing more to resolve */
+- if (d == c)
+- break;
+- }
+
+ break;
+
+@@ -461,16 +442,10 @@ main(int argc, char **argv){
+ case ADD:
+ case UPDATE:
+ /* ADD and UPDATE share the same code that adds new partitions. */
+- for (j = 0, c = 0; j < n; j++) {
++ for (j = 0; j < n; j++) {
+ if (slices[j].size == 0)
+ continue;
+
+- /* Skip all contained slices */
+- if (slices[j].container > 0) {
+- c++;
+- continue;
+- }
+-
+ if (safe_sprintf(partname, "%s%s%d",
+ mapname, delim, j+1)) {
+ fprintf(stderr, "partname too small\n");
+@@ -511,72 +486,6 @@ main(int argc, char **argv){
+ slices[j].minor, slices[j].size,
+ DM_TARGET, params);
+ }
+- /* Loop to resolve contained slices */
+- d = c;
+- while (c) {
+- for (j = 0; j < n; j++) {
+- uint64_t start;
+- int k = slices[j].container - 1;
+-
+- if (slices[j].size == 0)
+- continue;
+-
+- /* Skip all existing slices */
+- if (slices[j].minor > 0)
+- continue;
+-
+- /* Skip all simple slices */
+- if (slices[j].container == 0)
+- continue;
+-
+- /* Check container slice */
+- if (slices[k].size == 0)
+- fprintf(stderr, "Invalid slice %d\n",
+- k);
+-
+- if (safe_sprintf(partname, "%s%s%d",
+- mapname, delim, j+1)) {
+- fprintf(stderr, "partname too small\n");
+- exit(1);
+- }
+- strip_slash(partname);
+-
+- start = slices[j].start - slices[k].start;
+- if (safe_sprintf(params, "%d:%d %" PRIu64,
+- slices[k].major,
+- slices[k].minor,
+- start)) {
+- fprintf(stderr, "params too small\n");
+- exit(1);
+- }
+-
+- op = (dm_map_present(partname) ?
+- DM_DEVICE_RELOAD : DM_DEVICE_CREATE);
+-
+- dm_addmap(op, partname, DM_TARGET, params,
+- slices[j].size, ro, uuid, j+1,
+- buf.st_mode & 0777,
+- buf.st_uid, buf.st_gid,
+- &cookie);
+-
+- if (op == DM_DEVICE_RELOAD)
+- dm_simplecmd(DM_DEVICE_RESUME,
+- partname, 1,
+- &cookie);
+-
+- dm_devn(partname, &slices[j].major,
+- &slices[j].minor);
+-
+- if (verbose)
+- printf("add map %s : 0 %" PRIu64 " %s %s\n",
+- partname, slices[j].size,
+- DM_TARGET, params);
+- c--;
+- }
+- /* Terminate loop */
+- if (d == c)
+- break;
+- }
+
+ if (what == ADD) {
+ /* Skip code that removes devmappings for deleted partitions */
+Index: multipath-tools-120123/kpartx/kpartx.h
+===================================================================
+--- multipath-tools-120123.orig/kpartx/kpartx.h
++++ multipath-tools-120123/kpartx/kpartx.h
+@@ -24,7 +24,6 @@
+ struct slice {
+ uint64_t start;
+ uint64_t size;
+- int container;
+ int major;
+ int minor;
+ };
+Index: multipath-tools-120123/kpartx/sun.c
+===================================================================
+--- multipath-tools-120123.orig/kpartx/sun.c
++++ multipath-tools-120123/kpartx/sun.c
+@@ -62,8 +62,8 @@ int
+ read_sun_pt(int fd, struct slice all, struct slice *sp, int ns) {
+ struct sun_disk_label *l;
+ struct sun_raw_part *s;
+- unsigned int offset = all.start, end;
+- int i, j, n;
++ unsigned int offset = all.start;
++ int i, n;
+ char *bp;
+
+ bp = getblock(fd, offset);
+@@ -95,37 +95,6 @@ read_sun_pt(int fd, struct slice all, st
+ break;
+ }
+ }
+- /*
+- * Convention has it that the SUN disklabel will always have
+- * the 'c' partition spanning the entire disk.
+- * So we have to check for contained slices.
+- */
+- for(i = 0; i < SUN_DISK_MAXPARTITIONS; i++) {
+- if (sp[i].size == 0)
+- continue;
+-
+- end = sp[i].start + sp[i].size;
+- for(j = 0; j < SUN_DISK_MAXPARTITIONS; j ++) {
+- if ( i == j )
+- continue;
+- if (sp[j].size == 0)
+- continue;
+-
+- if (sp[i].start < sp[j].start) {
+- if (end > sp[j].start &&
+- end < sp[j].start + sp[j].size) {
+- /* Invalid slice */
+- fprintf(stderr,
+- "sun_disklabel: slice %d overlaps with %d\n", i , j);
+- sp[i].size = 0;
+- }
+- } else {
+- if (end <= sp[j].start + sp[j].size) {
+- sp[i].container = j + 1;
+- }
+- }
+- }
+- }
+ return n;
+ }
+
diff --git a/0015-RH-add-followover.patch b/0015-RH-add-followover.patch
new file mode 100644
index 0000000..9f28342
--- /dev/null
+++ b/0015-RH-add-followover.patch
@@ -0,0 +1,156 @@
+---
+ libmultipath/dict.c | 12 ++++++++++++
+ libmultipath/print.c | 2 ++
+ libmultipath/structs.h | 3 ++-
+ multipath/multipath.conf.5 | 5 +++++
+ multipathd/main.c | 29 ++++++++++++++++++++++++++++-
+ 5 files changed, 49 insertions(+), 2 deletions(-)
+
+Index: multipath-tools-120123/libmultipath/dict.c
+===================================================================
+--- multipath-tools-120123.orig/libmultipath/dict.c
++++ multipath-tools-120123/libmultipath/dict.c
+@@ -406,6 +406,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);
+
+@@ -1031,6 +1033,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);
+
+@@ -1303,6 +1307,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);
+
+@@ -1646,6 +1652,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);
+ }
+@@ -1985,6 +1993,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);
+ }
+@@ -2243,6 +2253,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", conf->pgfailback);
+ }
+Index: multipath-tools-120123/libmultipath/print.c
+===================================================================
+--- multipath-tools-120123.orig/libmultipath/print.c
++++ multipath-tools-120123/libmultipath/print.c
+@@ -143,6 +143,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-120123/libmultipath/structs.h
+===================================================================
+--- multipath-tools-120123.orig/libmultipath/structs.h
++++ multipath-tools-120123/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-120123/multipathd/main.c
+===================================================================
+--- multipath-tools-120123.orig/multipathd/main.c
++++ multipath-tools-120123/multipathd/main.c
+@@ -1011,6 +1011,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)
+ {
+@@ -1238,7 +1264,8 @@ check_path (struct vectors * vecs, struc
+ (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 ||
++ followover_should_failback(pp))
+ switch_pathgroup(pp->mpp);
+ }
+ }
+Index: multipath-tools-120123/multipath/multipath.conf.5
+===================================================================
+--- multipath-tools-120123.orig/multipath/multipath.conf.5
++++ multipath-tools-120123/multipath/multipath.conf.5
+@@ -258,6 +258,11 @@ active paths.
+ .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
diff --git a/0016-RH-dont-remove-map-on-enomem.patch b/0016-RH-dont-remove-map-on-enomem.patch
new file mode 100644
index 0000000..5b54a4a
--- /dev/null
+++ b/0016-RH-dont-remove-map-on-enomem.patch
@@ -0,0 +1,18 @@
+---
+ multipathd/main.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+Index: multipath-tools-120123/multipathd/main.c
+===================================================================
+--- multipath-tools-120123.orig/multipathd/main.c
++++ multipath-tools-120123/multipathd/main.c
+@@ -1003,7 +1003,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/0017-RH-fix-shutdown-crash.patch b/0017-RH-fix-shutdown-crash.patch
new file mode 100644
index 0000000..0e4f345
--- /dev/null
+++ b/0017-RH-fix-shutdown-crash.patch
@@ -0,0 +1,69 @@
+---
+ libmultipath/log_pthread.c | 1 +
+ libmultipath/waiter.c | 1 +
+ multipathd/main.c | 6 +++++-
+ 3 files changed, 7 insertions(+), 1 deletion(-)
+
+Index: multipath-tools-120123/multipathd/main.c
+===================================================================
+--- multipath-tools-120123.orig/multipathd/main.c
++++ multipath-tools-120123/multipathd/main.c
+@@ -735,6 +735,7 @@ uxsock_trigger (char * str, char ** repl
+
+ pthread_cleanup_push(cleanup_lock, &vecs->lock);
+ lock(vecs->lock);
++ pthread_testcancel();
+
+ r = parse_cmd(str, reply, len, vecs);
+
+@@ -787,7 +788,9 @@ uev_trigger (struct uevent * uev, void *
+ if (uev_discard(uev->devpath))
+ return 0;
+
++ pthread_cleanup_push(cleanup_lock, &vecs->lock);
+ lock(vecs->lock);
++ pthread_testcancel();
+
+ /*
+ * device map event
+@@ -827,7 +830,7 @@ uev_trigger (struct uevent * uev, void *
+ }
+
+ out:
+- unlock(vecs->lock);
++ lock_cleanup_pop(vecs->lock);
+ return r;
+ }
+
+@@ -1295,6 +1298,7 @@ checkerloop (void *ap)
+ block_signal(SIGHUP, &old);
+ pthread_cleanup_push(cleanup_lock, &vecs->lock);
+ lock(vecs->lock);
++ pthread_testcancel();
+ condlog(4, "tick");
+
+ if (vecs->pathvec) {
+Index: multipath-tools-120123/libmultipath/waiter.c
+===================================================================
+--- multipath-tools-120123.orig/libmultipath/waiter.c
++++ multipath-tools-120123/libmultipath/waiter.c
+@@ -157,6 +157,7 @@ int waiteventloop (struct event_thread *
+ */
+ pthread_cleanup_push(cleanup_lock, &waiter->vecs->lock);
+ lock(waiter->vecs->lock);
++ pthread_testcancel();
+ r = update_multipath(waiter->vecs, waiter->mapname, 1);
+ lock_cleanup_pop(waiter->vecs->lock);
+
+Index: multipath-tools-120123/libmultipath/log_pthread.c
+===================================================================
+--- multipath-tools-120123.orig/libmultipath/log_pthread.c
++++ multipath-tools-120123/libmultipath/log_pthread.c
+@@ -87,6 +87,7 @@ void log_thread_stop (void)
+ pthread_mutex_lock(logq_lock);
+ pthread_cancel(log_thr);
+ pthread_mutex_unlock(logq_lock);
++ pthread_join(log_thr, NULL);
+
+ flush_logqueue();
+
diff --git a/0018-RH-warn-on-bad-dev-loss-tmo.patch b/0018-RH-warn-on-bad-dev-loss-tmo.patch
new file mode 100644
index 0000000..508a02a
--- /dev/null
+++ b/0018-RH-warn-on-bad-dev-loss-tmo.patch
@@ -0,0 +1,68 @@
+---
+ libmultipath/discovery.c | 22 +++++++++++++++-------
+ libmultipath/structs_vec.c | 5 -----
+ 2 files changed, 15 insertions(+), 12 deletions(-)
+
+Index: multipath-tools-120123/libmultipath/discovery.c
+===================================================================
+--- multipath-tools-120123.orig/libmultipath/discovery.c
++++ multipath-tools-120123/libmultipath/discovery.c
+@@ -299,17 +299,17 @@ sysfs_set_scsi_tmo (struct multipath *mp
+ no_path_retry_tmo = MAX_DEV_LOSS_TMO;
+ if (no_path_retry_tmo > dev_loss_tmo)
+ dev_loss_tmo = no_path_retry_tmo;
+- condlog(3, "%s: update dev_loss_tmo to %d\n",
++ condlog(3, "%s: update dev_loss_tmo to %d",
+ mpp->alias, dev_loss_tmo);
+ } else if (mpp->no_path_retry == NO_PATH_RETRY_QUEUE) {
+ dev_loss_tmo = MAX_DEV_LOSS_TMO;
+- condlog(4, "%s: update dev_loss_tmo to %d\n",
++ condlog(3, "%s: update dev_loss_tmo to %d",
+ mpp->alias, dev_loss_tmo);
+ }
+ mpp->dev_loss = dev_loss_tmo;
+- if (mpp->fast_io_fail > mpp->dev_loss) {
++ if (mpp->fast_io_fail > (int)mpp->dev_loss) {
+ mpp->fast_io_fail = mpp->dev_loss;
+- condlog(3, "%s: update fast_io_fail to %d\n",
++ condlog(3, "%s: update fast_io_fail to %d",
+ mpp->alias, mpp->fast_io_fail);
+ }
+ if (!mpp->dev_loss && !mpp->fast_io_fail)
+@@ -333,9 +333,17 @@ sysfs_set_scsi_tmo (struct multipath *mp
+ snprintf(value, 11, "%u", mpp->dev_loss);
+ if (sysfs_attr_set_value(attr_path, "dev_loss_tmo",
+ value, 11) < 0) {
+- condlog(0, "%s failed to set %s/dev_loss_tmo",
+- mpp->alias, attr_path);
+- return 1;
++ int err = 1;
++ if (mpp->fast_io_fail <= 0 && mpp->dev_loss > 600) {
++ strncpy(value, "600", 4);
++ condlog(3, "%s: limiting dev_loss_tmo to 600, since fast_io_fail is not set", mpp->alias);
++ if (sysfs_attr_set_value(attr_path, "dev_loss_tmo", value, 11) >= 0)
++ err = 0;
++ }
++ if (err) {
++ condlog(0, "%s failed to set %s/dev_loss_tmo", mpp->alias, attr_path);
++ return 1;
++ }
+ }
+ }
+ if (mpp->fast_io_fail){
+Index: multipath-tools-120123/libmultipath/structs_vec.c
+===================================================================
+--- multipath-tools-120123.orig/libmultipath/structs_vec.c
++++ multipath-tools-120123/libmultipath/structs_vec.c
+@@ -441,11 +441,6 @@ verify_paths(struct multipath * mpp, str
+ if (!mpp)
+ return 0;
+
+- select_features(mpp);
+- select_no_path_retry(mpp);
+- select_dev_loss(mpp);
+- sysfs_set_scsi_tmo(mpp);
+-
+ vector_foreach_slot (mpp->paths, pp, i) {
+ /*
+ * see if path is in sysfs
diff --git a/0019-RH-deprecate-uid-gid-mode.patch b/0019-RH-deprecate-uid-gid-mode.patch
new file mode 100644
index 0000000..9270d9d
--- /dev/null
+++ b/0019-RH-deprecate-uid-gid-mode.patch
@@ -0,0 +1,90 @@
+---
+ multipath.conf.annotated | 53 -----------------------------------------------
+ multipath.conf.synthetic | 3 --
+ 2 files changed, 56 deletions(-)
+
+Index: multipath-tools-120123/multipath.conf.annotated
+===================================================================
+--- multipath-tools-120123.orig/multipath.conf.annotated
++++ multipath-tools-120123/multipath.conf.annotated
+@@ -186,32 +186,6 @@
+ # user_friendly_names no
+ #
+ # #
+-# # name : mode
+-# # scope : multipath & multipathd
+-# # 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 & multipathd
+-# # desc : The user id to use for the multipath device nodes. You
+-# # may use either the numeric or symbolic uid
+-# # values : <user_id>
+-# # default : determined by the process
+-# uid 0
+-#
+-# #
+-# # name : gid
+-# # scope : multipath & multipathd
+-# # desc : The group id to user for the multipath device nodes. You
+-# # may use either the numeric or symbolic gid
+-# # values : <group_id>
+-# # default : determined by the process
+-# gid disk
+-#
+-# #
+ # # name : checker_timeout
+ # # scope : multipath & multipathd
+ # # desc : The timeout to use for path checkers that issue scsi
+@@ -388,33 +362,6 @@
+ # #
+ # flush_on_last_del yes
+ #
+-# #
+-# # name : mode
+-# # scope : multipath & multipathd
+-# # 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 & multipathd
+-# # desc : The user id to use for the multipath device nodes.
+-# # You may use either the numeric or symbolic uid
+-# # values : <user_id>
+-# # default : determined by the process
+-# uid 0
+-#
+-# #
+-# # name : gid
+-# # scope : multipath & multipathd
+-# # desc : The group id to user for the multipath device nodes.
+-# # You may use either the numeric or symbolic gid
+-# # values : <group_id>
+-# # default : determined by the process
+-# gid 0
+-#
+ # }
+ # multipath {
+ # wwid 1DEC_____321816758474
+Index: multipath-tools-120123/multipath.conf.synthetic
+===================================================================
+--- multipath-tools-120123.orig/multipath.conf.synthetic
++++ multipath-tools-120123/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
diff --git a/0020-RH-dont-remove-map-twice.patch b/0020-RH-dont-remove-map-twice.patch
new file mode 100644
index 0000000..559ec1e
--- /dev/null
+++ b/0020-RH-dont-remove-map-twice.patch
@@ -0,0 +1,17 @@
+---
+ multipathd/main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: multipath-tools-120123/multipathd/main.c
+===================================================================
+--- multipath-tools-120123.orig/multipathd/main.c
++++ multipath-tools-120123/multipathd/main.c
+@@ -524,7 +524,7 @@ rescan:
+ * update our state from kernel regardless of create or reload
+ */
+ if (setup_multipath(vecs, mpp))
+- goto fail_map;
++ goto fail; /* if setup_multipath fails, it removes the map */
+
+ sync_map_state(mpp);
+
diff --git a/0021-RH-validate-guid-partitions.patch b/0021-RH-validate-guid-partitions.patch
new file mode 100644
index 0000000..19040d3
--- /dev/null
+++ b/0021-RH-validate-guid-partitions.patch
@@ -0,0 +1,24 @@
+---
+ kpartx/gpt.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+Index: multipath-tools-120123/kpartx/gpt.c
+===================================================================
+--- multipath-tools-120123.orig/kpartx/gpt.c
++++ multipath-tools-120123/kpartx/gpt.c
+@@ -367,6 +367,15 @@ is_gpt_valid(int fd, uint64_t lba,
+ }
+
+
++ /* Check that sizeof_partition_entry has the correct value */
++ if (__le32_to_cpu((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) {
++ // printf("GUID partition entry size check failed.\n");
++ free(*gpt);
++ *gpt = NULL;
++ return 0;
++ }
++
++
+ if (!(*ptes = alloc_read_gpt_entries(fd, *gpt))) {
+ free(*gpt);
+ *gpt = NULL;
diff --git a/0022-RH-adjust-messages.patch b/0022-RH-adjust-messages.patch
new file mode 100644
index 0000000..d7b021a
--- /dev/null
+++ b/0022-RH-adjust-messages.patch
@@ -0,0 +1,32 @@
+---
+ libmultipath/configure.c | 3 +++
+ libmultipath/discovery.c | 2 +-
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+Index: multipath-tools-120123/libmultipath/configure.c
+===================================================================
+--- multipath-tools-120123.orig/libmultipath/configure.c
++++ multipath-tools-120123/libmultipath/configure.c
+@@ -590,6 +590,9 @@ coalesce_paths (struct vectors * vecs, v
+ "for create/reload map",
+ mpp->alias, r);
+ if (r == DOMAP_FAIL) {
++ condlog(2, "%s: %s map",
++ mpp->alias, (mpp->action == ACT_CREATE)?
++ "ignoring" : "removing");
+ remove_map(mpp, vecs, 0);
+ continue;
+ } else /* if (r == DOMAP_RETRY) */
+Index: multipath-tools-120123/libmultipath/discovery.c
+===================================================================
+--- multipath-tools-120123.orig/libmultipath/discovery.c
++++ multipath-tools-120123/libmultipath/discovery.c
+@@ -318,7 +318,7 @@ sysfs_set_scsi_tmo (struct multipath *mp
+ 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);
++ condlog(3, "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;
+ }
+
diff --git a/0023-RH-manpage-update.patch b/0023-RH-manpage-update.patch
new file mode 100644
index 0000000..475ad41
--- /dev/null
+++ b/0023-RH-manpage-update.patch
@@ -0,0 +1,19 @@
+---
+ multipath/multipath.conf.5 | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+Index: multipath-tools-120123/multipath/multipath.conf.5
+===================================================================
+--- multipath-tools-120123.orig/multipath/multipath.conf.5
++++ multipath-tools-120123/multipath/multipath.conf.5
+@@ -338,7 +338,9 @@ will disable the timeout.
+ .TP
+ .B dev_loss_tmo
+ Specify the number of seconds the scsi layer will wait after a problem has
+-been detected on a FC remote port before removing it from the system.
++been detected on a FC remote port before removing it from the system. This
++can be set to "infinity" which sets it to the max value of 2147483647
++seconds, or 68 years.
+ .TP
+ .B queue_without_daemon
+ If set to
diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec
index cffd86a..59570ef 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: 21%{?dist}
+Release: 22%{?dist}
License: GPL+
Group: System Environment/Base
URL: http://christophe.varoqui.free.fr/
@@ -19,6 +19,18 @@ Patch0008: 0008-RH-add-mpathconf.patch
Patch0009: 0009-RH-add-find-multipaths.patch
Patch0010: 0010-RH-check-if-multipath-owns-path.patch
Patch0011: 0011-RH-add-hp_tur-checker.patch
+Patch0012: 0012-RH-update-on-show-topology.patch
+Patch0013: 0013-RH-manpage-update.patch
+Patch0014: 0014-RH-RHEL5-style-partitions.patch
+Patch0015: 0015-RH-add-followover.patch
+Patch0016: 0016-RH-dont-remove-map-on-enomem.patch
+Patch0017: 0017-RH-fix-shutdown-crash.patch
+Patch0018: 0018-RH-warn-on-bad-dev-loss-tmo.patch
+Patch0019: 0019-RH-deprecate-uid-gid-mode.patch
+Patch0020: 0020-RH-dont-remove-map-twice.patch
+Patch0021: 0021-RH-validate-guid-partitions.patch
+Patch0022: 0022-RH-adjust-messages.patch
+Patch0023: 0023-RH-manpage-update.patch
# runtime
Requires: %{name}-libs = %{version}-%{release}
@@ -82,6 +94,18 @@ kpartx manages partition creation and removal for device-mapper devices.
%patch0009 -p1
%patch0010 -p1
%patch0011 -p1
+%patch0012 -p1
+%patch0013 -p1
+%patch0014 -p1
+%patch0015 -p1
+%patch0016 -p1
+%patch0017 -p1
+%patch0018 -p1
+%patch0019 -p1
+%patch0020 -p1
+%patch0021 -p1
+%patch0022 -p1
+%patch0023 -p1
cp %{SOURCE1} .
%build
@@ -172,6 +196,20 @@ bin/systemctl --no-reload enable multipathd.service >/dev/null 2>&1 ||:
%{_mandir}/man8/kpartx.8.gz
%changelog
+* Fri Feb 10 2012 Benjamin Marzinski <bmarzins@redhat.com> 0.4.9-22
+- Add 0012-RH-update-on-show-topology.patch
+- Add 0013-RH-manpage-update.patch
+- Add 0014-RH-RHEL5-style-partitions.patch
+- Add 0015-RH-add-followover.patch
+- Add 0016-RH-dont-remove-map-on-enomem.patch
+- Add 0017-RH-fix-shutdown-crash.patch
+- Add 0018-RH-warn-on-bad-dev-loss-tmo.patch
+- Add 0019-RH-deprecate-uid-gid-mode.patch
+- Add 0020-RH-dont-remove-map-twice.patch
+- Add 0021-RH-validate-guid-partitions.patch
+- Add 0022-RH-adjust-messages.patch
+- Add 0023-RH-manpage-update.patch
+
* Tue Jan 24 2012 Benjamin Marzinski <bmarzins@redhat.com> 0.4.9-21
- Updated to latest upstream 0.4.9 code : multipath-tools-120123.tgz
(git commit id: 63704387009443bdb37d9deaaafa9ab121d45bfb)