summaryrefslogtreecommitdiffstats
path: root/modules.d/95nbd/nbdroot.sh
blob: b1a80308a528d22b668e3ade7fb51cd7bd837025 (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
#!/bin/sh

type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh

PATH=/usr/sbin:/usr/bin:/sbin:/bin

# Huh? Empty $1?
[ -z "$1" ] && exit 1

# Huh? Empty $2?
[ -z "$2" ] && exit 1

# Huh? Empty $3?
[ -z "$3" ] && exit 1

# root is in the form root=nbd:srv:port[:fstype[:rootflags[:nbdopts]]]
# shellcheck disable=SC2034
netif="$1"
nroot="$2"
NEWROOT="$3"

# If it's not nbd we don't continue
[ "${nroot%%:*}" = "nbd" ] || return

nroot=${nroot#nbd:}
nbdserver=${nroot%%:*}
if [ "${nbdserver%"${nbdserver#?}"}" = "[" ]; then
    nbdserver=${nroot#[}
    nbdserver=${nbdserver%%]:*}
    nroot=${nroot#*]:}
else
    nroot=${nroot#*:}
fi
nbdport=${nroot%%:*}
nroot=${nroot#*:}
nbdfstype=${nroot%%:*}
nroot=${nroot#*:}
nbdflags=${nroot%%:*}
nbdopts=${nroot#*:}

if [ "$nbdopts" = "$nbdflags" ]; then
    unset nbdopts
fi
if [ "$nbdflags" = "$nbdfstype" ]; then
    unset nbdflags
fi
if [ "$nbdfstype" = "$nbdport" ]; then
    unset nbdfstype
fi
if [ -z "$nbdfstype" ]; then
    nbdfstype=auto
fi

# look through the NBD options and pull out the ones that need to
# go before the host etc. Append a ',' so we know we terminate the loop
nbdopts=${nbdopts},
while [ -n "$nbdopts" ]; do
    f=${nbdopts%%,*}
    nbdopts=${nbdopts#*,}
    if [ -z "$f" ]; then
        break
    fi
    if [ -z "${f%bs=*}" -o -z "${f%timeout=*}" ]; then
        preopts="$preopts $f"
        continue
    fi
    opts="$opts $f"
done

# look through the flags and see if any are overridden by the command line
nbdflags=${nbdflags},
while [ -n "$nbdflags" ]; do
    f=${nbdflags%%,*}
    nbdflags=${nbdflags#*,}
    if [ -z "$f" ]; then
        break
    fi
    if [ "$f" = "ro" -o "$f" = "rw" ]; then
        nbdrw=$f
        continue
    fi
    fsopts=${fsopts:+$fsopts,}$f
done

getarg ro && nbdrw=ro
getarg rw && nbdrw=rw
fsopts=${fsopts:+$fsopts,}${nbdrw}

# XXX better way to wait for the device to be made?
i=0
while [ ! -b /dev/nbd0 ]; do
    [ $i -ge 20 ] && exit 1
    udevadm settle --exit-if-exists=/dev/nbd0
    i=$((i + 1))
done

# If we didn't get a root= on the command line, then we need to
# add the udev rules for mounting the nbd0 device
if [ "$root" = "block:/dev/root" -o "$root" = "dhcp" ]; then
    printf 'KERNEL=="nbd0", ENV{DEVTYPE}!="partition", ENV{ID_FS_TYPE}=="?*", SYMLINK+="root"\n' > /etc/udev/rules.d/99-nbd-root.rules
    udevadm control --reload
    wait_for_dev -n /dev/root

    if [ -z "$DRACUT_SYSTEMD" ]; then
        type write_fs_tab > /dev/null 2>&1 || . /lib/fs-lib.sh

        write_fs_tab /dev/root "$nbdfstype" "$fsopts"

        printf '/bin/mount %s\n' \
            "$NEWROOT" \
            > "$hookdir"/mount/01-$$-nbd.sh
    else
        mkdir -p /run/systemd/system/sysroot.mount.d
        cat << EOF > /run/systemd/system/sysroot.mount.d/dhcp.conf
[Mount]
Where=/sysroot
What=/dev/root
Type=$nbdfstype
Options=$fsopts
EOF
        systemctl --no-block daemon-reload
    fi
    # if we're on systemd, use the nbd-generator script
    # to create the /sysroot mount.
fi

if ! [ "$nbdport" -gt 0 ] 2> /dev/null; then
    nbdport="-name $nbdport"
fi

if ! nbd-client -check /dev/nbd0 > /dev/null; then
    # shellcheck disable=SC2086
    nbd-client -p -systemd-mark "$nbdserver" $nbdport /dev/nbd0 $opts || exit 1
fi

need_shutdown
exit 0