Skip to content

Commit 560711d

Browse files
committed
install: skip mountspec kargs when passed empty rootspec
Notably, we skip generating an fstab entry for boot, even if it's on a separate partition. this requires the image initramfs have some knowledge to find the rootfs and bootfs (labels or DPS). See #1441
1 parent f4b01ab commit 560711d

File tree

2 files changed

+50
-11
lines changed

2 files changed

+50
-11
lines changed

crates/lib/src/install.rs

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,13 @@ impl FromStr for MountSpec {
506506
let mut parts = s.split_ascii_whitespace().fuse();
507507
let source = parts.next().unwrap_or_default();
508508
if source.is_empty() {
509-
anyhow::bail!("Invalid empty mount specification");
509+
tracing::debug!("Empty mount specification");
510+
return Ok(Self {
511+
source: String::new(),
512+
target: String::new(),
513+
fstype: Self::AUTO.into(),
514+
options: None,
515+
});
510516
}
511517
let target = parts
512518
.next()
@@ -890,10 +896,13 @@ async fn install_container(
890896

891897
// Write the entry for /boot to /etc/fstab. TODO: Encourage OSes to use the karg?
892898
// Or better bind this with the grub data.
899+
// We omit it if the boot mountspec argument was empty
893900
if let Some(boot) = root_setup.boot.as_ref() {
894-
crate::lsm::atomic_replace_labeled(&root, "etc/fstab", 0o644.into(), sepolicy, |w| {
895-
writeln!(w, "{}", boot.to_fstab()).map_err(Into::into)
896-
})?;
901+
if !boot.source.is_empty() {
902+
crate::lsm::atomic_replace_labeled(&root, "etc/fstab", 0o644.into(), sepolicy, |w| {
903+
writeln!(w, "{}", boot.to_fstab()).map_err(Into::into)
904+
})?;
905+
}
897906
}
898907

899908
if let Some(contents) = state.root_ssh_authorized_keys.as_deref() {
@@ -1807,6 +1816,7 @@ pub(crate) async fn install_to_filesystem(
18071816

18081817
// We support overriding the mount specification for root (i.e. LABEL vs UUID versus
18091818
// raw paths).
1819+
// We also support an empty specification as a signal to omit any mountspec kargs.
18101820
let root_info = if let Some(s) = fsopts.root_mount_spec {
18111821
RootMountInfo {
18121822
mount_spec: s.to_string(),
@@ -1889,7 +1899,13 @@ pub(crate) async fn install_to_filesystem(
18891899

18901900
let rootarg = format!("root={}", root_info.mount_spec);
18911901
let mut boot = if let Some(spec) = fsopts.boot_mount_spec {
1892-
Some(MountSpec::new(&spec, "/boot"))
1902+
// An empty boot mount spec signals to ommit the mountspec kargs
1903+
// See https://github.com/bootc-dev/bootc/issues/1441
1904+
if spec.is_empty() {
1905+
None
1906+
} else {
1907+
Some(MountSpec::new(&spec, "/boot"))
1908+
}
18931909
} else {
18941910
boot_uuid
18951911
.as_deref()
@@ -1903,12 +1919,23 @@ pub(crate) async fn install_to_filesystem(
19031919
// By default, we inject a boot= karg because things like FIPS compliance currently
19041920
// require checking in the initramfs.
19051921
let bootarg = boot.as_ref().map(|boot| format!("boot={}", &boot.source));
1906-
let kargs = [rootarg]
1907-
.into_iter()
1908-
.chain(root_info.kargs)
1909-
.chain([RW_KARG.to_string()])
1910-
.chain(bootarg)
1911-
.collect::<Vec<_>>();
1922+
1923+
// If the root mount spec is empty, we omit the mounts kargs entirely.
1924+
// https://github.com/bootc-dev/bootc/issues/1441
1925+
let mut kargs = if root_info.mount_spec.is_empty() {
1926+
Vec::new()
1927+
} else {
1928+
[rootarg]
1929+
.into_iter()
1930+
.chain(root_info.kargs)
1931+
.collect::<Vec<_>>()
1932+
};
1933+
1934+
kargs.push(RW_KARG.to_string());
1935+
1936+
if let Some(bootarg) = bootarg {
1937+
kargs.push(bootarg);
1938+
}
19121939

19131940
let skip_finalize =
19141941
matches!(fsopts.replace, Some(ReplaceMode::Alongside)) || fsopts.skip_finalize;

docs/src/man/bootc-install-to-filesystem.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,25 @@ is currently expected to be empty by default.
3434

3535
If not provided, the UUID of the target filesystem will be used.
3636

37+
If the value is empty, i.e. passing `--root-mount-spec=`, the mount
38+
spec kernel argument will be ommited entirely.
39+
In this case the initramfs must have another way to find the rootfs,
40+
such as a partition label or follow the Discoverable Partition
41+
Specification.
42+
3743
**\--boot-mount-spec**=*BOOT_MOUNT_SPEC*
3844

3945
: Mount specification for the /boot filesystem.
4046

4147
This is optional. If \`/boot\` is detected as a mounted partition,
4248
then its UUID will be used.
4349

50+
If the value is empty, i.e. passing `--boot-mount-spec=`, the mount
51+
spec kernel argument will be ommited entirely.
52+
In this case the initramfs must have another way to find the boot
53+
parition, such as a partition label or follow the Discoverable
54+
Partition Specification.
55+
4456
**\--replace**=*REPLACE*
4557

4658
: Initialize the system in-place; at the moment, only one mode for

0 commit comments

Comments
 (0)