After manually failing some paths and then reinstating them, the following pattern of events has been observed:
[1535664.790944] localhost multipathd[26335]: mpathc: reinstate path 8:48 (operator) [1535664.791422] localhost multipathd[26335]: mpathc: devmap event #4 [1535664.793140] localhost kernel: device-mapper: multipath: 254:6: Reinstating path 8:48. [1535665.219024] localhost multipathd[26335]: mpathc: reload [0 125829120 multipath 1 queue_if_no_path 1 alua 2 1 queue-length 0 2 1 8:144 1 8:240 1 queue-length 0 2 1 8:48 1 65:80 1] [1535665.290268] localhost multipathd[26335]: sync_map_state: failing sdd state 2 dmstate 2 [1535665.292442] localhost kernel: device-mapper: multipath: 254:6: Failing path 8:48. [1535669.291320] localhost multipathd[26335]: sdd: tur state = up [1535669.291531] localhost multipathd[26335]: mpathc: sdd - tur checker reports path is up [1535669.291531] localhost multipathd[26335]: 8:48: reinstated We see that sdd (8:48) is first reinstated, then failed again during the reload operation, and finally reinstated in the checker. This happens because multipathd doesn't update the internal path state when it calls dm_reinstate_path(). If sync_map_state() is called, it will see the path in PATH_DOWN state and fail the path again. Fix it by setting pp->state to PATH_UNCHECKED. Signed-off-by: Martin Wilck <mwi...@suse.com> --- multipathd/cli_handlers.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c index 4bcc82a..fcb8775 100644 --- a/multipathd/cli_handlers.c +++ b/multipathd/cli_handlers.c @@ -1115,6 +1115,18 @@ cli_reinstate(void * v, struct strbuf *reply, void * data) pp->mpp->alias, pp->dev_t); checker_enable(&pp->checker); + + /* + * A path previously failed by the operator will be in PATH_DOWN state + * (set by update_multipath()). + * After the path has been reinstated in the kernel, and before + * the checker updates the path state, we may need to reload + * the map (e.g. for failback, while handling a dm event). + * If the path is still in PATH_DOWN state at that time, sync_map_state() + * will call dm_fail_path() again. + * Avoid that by setting the state to PATH_UNCHECKED. + */ + pp->state = PATH_UNCHECKED; pp->tick = 1; return dm_reinstate_path(pp->mpp->alias, pp->dev_t); } -- 2.50.0