bootc install to-existing-root fails when the target's parent mount has MS_SHARED propagation
- Lenguaje dominante
- Rust
- Estrellas
- 2.3k
- Forks
- 230
- Merge medio
- 3 d 12 h
- PR fusionados (30 d)
- 38
Descripción
### 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.
Guía de contribución
Línea de trabajo
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.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- linux, rust
- Área
- operating-systems
- Tipo de issue
- Error
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Estado de actividad
- Activo
- Claridad
- Bien especificado
- Aptitud para principiantes
- 72/100