bootc install to-existing-root fails when the target's parent mount has MS_SHARED propagation
- Lingua principale
- Rust
- Stelle
- 2.3k
- Fork
- 230
- Merge medio
- 3g 12h
- PR unite (30g)
- 38
Descrizione
### Summary
`bootc install to-existing-root` fails reproducibly with:
```
error: Installing to filesystem: Creating imgstorage: Initializing images: No such file or directory (os error 2)
```
on any host where `/` (or `/run`) has `MS_SHARED` mount propagation, which is systemd's default on most modern Linux distributions. `mount --make-private / /run` before running the install works around it completely.
### Environment
- bootc 1.16.10 and 1.16.12 (both affected)
- Fedora 44 Cloud Base, reproduced identically on x86_64 (KVM) and aarch64 (TCG)
### Repro
1. Fresh Fedora 44 install.
2. `dnf install -y bootc skopeo`
3. `touch /etc/ostree/prepare-root.conf` (workaround for #1410, unrelated to this issue)
4. `bootc install to-existing-root --bootloader none --source-imgref docker:// --acknowledge-destructive`
5. Fails with the error above, before ever reaching the image pull.
### Root cause
`CStorage::create()` (`crates/lib/src/podstorage.rs`) spawns `podman --root /run/bootc/storage --runroot /proc/self/fd/N images` to initialize image storage. The fd is handed to the child via `bind_storage_roots()`'s `pre_exec` hook: `fchdir(storage_root)`, `unshare(CLONE_NEWNS)`, `mount_bind(".", STORAGE_ALIAS_DIR)`.
The comment above that code already names the exact failure mode:
> EINVAL A bind operation (MS_BIND) was requested where source referred to a mount namespace magic link, but the propagation type of the parent mount of target was MS_SHARED...
Checked `/proc/self/mountinfo` on a failing host:
```
71 1 0:34 /root / rw,relatime shared:1 - btrfs ...
49 71 0:28 / /run rw,nosuid,nodev shared:14 - tmpfs ...
```
Both `shared`. Running `mount --make-private /` and `mount --make-private /run` before `bootc install` makes the failure disappear. Confirmed with repeated clean installs afterward, on both bootc versions and both architectures.
Since `shared` is systemd's standard default, this doesn't look like an edge case specific to constrained or virtualized environments. It looks like it would affect most freshly-booted systems attempting `to-existing-root`.
### Suggested fix
`bind_storage_roots()` (or `CStorage::create()` before calling it) could make the target's parent mount private itself before the bind-mount, rather than relying on the caller's environment already being private. Happy to help test a patch.
Guida per i contributori
Apri la guida per i contributori
Direzione di ricerca
Start in crates/lib/src/podstorage.rs, reading CStorage::create() and bind_storage_roots(), especially the pre_exec sequence using fchdir, unshare, and mount_bind. Reproduce with bootc install to-existing-root on a host with shared / or /run, then compare with private mounts. Done means the install no longer fails during imgstorage initialization without requiring callers to change mount propagation.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- linux, rust
- Ambito
- operating-systems
- Tipo di issue
- Bug
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Stato di attività
- Attiva
- Chiarezza
- Specificata chiaramente
- Idoneità per principianti
- 72/100