Skip to content

Commit 862bbdb

Browse files
author
MochiOS Team
committed
mochiboot: efivar boot counter + userspace integration
- mochiboot source now has MochiBootBootCount / MochiBootForceRecovery EFI variables for auto-recovery after 3 failed boots - mochiboot.conf: MOCHIBOOT_RECOVERY_ENTRY config option - installer.py writes MOCHIBOOT_RECOVERY_ENTRY to generated config - mochi-snapshot: reads/resets counter via efivarfs instead of file - mochi-snapshot: added force-recovery subcommand - Better help text
1 parent 50603ef commit 862bbdb

3 files changed

Lines changed: 71 additions & 25 deletions

File tree

‎installer.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,8 @@ def install_mochiboot(target, disk, root_uuid, lfn, ch, kernels=None):
409409
"TERM_MARGIN=2",
410410
"TERM_MARGIN_GRADIENT=0",
411411
"",
412+
"MOCHIBOOT_RECOVERY_ENTRY=MOCHIOS (recovery mode)",
413+
"",
412414
]
413415
for k in kernels:
414416
vmlinuz = f"/boot/vmlinuz-{k}"

‎pkgbuilds/mochiboot/mochiboot.conf‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ TERM_MARGIN_GRADIENT=0
2424
INTERFACE_HELP_HIDDEN=no
2525
INTERFACE_HELP_COLOUR=00aa00
2626

27+
# boot counter: auto-select this entry after 3 consecutive failed boots
28+
# (requires mochiboot with boot-counter support)
29+
MOCHIBOOT_RECOVERY_ENTRY=MOCHIOS (recovery mode)
30+
2731
:DEFAULT
2832
PROTOCOL=linux
2933
KERNEL_PATH=boot:///vmlinuz-linux

‎pkgbuilds/mochiboot/usr/bin/mochi-snapshot‎

Lines changed: 65 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -103,34 +103,63 @@ boot_snapshot() {
103103
BOOT_DIR="/boot/mochiboot"
104104
COUNTER_FILE="$BOOT_DIR/boot_counter"
105105

106+
# EFI variable path (mochiboot GUID: 6d6f6368-6962-6f6f-7400-000000000000)
107+
MOCHIBOOT_GUID="6d6f6368-6962-6f6f-7400-000000000000"
108+
EFIVARFS="/sys/firmware/efi/efivars"
109+
BOOT_COUNT_VAR="MochiBootBootCount-$MOCHIBOOT_GUID"
110+
FORCE_RECOVERY_VAR="MochiBootForceRecovery-$MOCHIBOOT_GUID"
111+
112+
# EFI variable attributes (BS|RT = 0x07)
113+
ATTRS="\x07\x00\x00\x00"
114+
115+
reset_efi_counter() {
116+
local efivar="$EFIVARFS/$BOOT_COUNT_VAR"
117+
if [ -f "$efivar" ]; then
118+
# attributes (4 bytes LE) + counter value (4 bytes LE) = 8 bytes
119+
printf '%b\x00\x00\x00\x00' "$ATTRS" > "$efivar"
120+
echo " boot counter reset (efivar)"
121+
fi
122+
}
123+
124+
set_force_recovery() {
125+
local efivar="$EFIVARFS/$FORCE_RECOVERY_VAR"
126+
printf '%b\x01\x00\x00\x00' "$ATTRS" > "$efivar"
127+
echo " force recovery on next boot (efivar)"
128+
}
129+
130+
get_efi_counter() {
131+
if [ -f "$EFIVARFS/$BOOT_COUNT_VAR" ]; then
132+
local data
133+
data=$(cat "$EFIVARFS/$BOOT_COUNT_VAR" 2>/dev/null) || return 1
134+
# skip first 4 bytes (attrs), read 4 bytes LE
135+
printf '%d' "'${data:4:1}" 2>/dev/null
136+
fi
137+
}
138+
106139
mark_good() {
107140
rm -f "$COUNTER_FILE"
108141
rm -f "$BOOT_DIR/next_snapshot"
142+
if [ -d "$EFIVARFS" ]; then
143+
reset_efi_counter
144+
fi
109145
echo " boot marked successful"
110146
}
111147

112148
check_counter() {
113149
local max="${1:-3}"
114-
if [ -f "$COUNTER_FILE" ]; then
115-
local count=$(cat "$COUNTER_FILE" 2>/dev/null || echo 0)
116-
if [ "$count" -ge "$max" ]; then
117-
echo "recovery"
118-
return 0
119-
fi
120-
fi
121-
echo "ok"
122-
return 0
123-
}
124-
125-
increment_counter() {
126150
local count=0
127-
if [ -f "$COUNTER_FILE" ]; then
151+
# check efivar first, fall back to file
152+
if [ -f "$EFIVARFS/$BOOT_COUNT_VAR" ]; then
153+
count=$(get_efi_counter) || count=0
154+
elif [ -f "$COUNTER_FILE" ]; then
128155
count=$(cat "$COUNTER_FILE" 2>/dev/null || echo 0)
129156
fi
130-
count=$((count + 1))
131-
mkdir -p "$BOOT_DIR"
132-
echo "$count" > "$COUNTER_FILE"
133-
echo " boot count: $count"
157+
if [ "$count" -ge "$max" ]; then
158+
echo "recovery"
159+
return 0
160+
fi
161+
echo "ok"
162+
return 0
134163
}
135164

136165
cmd="${1:-list}"
@@ -153,17 +182,28 @@ case "$cmd" in
153182
check_counter "$@"
154183
;;
155184
inc|increment)
156-
increment_counter
185+
if [ -d "$EFIVARFS" ]; then
186+
local count=$(get_efi_counter)
187+
count=$((count + 1))
188+
printf '%b%s' "$ATTRS" "$(printf '\\x%02x' "$count")\x00\x00\x00" > "$EFIVARFS/$BOOT_COUNT_VAR"
189+
echo " boot count: $count (efivar)"
190+
else
191+
increment_counter
192+
fi
193+
;;
194+
force-recovery|fr)
195+
set_force_recovery
157196
;;
158197
*)
159-
echo "usage: mochi-snapshot {list|select|boot|mark-good|check|inc}"
198+
echo "usage: mochi-snapshot {list|select|boot|mark-good|check|inc|force-recovery}"
160199
echo ""
161-
echo " list - list all btrfs snapshots"
162-
echo " select - interactively pick a snapshot"
163-
echo " boot <path> - set a snapshot to boot next"
164-
echo " mark-good - mark current boot as successful"
165-
echo " check [max] - check if boot count exceeds max"
166-
echo " inc - increment boot counter"
200+
echo " list - list all btrfs snapshots"
201+
echo " select - interactively pick a snapshot"
202+
echo " boot <path> - set a snapshot to boot next"
203+
echo " mark-good - mark current boot as successful"
204+
echo " check [max] - check if boot count exceeds max"
205+
echo " inc - increment boot counter"
206+
echo " force-recovery - force recovery entry on next boot"
167207
exit 1
168208
;;
169209
esac

0 commit comments

Comments
 (0)