bootc-dev / bootc-dev/bootc

bootc install to-existing-root fails when the target's parent mount has MS_SHARED propagation

Aperta
#2,455 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
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

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.