summaryrefslogtreecommitdiffstats
path: root/modules.d/90multipath/module-setup.sh
blob: 0a1fd55806579f7193536d0e43b4ed315ee8d2cc (plain)
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/bin/bash

is_mpath() {
    local _dev=$1
    [ -e /sys/dev/block/"$_dev"/dm/uuid ] || return 1
    [[ $(cat /sys/dev/block/"$_dev"/dm/uuid) =~ mpath- ]] && return 0
    return 1
}

majmin_to_mpath_dev() {
    local _dev
    for i in /dev/mapper/*; do
        [[ $i == /dev/mapper/control ]] && continue
        _dev=$(get_maj_min "$i")
        if [ "$_dev" = "$1" ]; then
            echo "$i"
            return
        fi
    done
}

# called by dracut
check() {
    local _any_mpath_dev

    # if there's no multipath binary, no go.
    require_binaries multipath || return 1
    require_binaries kpartx || return 1

    for_each_host_dev_and_slaves is_mpath
    _any_mpath_dev=$?

    [[ $hostonly ]] || [[ $mount_needs ]] && {
        [[ $_any_mpath_dev == 0 ]] || return 255
    }

    if [[ $_any_mpath_dev != 0 ]] && [[ ! -f /etc/multipath.conf ]]; then
        return 255
    fi

    return 0
}

# called by dracut
depends() {
    echo rootfs-block
    echo dm
    return 0
}

# called by dracut
cmdline() {
    for m in scsi_dh_alua scsi_dh_emc scsi_dh_rdac dm_multipath; do
        if grep -m 1 -q "$m" /proc/modules; then
            printf 'rd.driver.pre=%s ' "$m"
        fi
    done
}

# called by dracut
installkernel() {
    local _arch=${DRACUT_ARCH:-$(uname -m)}
    local _funcs='scsi_register_device_handler|dm_dirty_log_type_register|dm_register_path_selector|dm_register_target'

    if [ "$_arch" = "s390" ] || [ "$_arch" = "s390x" ]; then
        _s390drivers="=drivers/s390/scsi"
    fi

    hostonly='' dracut_instmods -o -s "$_funcs" "=drivers/scsi" "=drivers/md" ${_s390drivers:+"$_s390drivers"}
}

mpathconf_installed() {
    command -v mpathconf &> /dev/null
}

# called by dracut
install() {
    local -A _allow
    local config_dir

    # shellcheck disable=SC2317  # called later by for_each_host_dev_and_slaves
    add_hostonly_mpath_conf() {
        if is_mpath "$1"; then
            local _dev

            _dev=$(majmin_to_mpath_dev "$1")
            [ -z "$_dev" ] && return
            _allow["$_dev"]="$_dev"
        fi
    }

    local k v
    while read -r k v; do
        if [[ $k == "config_dir" ]]; then
            v="${v#\"}"
            config_dir="${v%\"}"
            break
        fi
    done < <(multipath -t 2> /dev/null)
    [[ -d $config_dir ]] || config_dir=/etc/multipath/conf.d

    inst_multiple \
        pkill \
        kpartx \
        dmsetup \
        multipath \
        multipathd

    inst_multiple -o \
        mpath_wait \
        mpathconf \
        mpathpersist \
        xdrgetprio \
        xdrgetuid \
        /etc/xdrdevices.conf \
        /etc/multipath.conf \
        /etc/multipath/* \
        "$config_dir"/* \
        "$tmpfilesdir/multipath.conf"

    mpathconf_installed \
        && [[ $hostonly ]] && [[ $hostonly_mode == "strict" ]] && {
        for_each_host_dev_and_slaves_all add_hostonly_mpath_conf
        if ((${#_allow[@]} > 0)); then
            local -a _args
            local _dev
            for _dev in "${_allow[@]}"; do
                _args+=("--allow" "$_dev")
            done
            mpathconf "${_args[@]}" --outfile "${initdir}"/etc/multipath.conf
        fi
    }

    inst "$(command -v partx)" /sbin/partx

    inst_libdir_file "libmultipath*" "multipath/*"
    inst_libdir_file 'libgcc_s.so*'

    if [[ $hostonly_cmdline == "yes" ]]; then
        local _conf
        _conf=$(cmdline)
        [[ $_conf ]] && echo "$_conf" >> "${initdir}/etc/cmdline.d/90multipath.conf"
    fi

    if dracut_module_included "systemd"; then
        if mpathconf_installed; then
            inst_simple "${moddir}/multipathd-configure.service" "${systemdsystemunitdir}/multipathd-configure.service"
            $SYSTEMCTL -q --root "$initdir" enable multipathd-configure.service
        fi
        inst_simple "${moddir}/multipathd.service" "${systemdsystemunitdir}/multipathd.service"
        $SYSTEMCTL -q --root "$initdir" enable multipathd.service
    else
        inst_hook pre-trigger 02 "$moddir/multipathd.sh"
        inst_hook cleanup 02 "$moddir/multipathd-stop.sh"
    fi

    inst_hook cleanup 80 "$moddir/multipathd-needshutdown.sh"
    inst_hook shutdown 20 "$moddir/multipath-shutdown.sh"

    inst_rules 40-multipath.rules 56-multipath.rules \
        62-multipath.rules 65-multipath.rules \
        66-kpartx.rules 67-kpartx-compat.rules \
        11-dm-mpath.rules 11-dm-parts.rules
}