libmultipath: fix marginal paths queueing errors
authorBenjamin Marzinski <bmarzins@redhat.com>
Sat, 30 Mar 2019 06:05:53 +0000 (01:05 -0500)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Thu, 18 Apr 2019 11:03:28 +0000 (13:03 +0200)
commit058df778da4dc8bbcfe898d95709b47929d45c97
tree04819f8c0db6063c2421e33fbb193837089d28ea
parentff6ae2ef54f2e8063cb0d0b8fbfa1b481eb5f3a6
libmultipath: fix marginal paths queueing errors

The current marginal paths code tries to enqueue paths for io error
checking when multipathd receives a uevent on path failure. This can run
into a couple of problems. First, this uevent could happen before or
after multipathd actually fails the path, so simply checking nr_active
doesn't tell us if this is the last active path. Also, The code to fail
the path in enqueue_io_err_stat_by_path() doesn't ever update the path
state. This can cause the path to get failed twice, temporarily leading
to incorrect nr_active counts. Further, The point when multipathd should
care if this is the last active path is when the path has come up again,
not when it goes down. Lastly, if the path is down, it is often
impossible to open the path device, causing setup_directio_ctx() to
fail, which causes multipathd to skip io error checking and mark the
path as not marginal.

Instead, multipathd should just make sure that if the path is marginal,
it gets failed in the uevent, so as not to race with the checkerloop
thread. Then, when the path comes back up, check_path() can enqueue it,
just like it does for paths that need to get rechecked. To make it
obvious that the state PATH_IO_ERR_IN_POLLING_RECHECK and the function
hit_io_err_recheck_time() now apply to paths waiting to be enqueued for
the first time as well, I've also changed their names to
PATH_IO_ERR_WAITING_TO_CHECK and need_io_err_check(), respectively.

Reviewed-by: Martin Wilck <mwilck@suse.com>
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
libmultipath/io_err_stat.c
libmultipath/io_err_stat.h
multipathd/main.c