summaryrefslogtreecommitdiffstats
path: root/0189-RHBZ-1368211-remove-retries.patch
blob: 253d57258e1adc953f12214ea1086e9d5c3d87d8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
---
 libmultipath/config.c      |    1 +
 libmultipath/config.h      |    1 +
 libmultipath/devmapper.c   |   35 +++++++++++++++++++----------------
 libmultipath/dict.c        |   25 +++++++++++++++++++++++++
 multipath.conf.defaults    |    1 +
 multipath/multipath.conf.5 |    5 +++++
 6 files changed, 52 insertions(+), 16 deletions(-)

Index: multipath-tools-130222/libmultipath/devmapper.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/devmapper.c
+++ multipath-tools-130222/libmultipath/devmapper.c
@@ -803,10 +803,11 @@ dm_flush_map_nopaths(const char * mapnam
 extern int
 dm_suspend_and_flush_map (const char * mapname)
 {
-	int s = 0, queue_if_no_path = 0;
+	int need_reset = 0, queue_if_no_path = 0;
 	unsigned long long mapsize;
 	char params[PARAMS_SIZE] = {0};
 	int udev_flags = 0;
+	int retries = conf->remove_retries;
 
 	if (!dm_is_mpath(mapname))
 		return 0; /* nothing to do */
@@ -821,22 +822,24 @@ dm_suspend_and_flush_map (const char * m
 			queue_if_no_path = 1;
 	}
 
-	if (queue_if_no_path)
-		s = dm_queue_if_no_path((char *)mapname, 0);
-	/* Leave queue_if_no_path alone if unset failed */
-	if (s)
-		queue_if_no_path = 0;
-	else
-		s = dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 0, 0);
-
-	if (!dm_flush_map(mapname)) {
-		condlog(4, "multipath map %s removed", mapname);
-		return 0;
-	}
+	if (queue_if_no_path && dm_queue_if_no_path((char *)mapname, 0) == 0)
+		need_reset = 1;
+
+	do {
+		if (!queue_if_no_path || need_reset)
+			dm_simplecmd_flush(DM_DEVICE_SUSPEND, mapname, 0, 0);
+
+		if (!dm_flush_map(mapname)) {
+			condlog(4, "multipath map %s removed", mapname);
+			return 0;
+		}
+		dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname, udev_flags);
+		if (retries)
+			sleep(1);
+	} while (retries-- > 0);
 	condlog(2, "failed to remove multipath map %s", mapname);
-	dm_simplecmd_noflush(DM_DEVICE_RESUME, mapname, udev_flags);
-	if (queue_if_no_path)
-		s = dm_queue_if_no_path((char *)mapname, 1);
+	if (need_reset)
+		dm_queue_if_no_path((char *)mapname, 1);
 	return 1;
 }
 
Index: multipath-tools-130222/libmultipath/config.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/config.c
+++ multipath-tools-130222/libmultipath/config.c
@@ -680,6 +680,7 @@ load_config (char * file, struct udev *u
 	conf->new_bindings_in_boot = 0;
 	conf->uev_wait_timeout = DEFAULT_UEV_WAIT_TIMEOUT;
 	conf->skip_kpartx = DEFAULT_SKIP_KPARTX;
+	conf->remove_retries = 0;
 
 	/*
 	 * preload default hwtable
Index: multipath-tools-130222/libmultipath/config.h
===================================================================
--- multipath-tools-130222.orig/libmultipath/config.h
+++ multipath-tools-130222/libmultipath/config.h
@@ -146,6 +146,7 @@ struct config {
 	int delayed_reconfig;
 	int uev_wait_timeout;
 	int skip_kpartx;
+	int remove_retries;
 	unsigned int version[3];
 
 	char * dev;
Index: multipath-tools-130222/libmultipath/dict.c
===================================================================
--- multipath-tools-130222.orig/libmultipath/dict.c
+++ multipath-tools-130222/libmultipath/dict.c
@@ -935,6 +935,24 @@ def_new_bindings_in_boot_handler(vector
 	return 0;
 }
 
+static int
+def_remove_retries_handler(vector strvec)
+{
+	char *buff;
+
+	buff = set_value(strvec);
+
+	if (!buff)
+		return 1;
+
+	conf->remove_retries = atoi(buff);
+	if (conf->remove_retries < 0)
+		conf->remove_retries = 0;
+	FREE(buff);
+
+	return 0;
+}
+
 /*
  * blacklist block handlers
  */
@@ -3405,6 +3423,12 @@ snprint_def_new_bindings_in_boot(char *
 }
 
 static int
+snprint_def_remove_retries (char * buff, int len, void * data)
+{
+	return snprintf(buff, len, "%i", conf->remove_retries);
+}
+
+static int
 snprint_ble_simple (char * buff, int len, void * data)
 {
 	struct blentry * ble = (struct blentry *)data;
@@ -3483,6 +3507,7 @@ init_keywords(void)
 	install_keyword("retrigger_delay", &def_retrigger_delay_handler, &snprint_def_retrigger_delay);
 	install_keyword("missing_uev_wait_timeout", &def_uev_wait_timeout_handler, &snprint_def_uev_wait_timeout);
 	install_keyword("new_bindings_in_boot", &def_new_bindings_in_boot_handler, &snprint_def_new_bindings_in_boot);
+	install_keyword("remove_retries", &def_remove_retries_handler, &snprint_def_remove_retries);
 	__deprecated install_keyword("default_selector", &def_selector_handler, NULL);
 	__deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
 	__deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
Index: multipath-tools-130222/multipath.conf.defaults
===================================================================
--- multipath-tools-130222.orig/multipath.conf.defaults
+++ multipath-tools-130222/multipath.conf.defaults
@@ -41,6 +41,7 @@
 #	retrigger_delay 10
 #	missing_uev_wait_timeout 30
 #	new_bindings_in_boot no
+#	remove_retries 0
 #}
 #blacklist {
 #	devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*"
Index: multipath-tools-130222/multipath/multipath.conf.5
===================================================================
--- multipath-tools-130222.orig/multipath/multipath.conf.5
+++ multipath-tools-130222/multipath/multipath.conf.5
@@ -556,6 +556,11 @@ user_friendly_names.  When multipathd is
 regular filesystem, the device will be renamed to a user_friendly_name. The
 default is
 .I no
+.TP
+.B remove_retries
+This sets how may times multipath will retry removing a device that is in-use.
+Between each attempt, multipath will sleep 1 second. The default is
+.I 0
 .
 .SH "blacklist section"
 The