File: boot-state

package info (click to toggle)
snapd 2.71-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 79,536 kB
  • sloc: ansic: 16,114; sh: 16,105; python: 9,941; makefile: 1,890; exp: 190; awk: 40; xml: 22
file content (201 lines) | stat: -rwxr-xr-x 5,075 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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#!/bin/bash

show_help() {
    echo "usage: boot-state bootenv show [var]"
    echo "       boot-state bootenv set <var> <value>"
    echo "       boot-state bootenv unset <var>"
    echo "       boot-state boot-path"
    echo "       boot-state wait-core-post-boot"
    echo ""
    echo "Get information and manages the boot loader for the current system"
    echo ""
    echo "COMMANDS:"
    echo "  bootenv show:         prints the whole bootenv or just the variable passed as parameter"
    echo "  bootenv set:          sets the given var and value on boot configuration"
    echo "  bootenv unset:        unsets the given var from boot configuration"
    echo "  boot-path:            prints the boot path"
    echo "  wait-core-post-boot:  waits until the snap_mode bootenv var is empty"
}

get_grub_editenv() {
    if [ -e /boot/grub2/grubenv ]; then
        command -v grub2-editenv
    elif [ -e /boot/grub/grubenv ]; then
        command -v grub-editenv
    fi
}

run_grub_editenv() {
    "$(get_grub_editenv)" "$@"
}

get_grub_envfile() {
    if [ -e /boot/grub2/grubenv ]; then
        echo /boot/grub2/grubenv
    elif [ -e /boot/grub/grubenv ]; then
        echo /boot/grub/grubenv
    else
        echo ""
    fi
}

bootenv() {
    # Core 18/20 not supported on ARM devices
    # TODO: try to support doing this kind of test not with fw_printenv/setenv and friends
    # but instead through snap debug boot-state ... much like we do with snap debug boot-vars
    case "${1:-}" in
        show)
            shift
            bootenv_show "$@"
            exit
            ;;
        set)
            shift
            bootenv_set "$@"
            exit
            ;;
        unset)
            shift
            bootenv_unset "$@"
            exit
            ;;
        *)
            echo "boot-state: unsupported bootenv sub-command $1" >&2
            show_help
            exit 1
            ;;
    esac
}

bootenv_show() {
    local var="${1:-}"
    local grubenv_file
    grubenv_file="$(get_grub_envfile)"

    if [ -z "$var" ]; then
        if run_grub_editenv list; then
            return
        elif [ -s "$grubenv_file" ]; then
            cat "$grubenv_file"
        else
            fw_printenv
        fi
    else
        # TODO: fix that, it could be problematic if var ends up with regular expression
        if run_grub_editenv list | grep "^$var"; then
            return
        elif [ -s "$grubenv_file" ]; then
            grep "^$var" "$grubenv_file"
        else
            fw_printenv "$1"
        fi | sed "s/^${var}=//"
    fi
}

bootenv_set() {
    local var="$1"
    local value="$2"

    if [ -z "$var" ] || [ -z "$value" ]; then
        echo "boot-state: variable and value required to set in bootenv" >&2
        show_help
        exit 1
    fi
    local grubenv_file
    grubenv_file="$(get_grub_envfile)"

    if run_grub_editenv set "$var=$value"; then
        return
    elif [ -s "$grubenv_file" ]; then
        sed --follow-symlinks -i "/^$var=/d" "$grubenv_file"
        #The grubenv file could not have a new line at the end
        if [ -n "$(tail -n 1 "$grubenv_file")" ]; then
            echo "" >> "$grubenv_file"
        fi
        echo "$var=$value" >> "$grubenv_file"
    else
        fw_setenv "$var" "$value"
    fi
}

bootenv_unset() {
    local var="$1"

    if [ -z "$var" ]; then
        echo "boot-state: variable required to unset from bootenv" >&2
        show_help
        exit 1
    fi
    local grubenv_file
    grubenv_file="$(get_grub_envfile)"

    if run_grub_editenv "$grubenv_file" unset "$var"; then
        return
    elif [ -s "$grubenv_file" ]; then
        sed --follow-symlinks -i "/^$var=/d" "$grubenv_file"
    else
        fw_setenv "$var"
    fi
}

boot_path() {
    if [ -f /boot/uboot/uboot.env ] || [ -f /boot/uboot/boot.sel ]; then
        # uc16/uc18 have /boot/uboot/uboot.env
        # uc20 has /boot/uboot/boot.sel
        echo "/boot/uboot/"
    elif [ -f /boot/grub/grubenv ]; then
        echo "/boot/grub/"
    elif [ -f /boot/grub2/grubenv ]; then
        echo "/boot/grub2/"
    elif [ -f /boot/piboot/piboot.conf ]; then
        echo "/boot/piboot/"
    else
        echo "boot-state: cannot determine boot path" >&2
        ls -alR /boot
        exit 1
    fi
}

wait_core_post_boot() {
    for _ in $(seq 120); do
        if [ "$(bootenv_show snap_mode)" = "" ]; then
            return
        fi
        sleep 1
    done
    echo "boot-state: timeout reached waiting for core after boot" >&2
    exit 1
}

main() {
    if [ $# -eq 0 ]; then
        show_help
        exit 0
    fi

    case "$1" in
        -h|--help)
            show_help
            exit
            ;;
        bootenv)
            shift
            bootenv "$@"
            ;;
        boot-path)
            boot_path
            exit
            ;;
        wait-core-post-boot)
            wait_core_post_boot
            exit
            ;;
        *)
            echo "boot-state: unsupported parameter $1" >&2
            show_help
            exit 1
            ;;
    esac
}

main "$@"