multipath: fix rcu thread cancellation hang
authorBenjamin Marzinski <bmarzins@redhat.com>
Fri, 23 Mar 2018 20:00:46 +0000 (15:00 -0500)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Tue, 27 Mar 2018 20:47:24 +0000 (22:47 +0200)
commitd3b71498f1e433782de3282164f20e037bb7a711
tree705ea9bc38631f1d46f2ffefff57c70e426b188c
parentf556433c4134d958eddf6b85b9833fbffa96dfa8
multipath: fix rcu thread cancellation hang

While the rcu code is waiting for a grace period to elapse, no threads
can register or unregister as rcu reader threads. If for some reason, a
thread never calls put_multipath_config() to exit a read side critical
section, then any threads trying to start or stop will hang. This can
happen if a thread is cancelled between calls to get_multipath_config()
and put_multipath_config(), and multipathd is reconfigured (which causes
the rcu code to wait for a grace period).

This patch fixes this issue in two ways. Where possible, it reorders the
code or saves config values into local variables to remove cancellation
points between calls to get_multipath_config() and
put_multipath_config().  In cases where this isn't possible (or where it
would cause a significant amount of extra work to be done) multipath now
pushes a cleanup handler to call put_multipath_config().

The only functions that were not modified were ones that were only
called by multipath or mpathpersist, since these are single threaded
and already disable rcu thread registration.

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
13 files changed:
libmultipath/config.h
libmultipath/configure.c
libmultipath/devmapper.c
libmultipath/discovery.c
libmultipath/parser.c
libmultipath/structs_vec.c
libmultipath/uevent.c
libmultipath/wwids.c
mpathpersist/main.c
multipath/main.c
multipathd/cli_handlers.c
multipathd/main.c
tests/globals.c