systemd: lock disks while running filesystem checks - #18653
systemd: lock disks while running filesystem checks#18653Pawel Winogrodzki (PawelWMS) wants to merge 4 commits into
Conversation
8f32f47 to
bc45e8f
Compare
Acquire the exclusive whole-disk lock in systemd-fsck before launching its child fsck process, and retain it until that process exits. This is a systemd-owned alternative to native e2fsprogs locking. The two implementations must not be combined because nested locks would deadlock. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bb0e6716-4886-4e95-9efe-71dcde8687d6
bc45e8f to
aee4066
Compare
| + "Path '%s' no longer refers to block device %u:%u.", | ||
| + whole_disk, major(devno), minor(devno)); | ||
| + | ||
| + r = lock_generic(fd, LOCK_BSD, LOCK_EX); |
There was a problem hiding this comment.
This code might introduce a dead lock. The default timeout for systemd-fsck@ service is infinity. This might cause the fsck service to wait this lock forever.
This would not be an issue in udev. It uses LOCK_NB for non-blocking lock acquiring.
|
This of course would be better if it was upstreamed first, as it may require changes based on upstream feedback. The added function is mostly identical to udev's Also as Ziwei Mao (@ZzzMao) pointed out, leaving the Otherwise, it looks fine to me. |
Keep the package spec focused on patch registration and document the mutual-exclusion requirement at the lock acquisition site. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bb0e6716-4886-4e95-9efe-71dcde8687d6
Keep downstream compatibility guidance in the patch description. Do not add it to the patched source. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bb0e6716-4886-4e95-9efe-71dcde8687d6
Wait up to 60 seconds for the exclusive whole-disk lock. If the wait times out, emit a warning and run the filesystem checker without the lock to preserve previous boot behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bb0e6716-4886-4e95-9efe-71dcde8687d6
| + if (lock_fd < 0) | ||
| + if (lock_fd == -ETIMEDOUT) { | ||
| + log_warning( | ||
| + "Timed out waiting 60 seconds for whole block device lock for '%s'; proceeding without lock.", |
There was a problem hiding this comment.
Use a constant for the timeout, so we don't repeat "60" in two places in the code and potentially have them go out of sync.
Alternative implementation
Important
This change is a systemd-owned alternative to native e2fsprogs whole-disk locking.
Do not ship both implementations.
systemd-fsckretains its exclusive lock while waiting for childfsck; native e2fsprogs locking would block while acquiring a second independently opened lock on the same disk and deadlock boot.What
systemd-fsck.fsckchecks the filesystem.systemdandsystemd-boot-signedreleases synchronized at 255-35.Why
The root filesystem check can update ext4 metadata while
systemd-udevdprobes the same disk. Ifudevobserves the primary superblock between its payload and checksum writes,libblkidcan temporarily reject the filesystem and remove its filesystem UUID link. The generated root mount then cannot resolve the device and boot stops in the initramfs.systemd-udevdalready takes a shared whole-disk lock while probing. Holding an exclusive lock across the filesystem check makesudevdefer and retry its event after filesystem metadata is consistent.How it works
All systemd-managed filesystem checks converge in
systemd-fsck. After resolving the exact block device and verifying that anfsckimplementation exists, the patch:LOCK_EXBSD lock.fsckwhile the parent retains the lock descriptor.Relationship to #18695
#18695 is a clean alternative based directly on
3.0-dev. It routesudevandsystemd-fsckthrough shared block-device lock mechanics. This PR keeps the smaller private-helper implementation. Do not merge both.Scope
This affects every filesystem check launched through
systemd-fsck, not only initrd root and/usrunits. Checks for partitions on the same physical disk now serialize on one whole-disk lock.Risk
systemd-fsckunit.fsck -llock may not previously have serialized them.Verification
836fa3cab7d3d44f36026c3734d9e6b71ae4ac5d(signed).patch --dry-run -p1without fuzz or offsets.systemdpackages successfully on x86_64 and aarch64.systemdpackage tests: 1,216 on x86_64 and 1,217 on aarch64, with zero failures.daselon both architectures; it fails outside this package's scope whilesystemdbuilds and tests pass.systemd-rpm-macros, at 255-35 in one RPM transaction on an Azure Linux 3 VM running kernel 6.6.143.1-1.azl3.dracutstep.systemd-fsckSHA-256:a6cb9409af4c464e51cc7dd0f31cf877080faf4e9243dc17fd1e276fd7167248.running, no units failed, andemergency.targetremained inactive.systemd-fsckwarned after 60.010 seconds, continued to the checker while contention remained, and completed successfully.