@@ -1240,9 +1240,7 @@ int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid,
mpp->no_path_retry != NO_PATH_RETRY_FAIL)
condlog(3, "%s: multipathd not running, unset "
"queue_if_no_path feature", mpp->alias);
- if (!dm_queue_if_no_path(mpp->alias, 0))
- remove_feature(&mpp->features,
- "queue_if_no_path");
+ dm_queue_if_no_path(mpp, 0);
}
if (!is_daemon && mpp->action != ACT_NOTHING)
@@ -56,6 +56,7 @@ static int dm_cancel_remove_partmaps(const char * mapname);
static int do_foreach_partmaps(const char * mapname,
int (*partmap_func)(const char *, void *),
void *data);
+static int _dm_queue_if_no_path(const char *mapname, int enable);
#ifndef LIBDM_API_COOKIE
static inline int dm_task_set_cookie(struct dm_task *dmt, uint32_t *c, int a)
@@ -1085,7 +1086,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove,
if (need_suspend &&
dm_get_map(mapname, &mapsize, ¶ms) == DMP_OK &&
strstr(params, "queue_if_no_path")) {
- if (!dm_queue_if_no_path(mapname, 0))
+ if (!_dm_queue_if_no_path(mapname, 0))
queue_if_no_path = 1;
else
/* Leave queue_if_no_path alone if unset failed */
@@ -1134,7 +1135,7 @@ int _dm_flush_map (const char * mapname, int need_sync, int deferred_remove,
} while (retries-- > 0);
if (queue_if_no_path == 1)
- dm_queue_if_no_path(mapname, 1);
+ _dm_queue_if_no_path(mapname, 1);
return 1;
}
@@ -1252,8 +1253,8 @@ dm_reinstate_path(const char * mapname, char * path)
return dm_message(mapname, message);
}
-int
-dm_queue_if_no_path(const char *mapname, int enable)
+static int
+_dm_queue_if_no_path(const char *mapname, int enable)
{
char *message;
@@ -1265,6 +1266,20 @@ dm_queue_if_no_path(const char *mapname, int enable)
return dm_message(mapname, message);
}
+int dm_queue_if_no_path(struct multipath *mpp, int enable)
+{
+ int r;
+ static const char no_path_retry[] = "queue_if_no_path";
+
+ if ((r = _dm_queue_if_no_path(mpp->alias, enable)) == 0) {
+ if (enable)
+ add_feature(&mpp->features, no_path_retry);
+ else
+ remove_feature(&mpp->features, no_path_retry);
+ }
+ return r;
+}
+
static int
dm_groupmsg (const char * msg, const char * mapname, int index)
{
@@ -58,7 +58,7 @@ int dm_cancel_deferred_remove(struct multipath *mpp);
int dm_flush_maps (int need_suspend, int retries);
int dm_fail_path(const char * mapname, char * path);
int dm_reinstate_path(const char * mapname, char * path);
-int dm_queue_if_no_path(const char *mapname, int enable);
+int dm_queue_if_no_path(struct multipath *mpp, int enable);
int dm_switchgroup(const char * mapname, int index);
int dm_enablegroup(const char * mapname, int index);
int dm_disablegroup(const char * mapname, int index);
@@ -593,7 +593,7 @@ static void leave_recovery_mode(struct multipath *mpp)
*/
if (recovery && (mpp->no_path_retry == NO_PATH_RETRY_QUEUE ||
mpp->no_path_retry > 0)) {
- dm_queue_if_no_path(mpp->alias, 1);
+ dm_queue_if_no_path(mpp, 1);
condlog(2, "%s: queue_if_no_path enabled", mpp->alias);
condlog(1, "%s: Recovered to normal mode", mpp->alias);
}
@@ -611,11 +611,11 @@ void set_no_path_retry(struct multipath *mpp)
break;
case NO_PATH_RETRY_FAIL:
if (!mpp->features || is_queueing)
- dm_queue_if_no_path(mpp->alias, 0);
+ dm_queue_if_no_path(mpp, 0);
break;
case NO_PATH_RETRY_QUEUE:
if (!mpp->features || !is_queueing)
- dm_queue_if_no_path(mpp->alias, 1);
+ dm_queue_if_no_path(mpp, 1);
break;
default:
if (count_active_paths(mpp) > 0) {
@@ -625,7 +625,7 @@ void set_no_path_retry(struct multipath *mpp)
*/
if ((!mpp->features || !is_queueing) &&
!mpp->in_recovery)
- dm_queue_if_no_path(mpp->alias, 1);
+ dm_queue_if_no_path(mpp, 1);
leave_recovery_mode(mpp);
} else {
/*
@@ -636,7 +636,7 @@ void set_no_path_retry(struct multipath *mpp)
*/
if ((!mpp->features || is_queueing) &&
mpp->in_recovery && mpp->retry_tick == 0)
- dm_queue_if_no_path(mpp->alias, 0);
+ dm_queue_if_no_path(mpp, 0);
if (pathcount(mpp, PATH_PENDING) == 0)
enter_recovery_mode(mpp);
}
@@ -596,7 +596,7 @@ flush_map_nopaths(struct multipath *mpp, struct vectors *vecs) {
mpp->no_path_retry = NO_PATH_RETRY_FAIL;
mpp->disable_queueing = 1;
mpp->stat_map_failures++;
- dm_queue_if_no_path(mpp->alias, 0);
+ dm_queue_if_no_path(mpp, 0);
}
if (!flush_map(mpp, vecs, 1)) {
condlog(2, "%s: removed map after removing all paths", alias);
@@ -930,7 +930,7 @@ uev_remove_map (struct uevent * uev, struct vectors * vecs)
goto out;
}
- dm_queue_if_no_path(alias, 0);
+ dm_queue_if_no_path(mpp, 0);
remove_map_and_stop_waiter(mpp, vecs);
out:
lock_cleanup_pop(vecs->lock);
@@ -2094,7 +2094,7 @@ retry_count_tick(vector mpvec)
condlog(4, "%s: Retrying.. No active path", mpp->alias);
if(--mpp->retry_tick == 0) {
mpp->stat_map_failures++;
- dm_queue_if_no_path(mpp->alias, 0);
+ dm_queue_if_no_path(mpp, 0);
condlog(2, "%s: Disable queueing", mpp->alias);
}
}
@@ -3260,7 +3260,7 @@ static void cleanup_maps(struct vectors *vecs)
put_multipath_config(conf);
if (queue_without_daemon == QUE_NO_DAEMON_OFF)
vector_foreach_slot(vecs->mpvec, mpp, i)
- dm_queue_if_no_path(mpp->alias, 0);
+ dm_queue_if_no_path(mpp, 0);
remove_maps_and_stop_waiters(vecs);
vecs->mpvec = NULL;
}
Make multipathd update mpp->features when in enables or disables queuing. This patch handles all the cases except failed removes by dm_suspend_and_flush_map(), which is never called by multipathd. Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> --- libmultipath/configure.c | 4 +--- libmultipath/devmapper.c | 23 +++++++++++++++++++---- libmultipath/devmapper.h | 2 +- libmultipath/structs_vec.c | 10 +++++----- multipathd/main.c | 8 ++++---- 5 files changed, 30 insertions(+), 17 deletions(-)