bootc install to-existing-root fails when the target's parent mount has MS_SHARED propagation
- 主要言語
- Rust
- スター
- 2.3k
- フォーク
- 230
- 平均マージ
- 3日 12時間
- マージ済み PR(30日)
- 38
説明
### 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.
コントリビューションガイド
調査の方向性
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.
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- linux, rust
- 領域
- operating-systems
- issue の種類
- バグ
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 活発さ
- 活発
- 明瞭さ
- 明確に書かれている
- 初心者へのやさしさ
- 72/100