-
Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathmultipath.rules.in
101 lines (80 loc) · 4.41 KB
/
multipath.rules.in
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# Set DM_MULTIPATH_DEVICE_PATH if the device should be handled by multipath
SUBSYSTEM!="block", GOTO="end_mpath"
KERNEL!="sd*|dasd*|nvme*", GOTO="end_mpath"
ACTION=="remove", TEST=="@RUNTIME_DIR@/multipath/find_multipaths/$major:$minor", \
RUN+="/usr/bin/rm -f @RUNTIME_DIR@/multipath/find_multipaths/$major:$minor"
ACTION!="add|change", GOTO="end_mpath"
IMPORT{cmdline}="nompath"
ENV{nompath}=="?*", GOTO="end_mpath"
IMPORT{cmdline}="multipath"
ENV{multipath}=="off", GOTO="end_mpath"
ENV{DEVTYPE}!="partition", GOTO="test_dev"
IMPORT{parent}="DM_MULTIPATH_DEVICE_PATH"
ENV{DM_MULTIPATH_DEVICE_PATH}=="1", ENV{ID_FS_TYPE}="none", \
ENV{SYSTEMD_READY}="0"
GOTO="end_mpath"
LABEL="test_dev"
ENV{MPATH_SBIN_PATH}="/sbin"
TEST!="$env{MPATH_SBIN_PATH}/multipath", ENV{MPATH_SBIN_PATH}="/usr/sbin"
# FIND_MULTIPATHS_WAIT_UNTIL is the timeout (in seconds after the
# epoch).
IMPORT{db}="FIND_MULTIPATHS_WAIT_UNTIL"
ENV{.SAVED_FM_WAIT_UNTIL}="$env{FIND_MULTIPATHS_WAIT_UNTIL}"
# multipath -u needs to know if this device has ever been exported
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", \
ENV{.MPATH_CHECK_PASSED}="1"
# case 1: this is definitely multipath
ENV{DM_MULTIPATH_DEVICE_PATH}=="1", \
ENV{ID_FS_TYPE}="mpath_member", ENV{SYSTEMD_READY}="0", \
GOTO="stop_wait"
# case 2: this is definitely not multipath, or timeout has expired
ENV{DM_MULTIPATH_DEVICE_PATH}!="2", \
GOTO="stop_wait"
# Code below here is only run in "smart" mode.
# multipath -u has indicated this is "maybe" multipath.
# Note that DM_MULTIPATH_DEVICE_PATH has the value 2 at this point.
# This value will never propagate to other rules files, because
# it will be reset to 1 in the "pretend_multipath" section below.
# This shouldn't happen, just in case.
ENV{FIND_MULTIPATHS_WAIT_UNTIL}!="?*", GOTO="end_mpath"
# Be careful not to start the timer twice.
ACTION!="add", GOTO="pretend_mpath"
ENV{.SAVED_FM_WAIT_UNTIL}=="?*", GOTO="pretend_mpath"
# At this point, we are seeing this path for the first time, and it's "maybe" multipath.
# The actual start command for the timer.
#
# The purpose of this command is only to make sure we will receive another
# uevent eventually. *Any* uevent may cause waiting to finish if it either ends
# in case 1-3 above, or if it arrives after FIND_MULTIPATHS_WAIT_UNTIL.
#
# Note that this will try to activate multipathd if it isn't running yet.
# If that fails, the unit starts and expires nonetheless. If multipathd
# startup needs to wait for other services, this wait time will add up with
# the --on-active timeout.
#
# We must trigger an "add" event because LVM2 will only act on those.
RUN+="/usr/bin/systemd-run --unit=cancel-multipath-wait-$kernel --description 'cancel waiting for multipath siblings of $kernel' --no-block --timer-property DefaultDependencies=no --timer-property Conflicts=shutdown.target --timer-property Before=shutdown.target --timer-property Conflicts=initrd-cleanup.service --timer-property Before=initrd-cleanup.service --timer-property AccuracySec=500ms --property DefaultDependencies=no --property Conflicts=shutdown.target --property Before=shutdown.target --property Conflicts=initrd-cleanup.service --property Before=initrd-cleanup.service --on-active=$env{FIND_MULTIPATHS_WAIT_UNTIL} /usr/bin/udevadm trigger --action=add $sys$devpath"
LABEL="pretend_mpath"
ENV{DM_MULTIPATH_DEVICE_PATH}="1"
ENV{SYSTEMD_READY}="0"
GOTO="end_mpath"
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}=="?*", 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"