From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 7 Feb 2023 15:39:26 -0600 Subject: [PATCH] multipath.rules: fix "smart" bug with failed valid path check If "multipath -u" fails, udev doesn't import any values from the program. This means that multipath.rules will continue to use the values for DM_MULTIPATH_DEVICE_PATH and FIND_MULTIPATHS_WAIT_UNTIL that it has already imported from the database. This is the correct thing to do for every case except the MAYBE case for "find_multipaths smart". In that case, DM_MULTIPATH_DEVICE_PATH will be set to 1, and the rules will assume that the device has been definitively claimed. In this case, we know that the device shouldn't have been claimed before, but we don't know if it should be claimed now, or if we have hit the timeout and it should be released, since we didn't get any information from multipath. The safest thing to do is assume that this was the timeout, and the device shouldn't be claimed. The only time when this could be the wrong answer is when we first see a new multipath device, and it could only cause problems if there is metadata on the device that will cause it to get autoassembled by something else, before multipathd can autoassemble it. If we assume that it is a multipath device, or we assume that this wasn't actually the timeout uevent, we can keep a necessary device from getting released to the reset of the system. Signed-off-by: Benjamin Marzinski --- multipath/multipath.rules.in | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/multipath/multipath.rules.in b/multipath/multipath.rules.in index 5c4447a2..70b69a06 100644 --- a/multipath/multipath.rules.in +++ b/multipath/multipath.rules.in @@ -32,7 +32,8 @@ IMPORT{db}="DM_MULTIPATH_DEVICE_PATH" # multipath -u sets DM_MULTIPATH_DEVICE_PATH and, # if "find_multipaths smart", also FIND_MULTIPATHS_WAIT_UNTIL. -IMPORT{program}="$env{MPATH_SBIN_PATH}/multipath -u %k" +IMPORT{program}=="$env{MPATH_SBIN_PATH}/multipath -u %k", \ + ENV{.MPATH_CHECK_PASSED}="1" # case 1: this is definitely multipath ENV{DM_MULTIPATH_DEVICE_PATH}=="1", \ @@ -83,10 +84,19 @@ LABEL="stop_wait" # If timeout hasn't expired but we're not in "maybe" state any more, stop timer # Do this only once, and only if the timer has been started before IMPORT{db}="FIND_MULTIPATHS_WAIT_CANCELLED" -ENV{FIND_MULTIPATHS_WAIT_CANCELLED}!="?*", \ - ENV{FIND_MULTIPATHS_WAIT_UNTIL}=="?*", \ - ENV{FIND_MULTIPATHS_WAIT_UNTIL}!="0", \ - ENV{FIND_MULTIPATHS_WAIT_CANCELLED}="1", \ - RUN+="/usr/bin/systemctl stop cancel-multipath-wait-$kernel.timer" +ENV{FIND_MULTIPATHS_WAIT_CANCELLED}=="?*", GOTO="end_mpath" +ENV{FIND_MULTIPATHS_WAIT_UNTIL}!="?*", GOTO="end_mpath" +ENV{FIND_MULTIPATHS_WAIT_UNTIL}=="0", GOTO="end_mpath" + +ENV{FIND_MULTIPATHS_WAIT_CANCELLED}="1" +RUN+="/usr/bin/systemctl stop cancel-multipath-wait-$kernel.timer" + +# If "multipath -u" failed, no values are imported from the program, +# and we are still using the values for DM_MULTIPATH_DEVICE_PATH and +# FIND_MULTIPATHS_WAIT_UNTIL that were imported from the database. +# If we are in "smart" mode, we need to give up on the path now, +# since this may have been the timeout event. Without the imports +# from "multipath -u", we can't tell. +ENV{.MPATH_CHECK_PASSED}!="?*", ENV{DM_MULTIPATH_DEVICE_PATH}="0" LABEL="end_mpath"