summaryrefslogtreecommitdiffstats
path: root/init_functions
blob: ebdb46896c44e4eafb05949a179a140d62bce340 (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
# This file contains common functions used in init and in hooks

msg () {
    [ "${quiet}" != "y" ] && echo $@
}
err () {
    echo "ERROR: $@"
}

poll_device() {
    device="$1"
    if [ "$2" -gt 0 ]; then
        seconds="$2"
    else
        seconds=5
    fi
    echo "Waiting ${seconds} seconds for device ${device} ..."
    while [ ! -b "${device}" -a ! -h "${device}" -a ${seconds} -gt 0 ]; do
        sleep 1
        seconds=$((${seconds}-1))
    done
    [ -b "${device}" -o -h "${device}" ]
}

launch_interactive_shell() {
    export PS1='[ramfs \W]\$ '
    [ "$1" = "--exec" ] && exec /bin/sh -i
    /bin/sh -i
}

default_mount_handler() {
    if [ ${root:0:5} != "/dev/" ] || ! poll_device "${root}" ${rootdelay}; then
        msg "\nRoot device '${root}' doesn't exist. Attempting to create it."
        rootdev=""
        if [ ${root:0:5} = "/dev/" ]; then
            # It might be a block device (/dev/sda) -> /sys/block/sda/dev
            # or a partition (/dev/sda1) -> /sys/block/sda/sda1/dev
            for dir in /sys/block /sys/block/*; do
                if [ -f ${dir}/${root:5}/dev ]; then
                    rootdev="$(cat ${dir}/${root:5}/dev | sed 's|:| |')"
                    break
                fi
            done
        # It might be a major/minor pair (8:1)
        elif echo ${root} | grep -q :; then
            rootdev="$(echo ${root} | sed 's|:| |')"
            root="/dev/root"
        # It might be major/minor encoded as a single hex-number (lilo-style) (801)
        elif [ ${#root} -le 4 -a ${#root} -gt 2 ] && echo "${root}" | grep -qe '^[A-Fa-f0-9]*$'; then
            str_offset=$((${#root}-2))
            major=$(printf "%d" 0x${root:0:${str_offset}})
            minor=$(printf "%d" 0x${root:${str_offset}})
            rootdev="${major} ${minor}"
            root="/dev/root"
        fi
        if [ -n "${rootdev}" ]; then
            msg "Creating root device ${root} with major $(echo "${rootdev}" | cut -d\   -f1) and minor $(echo "${rootdev}" | cut -d\   -f2)."
            mknod ${root} b ${rootdev}
        else
            err "Unable to determine major/minor number of root device '${root}'."
            echo "You are being dropped to a recovery shell"
            echo "    Type 'exit' to try and continue booting"
            launch_interactive_shell
            msg "Trying to continue (this will most likely fail) ..."
        fi
    fi
    # We didn't build filesystem support into busybox,
    # instead we use util-linux-ng's blkid for best compatibility
    if [ -n "${rootfstype}" ]; then
        fstype="${rootfstype}"
    else
        fstype=$(eval $(/sbin/blkid -o udev -p "${root}"); echo $ID_FS_TYPE)
        if [ -z "${fstype}" ]; then
            err "Unable to determine the file system type of ${root}:"
            echo "Either it contains no filesystem, an unknown filesystem,"
            echo "or more than one valid file system signature was found."
            echo
            echo "Try adding"
            echo "    rootfstype=your_filesystem_type"
            echo "to the kernel command line."
            echo
            echo "You are now being dropped into an emergency shell."
            launch_interactive_shell
            msg "Trying to continue (this will most likely fail) ..."
        fi
    fi
    if [ "${readwrite}" = "yes" ]; then
        rwopt="rw"
    else
        rwopt="ro"
    fi
    mount ${fstype:+-t ${fstype}} -o ${rwopt}${rootflags:+,${rootflags}} "${root}" "$1"
}