File: dracut-dev-lib.sh

package info (click to toggle)
dracut 110-7
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 4,880 kB
  • sloc: sh: 24,973; ansic: 5,236; makefile: 346; perl: 186; python: 48; javascript: 19
file content (152 lines) | stat: -rwxr-xr-x 4,470 bytes parent folder | download | duplicates (2)
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
#!/bin/sh

# replaces all occurrences of 'search' in 'str' with 'replacement'
#
# str_replace str search replacement
#
# example:
# str_replace '  one two  three  ' ' ' '_'
str_replace() {
    local in="$1"
    local s="$2"
    local r="$3"
    local out=''

    while [ "${in##*"$s"*}" != "$in" ]; do
        chop="${in%%"$s"*}"
        out="${out}${chop}$r"
        in="${in#*"$s"}"
    done
    printf -- '%s' "${out}${in}"
}

# get a systemd-compatible unit name from a path
# (mimics unit_name_from_path_instance())
dev_unit_name() {
    local dev="$1"

    if command -v systemd-escape > /dev/null; then
        case $dev in
            */*) systemd-escape -p -- "$dev" ;;
            *) systemd-escape -- "$dev" ;;
        esac
        return $?
    fi

    if [ "$dev" = "/" ] || [ -z "$dev" ]; then
        printf -- "-"
        return 0
    fi

    dev="${1%%/}"
    dev="${dev##/}"
    # shellcheck disable=SC1003
    dev="$(str_replace "$dev" '\' '\x5c')"
    dev="$(str_replace "$dev" '-' '\x2d')"
    if [ "${dev##.}" != "$dev" ]; then
        dev="\x2e${dev##.}"
    fi
    dev="$(str_replace "$dev" '/' '-')"

    printf -- "%s" "$dev"
}

# set_systemd_timeout_for_dev [-n] <dev> [<timeout>]
# Set 'rd.timeout' as the systemd timeout for <dev>
set_systemd_timeout_for_dev() {
    local _name
    local _needreload
    local _noreload
    local _timeout

    [ -z "${DRACUT_SYSTEMD-}" ] && return 0

    if [ "$1" = "-n" ]; then
        _noreload=1
        shift
    fi

    if [ -n "$2" ]; then
        _timeout="$2"
    else
        _timeout=$(getarg rd.timeout)
    fi

    _timeout=${_timeout:-infinity}

    _name=$(dev_unit_name "$1")

    if ! [ -f "${PREFIX-}/etc/systemd/system/${_name}.device.d/timeout.conf" ]; then
        mkdir -p "${PREFIX-}/etc/systemd/system/${_name}.device.d"
        {
            echo "[Unit]"
            echo "JobTimeoutSec=$_timeout"
            echo "JobRunningTimeoutSec=$_timeout"
        } > "${PREFIX-}/etc/systemd/system/${_name}.device.d/timeout.conf"
        type mark_hostonly > /dev/null 2>&1 && mark_hostonly /etc/systemd/system/"${_name}".device.d/timeout.conf
        _needreload=1
    fi

    if [ -z "${PREFIX-}" ] && [ "$_needreload" = 1 ] && [ -z "$_noreload" ]; then
        /sbin/initqueue --onetime --unique --name daemon-reload systemctl daemon-reload
    fi
}

# wait_for_dev <dev> [<timeout>]
#
# Installs a initqueue-finished script,
# which will cause the main loop only to exit,
# if the device <dev> is recognized by the system.
wait_for_dev() {
    local _name
    local _needreload
    local _noreload
    local _unit

    if [ "$1" = "-n" ]; then
        _noreload=-n
        shift
    fi

    _name="$(str_replace "$1" '/' '\x2f')"

    type mark_hostonly > /dev/null 2>&1 && mark_hostonly "$hookdir/initqueue/finished/devexists-${_name}.sh"

    [ -e "${PREFIX-}$hookdir/initqueue/finished/devexists-${_name}.sh" ] && return 0

    printf '[ -e "%s" ]\n' "$1" \
        >> "${PREFIX-}$hookdir/initqueue/finished/devexists-${_name}.sh"
    {
        printf '[ -e "%s" ] || ' "$1"
        printf 'warn "\"%s\" does not exist"\n' "$1"
    } >> "${PREFIX-}$hookdir/emergency/80-${_name}.sh"

    [ -n "${DRACUT_SYSTEMD-}" ] || return 0
    _unit="$(dev_unit_name "$1").device"

    if ! [ -L "${PREFIX-}/etc/systemd/system/initrd.target.wants/${_unit}" ]; then
        [ -d "${PREFIX-}"/etc/systemd/system/initrd.target.wants ] || mkdir -p "${PREFIX-}"/etc/systemd/system/initrd.target.wants
        ln -s ../"${_unit}" "${PREFIX-}/etc/systemd/system/initrd.target.wants/${_unit}"
        type mark_hostonly > /dev/null 2>&1 && mark_hostonly /etc/systemd/system/initrd.target.wants/"${_unit}"
        _needreload=1
    fi

    if [ -z "${PREFIX-}" ] && [ "$_needreload" = 1 ] && [ -z "$_noreload" ]; then
        /sbin/initqueue --onetime --unique --name daemon-reload systemctl daemon-reload
    fi

    set_systemd_timeout_for_dev $_noreload "$@"
}

cancel_wait_for_dev() {
    local _name
    _name="$(str_replace "$1" '/' '\x2f')"
    rm -f -- "$hookdir/initqueue/finished/devexists-${_name}.sh"
    rm -f -- "$hookdir/emergency/80-${_name}.sh"
    if [ -n "${DRACUT_SYSTEMD-}" ]; then
        _name=$(dev_unit_name "$1")
        rm -f -- "${PREFIX-}/etc/systemd/system/initrd.target.wants/${_name}.device"
        rm -f -- "${PREFIX-}/etc/systemd/system/${_name}.device.d/timeout.conf"
        /sbin/initqueue --onetime --unique --name daemon-reload systemctl daemon-reload
    fi
}