Skip to content

Commit c70db30

Browse files
committed
fix: add missing locks for activate/deactivate/protect/unprotect
1 parent dc5cf53 commit c70db30

3 files changed

Lines changed: 28 additions & 5 deletions

File tree

‎bin/atomic-gc‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ case "$COMMAND" in
134134
activate)
135135
[[ ${#ARGS[@]} -eq 0 ]] && { echo "ERROR: Specify generation to activate" >&2; exit 1; }
136136
gen_id="${ARGS[0]}"
137+
acquire_lock
137138
# Validate gen_id format
138139
if [[ ! "$gen_id" =~ ^[0-9]{8}-[0-9]{6}(-.+)?$ ]]; then
139140
echo "ERROR: Invalid generation ID format: ${gen_id}" >&2
@@ -144,18 +145,23 @@ case "$COMMAND" in
144145
echo "Generation ${gen_id} is already active"
145146
exit 0
146147
fi
147-
# Check if UKI exists
148-
if [[ ! -f "${ESP}/EFI/Linux/arch-${gen_id}.efi" ]]; then
148+
# Check if UKI exists (regular or active)
149+
if [[ ! -f "${ESP}/EFI/Linux/arch-${gen_id}.efi" ]] && \
150+
[[ ! -f "${ESP}/EFI/Linux/0-active-arch-${gen_id}.efi" ]] && \
151+
[[ ! -d "${BTRFS_MOUNT}/root-${gen_id}" ]]; then
149152
echo "ERROR: Generation not found: ${gen_id}" >&2
150153
exit 1
151154
fi
152155
# Rename to add active prefix
153-
mv "${ESP}/EFI/Linux/arch-${gen_id}.efi" "${ESP}/EFI/Linux/0-active-arch-${gen_id}.efi"
156+
if [[ -f "${ESP}/EFI/Linux/arch-${gen_id}.efi" ]]; then
157+
mv "${ESP}/EFI/Linux/arch-${gen_id}.efi" "${ESP}/EFI/Linux/0-active-arch-${gen_id}.efi"
158+
fi
154159
echo "Activated: ${gen_id} (will boot first)"
155160
;;
156161
deactivate)
157162
[[ ${#ARGS[@]} -eq 0 ]] && { echo "ERROR: Specify generation to deactivate" >&2; exit 1; }
158163
gen_id="${ARGS[0]}"
164+
acquire_lock
159165
# Validate gen_id format
160166
if [[ ! "$gen_id" =~ ^[0-9]{8}-[0-9]{6}(-.+)?$ ]]; then
161167
echo "ERROR: Invalid generation ID format: ${gen_id}" >&2
@@ -173,6 +179,7 @@ case "$COMMAND" in
173179
protect)
174180
[[ ${#ARGS[@]} -eq 0 ]] && { echo "ERROR: Specify generation to protect" >&2; exit 1; }
175181
gen_id="${ARGS[0]}"
182+
acquire_lock
176183
# Validate gen_id format
177184
if [[ ! "$gen_id" =~ ^[0-9]{8}-[0-9]{6}(-.+)?$ ]]; then
178185
echo "ERROR: Invalid generation ID format: ${gen_id}" >&2
@@ -185,7 +192,8 @@ case "$COMMAND" in
185192
fi
186193
# Check if UKI exists (could be active or regular)
187194
if [[ -f "${ESP}/EFI/Linux/arch-${gen_id}.efi" ]] || \
188-
[[ -f "${ESP}/EFI/Linux/0-active-arch-${gen_id}.efi" ]]; then
195+
[[ -f "${ESP}/EFI/Linux/0-active-arch-${gen_id}.efi" ]] || \
196+
[[ -d "${BTRFS_MOUNT}/root-${gen_id}" ]]; then
189197
touch "${ESP}/EFI/Linux/arch-${gen_id}.efi.protected"
190198
echo "Protected: ${gen_id} (won't be garbage collected)"
191199
else
@@ -196,6 +204,7 @@ case "$COMMAND" in
196204
unprotect)
197205
[[ ${#ARGS[@]} -eq 0 ]] && { echo "ERROR: Specify generation to unprotect" >&2; exit 1; }
198206
gen_id="${ARGS[0]}"
207+
acquire_lock
199208
# Validate gen_id format
200209
if [[ ! "$gen_id" =~ ^[0-9]{8}-[0-9]{6}(-.+)?$ ]]; then
201210
echo "ERROR: Invalid generation ID format: ${gen_id}" >&2

‎completions/atomic-gc.bash‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ _atomic_gc() {
3131
else
3232
local -a gens=()
3333
local f name
34-
for f in "$esp"/EFI/Linux/"*arch-"*.efi; do
34+
for f in "$esp"/EFI/Linux/*arch-*.efi; do
3535
[[ -e "$f" ]] || continue
3636
name="${f##*/}"
3737
name="${name#0-active-}"

‎tests/test_atomic_gc.sh‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,20 @@ assert_contains "already protected message" "already protected" "$_out"
355355
_run_gc protect 20990101-000000
356356
assert_eq "protect non-existent → rc 1" "1" "$_rc"
357357

358+
# ── protect command: already-active generation ─────────────
359+
360+
touch "${_FAKE_ESP}/EFI/Linux/0-active-arch-20250604-100001.efi"
361+
rm -f "${_FAKE_ESP}/EFI/Linux/arch-20250604-100001.efi"
362+
rm -f "${_FAKE_ESP}/EFI/Linux/arch-20250604-100001.efi.protected"
363+
364+
_run_gc protect 20250604-100001
365+
assert_eq "protect already-active → rc 0" "0" "$_rc"
366+
assert_contains "protected message for active" "Protected" "$_out"
367+
assert_file_exists "protected sidecar created for active" "${_FAKE_ESP}/EFI/Linux/arch-20250604-100001.efi.protected"
368+
369+
rm -f "${_FAKE_ESP}/EFI/Linux/0-active-arch-20250604-100001.efi"
370+
rm -f "${_FAKE_ESP}/EFI/Linux/arch-20250604-100001.efi.protected"
371+
358372
# ── unprotect command ──────────────────────────────────────
359373

360374
section "unprotect command"

0 commit comments

Comments
 (0)