Skip to content

Handle active swap partitions when opening an existing disk - #4745

Open
VykosMolt wants to merge 2 commits into
archlinux:masterfrom
VykosMolt:fix/legacy-swap-4235
Open

Handle active swap partitions when opening an existing disk#4745
VykosMolt wants to merge 2 commits into
archlinux:masterfrom
VykosMolt:fix/legacy-swap-4235

Conversation

@VykosMolt

Copy link
Copy Markdown

Fixes #4235

Install once with a normal swap partition, then open the installer again on
that disk. Swap shows up in the partition list as if it were mounted at a
folder called [SWAP], and tearing the layout down fails.

Both come from the same place. When a partition is in use as swap, lsblk
prints [SWAP] where it would normally print a mountpoint, in both
mountpoint and mountpoints. LsblkInfo turned that into Path('[SWAP]'),
so as far as the rest of the code was concerned the partition was mounted at a
folder of that name. umount() then saw a non-empty list of mountpoints,
skipped the early return it has for unmounted partitions, and ran
umount -R '[SWAP]'.

Two changes.

LsblkInfo no longer treats [SWAP] as a path. It is matched exactly rather
than stripping anything in brackets, because [SWAP] is the only bracketed
value lsblk prints and a real folder is allowed brackets in its name. That
also keeps it out of the partition list, which I think matches what you meant
by "could simply be skipped".

umount_all_existing() now sends swap partitions to a new swapoff() helper
next to swapon(), rather than trying to unmount them. Swap is not mounted at
a folder, so there is nothing to unmount; it has to be switched off or the
partition stays busy and the disk cannot be repartitioned.

swapoff itself errors if you point it at something that is not currently in
use as swap, so the helper asks swapon --show what is in use before doing
anything. That makes it safe to call on a partition whose swap is already off,
which matters because the installer cannot tell the two apart. Both paths are
resolved before comparing, since swap can be switched on through a link like
/dev/disk/by-uuid/... while swapon reports the device it points at.

I took that list from swapon rather than from lsblk on purpose. A swap area is
not always a block device, and get_lsblk_info() raises on a swap file:

get_lsblk_info(/swapfile)  -> DiskError: Failed to read disk "/swapfile" with lsblk
get_lsblk_info(/dev/zram0) -> ok

Going through swapon means the helper works for partitions, encrypted and LVM
devices, and swap files alike, so it should be reusable for the teardown work
in #4536 and for the swap file in #4729 without either needing its own copy.
Real failures raise DiskError, matching swapon(), so nothing is swallowed.

Nine tests cover both fields carrying [SWAP], swap that is not currently on,
ordinary mountpoints, a real mountpoint with brackets in it, the symlink case,
and both failure paths. Seven of them fail on master.

One known gap: LUKS-encrypted swap still will not tear down, because
cryptsetup close finds the mapper busy. That is broken on master today too
and it needs a LUKS setup to test properly, so I have left it rather than
guess at it.

One limitation worth stating: swapon --show --raw prints names unquoted, so a
swap path containing whitespace would be ambiguous. Nothing archinstall creates
looks like that, but it is a real bound rather than a non-issue.

Claude Opus was used for codebase archaeology, implementation assistance, and
test review. I reviewed and tested the changes myself.

lsblk reports an active swap area by printing `[SWAP]` where a mountpoint
would go, in both `mountpoint` and `mountpoints`. `LsblkInfo` parsed that
straight into `Path('[SWAP]')`, so a swap partition looked like it was
mounted at a folder of that name. That is why `[SWAP]` shows up as a
mountpoint in the partition list, and it is what later gets handed to
`umount`.

`[SWAP]` is the only bracketed value lsblk emits, so match it exactly rather
than stripping anything bracketed: a real mountpoint may legitimately contain
brackets.
`umount_all_existing()` ran `umount` against every partition that was not
LUKS, including swap. Swap is not mounted at a folder, so the call failed and
the partition stayed busy, which is what breaks opening the installer a second
time on a disk with a legacy swap partition.

Route swap partitions to a new `swapoff()` helper alongside `swapon()`.
swapoff fails if it is pointed at something that is not currently in use as
swap, so the helper asks `swapon --show` first and does nothing if the path is
not there. Both sides are resolved because swap can be switched on through a
link such as /dev/disk/by-uuid/... A real failure raises `DiskError`, matching
`swapon()`.

Taking that list from swapon rather than from lsblk keeps the helper usable
for anything that can be swap, including encrypted and LVM devices and swap
files. lsblk cannot describe a swap file at all.
@VykosMolt
VykosMolt requested a review from Torxed as a code owner August 31, 2026 15:57
@svartkanin

Copy link
Copy Markdown
Collaborator

This seems to be a purely AI generated PR, we don't have a AI policy (yet) so I'll leave these comments for it

  • Please write a human description
  • Please remove AI comments as they rarely add any value and just add verbosity
  • Please test the code and review it yourself before submitting

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Handle legacy swap parts

2 participants