bootc-dev / bootc-dev/bootc

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

オープン
#2,455 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る
主要言語
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

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。