Skip to content

Commit ce67246

Browse files
rootmap: use full path for 'root=' karg when rootfs is directly on multipath
Issue: coreos/fedora-coreos-tracker#1980 This was first observed on s390x builders under high system load, where `ext.config.multipath.resilient` would intermittently fail during subsequent boot: ``` [ 2.781559] multipathd[321]: sdd [8:48]: path added to devmap 0xcadf6fadb3ee446d [ 2.853163] multipathd[321]: sdb [8:16]: path added to devmap 0x000000000000000b [ 3.012431] systemd[1]: Reached target coreos-multipath-wait.target - CoreOS Wait For Multipathed Boot. [ 3.139605] systemd[1]: Mounting sysroot.mount - /sysroot... [ 3.450666] mount[806]: mount: /sysroot: fsconfig system call failed: /dev/sdd4: Can't open blockdev. ``` It looks like a race condition between multipathd taking ownership of the root device and systemd trying to mount /sysroot. This might happen because the udev database isn't ready in time. Signed-off-by: Nikita Dubrovskii <nikita@linux.ibm.com>
1 parent ceb250d commit ce67246

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

docs/release-notes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Minor changes:
1515
Internal changes:
1616

1717
- Add initial TMT tests and a new workflow to execute tests on PRs
18+
- rootmap: Inject `root=/dev/disk/by-uuid/dm-mpath-$UUID` when on multipath
1819

1920
Packaging changes:
2021

src/bin/rdcore/rootmap.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,20 @@ use crate::cmdline::*;
3030
/// composefs, the mount of / and /sysroot will be distinct.
3131
const PHYSICAL_ROOT_MOUNT: &str = "sysroot";
3232

33+
fn is_on_multipath(device: &str) -> Result<bool> {
34+
let on_mpath = find_parent_devices(device)?
35+
.into_iter()
36+
.map(|p| lsblk(Path::new(&p), false))
37+
.collect::<Result<Vec<_>>>()?
38+
.iter()
39+
.any(|info| {
40+
info.iter()
41+
.any(|m| m.get("TYPE").is_some_and(|t| t == "mpath"))
42+
});
43+
44+
Ok(on_mpath)
45+
}
46+
3347
pub fn rootmap(config: RootmapConfig) -> Result<()> {
3448
let root_mount_path = Path::new(&config.root_mount);
3549
// Get the mount point for the deployment root, which will have e.g. /etc which we might parse
@@ -51,13 +65,22 @@ pub fn rootmap(config: RootmapConfig) -> Result<()> {
5165
}
5266
}
5367

68+
// use full path when the rootfs is directly on multipath;
69+
// this prevents race condition between systemd's autogenerated sysroot.mount and multipathd/udev,
70+
// see also: https://github.com/coreos/fedora-coreos-tracker/issues/1980
71+
let root = if is_on_multipath(physical_mount.device())? {
72+
// https://github.com/coreos/fedora-coreos-config/blob/testing-devel/overlay.d/05core/usr/lib/udev/rules.d/90-coreos-device-mapper.rules#L25
73+
format!(
74+
"root=/dev/disk/by-uuid/dm-mpath-{}",
75+
physical_mount.get_filesystem_uuid()?
76+
)
77+
} else {
78+
format!("root=UUID={}", physical_mount.get_filesystem_uuid()?)
79+
};
5480
// we push the root kargs last, this has the nice property that the final order of kargs goes
5581
// from lowest level to highest; see also
5682
// https://github.com/coreos/fedora-coreos-tracker/issues/465
57-
kargs.push(format!(
58-
"root=UUID={}",
59-
physical_mount.get_filesystem_uuid()?
60-
));
83+
kargs.push(root);
6184

6285
// we need this because with root= it's systemd that takes care of mounting via
6386
// systemd-fstab-generator, and it defaults to read-only otherwise

0 commit comments

Comments
 (0)