From db955ed925bce1f9a7c4d392028e169b3feccf96 Mon Sep 17 00:00:00 2001 From: Joseph Marrero Corchado Date: Wed, 22 Apr 2026 09:01:23 -0400 Subject: [PATCH 1/3] tests: Skip BLI detection test when not in image-mode The 052-test-bli-detection test asserts that Fedora 43+ systems boot without a root= kernel argument (using DPS auto-discovery instead). However, this only works when the install was performed via bootc install to-disk, which creates partitions with DPS type GUIDs. In Packit/gating CI, the system is installed via bootc install to-existing-root on a Testing Farm VM whose partitions were not created with DPS type GUIDs. The test was unconditionally failing in this environment. Fix this by checking for the BCVK_EXPORT environment variable, which is set by xtask when running tests via bcvk (image-mode). When not in image-mode, the test skips since DPS root discovery cannot work on partitions that lack the proper type GUIDs. Fixes: #2123 Assisted-by: OpenCode (Claude Opus 4.6) Signed-off-by: Joseph Marrero Corchado --- tmt/tests/booted/readonly/052-test-bli-detection.nu | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tmt/tests/booted/readonly/052-test-bli-detection.nu b/tmt/tests/booted/readonly/052-test-bli-detection.nu index 474456670..12d4878db 100644 --- a/tmt/tests/booted/readonly/052-test-bli-detection.nu +++ b/tmt/tests/booted/readonly/052-test-bli-detection.nu @@ -29,6 +29,16 @@ if not ($os_id == "fedora" and $version_id >= 43) { exit 0 } +# DPS root discovery only works when bootc install to-disk created the +# partitions with DPS type GUIDs. In Packit/gating CI the system was +# installed via to-existing-root on pre-existing partitions, so skip. +# BCVK_EXPORT=1 is set by xtask when running via bcvk (image-mode). +if ($env.BCVK_EXPORT? | default "" | is-empty) { + print "# skip: not running in image-mode (BCVK_EXPORT not set)" + tap ok + exit 0 +} + print $"Running on ($os_id) ($version_id), checking DPS root discovery" let cmdline = (open /proc/cmdline) From 9e5d01501e9be39d4dce84d745e85571864eddbc Mon Sep 17 00:00:00 2001 From: jbtrystram Date: Mon, 20 Apr 2026 14:05:39 +0200 Subject: [PATCH 2/3] install/ostree: Set zipl as the bootloader for s390x `zipl` cannot dynamically read BLS config at boot, and requires the MBR to be updated before. So we set `zipl` as the bootloader for s390x by default. Otherwise, s390x systems cannot reboot into new deployments. We set the ostree parameter after the initial ostree deployement because it fails if called during it. See https://github.com/coreos/coreos-assembler/blob/99bb23e7dfbfa8f1ae8b9bfaca9ff2e6d98c6cba/src/osbuild-manifests/build.common.ipp.yaml#L160-L163 Fixes https://github.com/bootc-dev/bootc/issues/2151 Signed-off-by: jbtrystram --- crates/lib/src/install.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/crates/lib/src/install.rs b/crates/lib/src/install.rs index 2a18c45c2..4b391afb9 100644 --- a/crates/lib/src/install.rs +++ b/crates/lib/src/install.rs @@ -2053,6 +2053,24 @@ async fn install_to_filesystem_impl( } } else { ostree_install(state, rootfs, cleanup).await?; + + // For s390x, we set zipl as the bootloader + // this needs to be done after the ostree commit is deployed, + // as we don't want zipl to run during the initial ostree deployement. + if cfg!(target_arch = "s390x") { + Command::new("ostree") + .args([ + "config", + "--repo", + "ostree/repo", + "set", + "sysroot.bootloader", + "zipl", + ]) + .cwd_dir(rootfs.physical_root.try_clone()?) + .run_capture_stderr() + .context("Setting bootloader config to zipl")?; + } } // As the very last step before filesystem finalization, do a full SELinux From a7176cdc2d401f486a542f1b95209e447d4cb9be Mon Sep 17 00:00:00 2001 From: John Eckersberg Date: Tue, 21 Apr 2026 09:45:50 -0400 Subject: [PATCH 3/3] install: Pass explicit filesystem type to mount after mkfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When mounting a freshly-created filesystem during install, pass -t to mount rather than relying on auto-detection. util-linux 2.42 introduced an optimization (commit 8bdc2546d) where libmount reads device properties from the udev database instead of probing the device superblock with libblkid. When mkfs runs inside a container, the udev database is stale for the filesystem type because mkfs does not generate a kernel uevent — udev only re-probes devices on kernel-generated events (such as partition table changes from sfdisk), not on arbitrary block device writes. As a result, the udev database has partition tags (PARTUUID, PARTLABEL) from sfdisk but lacks ID_FS_TYPE. libmount's read_from_udev() returns success after finding those partition tags, so the libblkid direct-probe fallback is never called. Without a filesystem type, mount falls back to iterating /etc/filesystems and /proc/filesystems, which fails for filesystem modules (like xfs with CONFIG_XFS_FS=m) that are not yet loaded. Since bootc already knows the filesystem type (it just ran mkfs), passing -t avoids the auto-detection path entirely. Closes: #2148 Assisted-by: OpenCode (claude-opus-4-6) Signed-off-by: John Eckersberg --- crates/lib/src/install/baseline.rs | 5 +++-- crates/mount/src/mount.rs | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/crates/lib/src/install/baseline.rs b/crates/lib/src/install/baseline.rs index 8a32e98c9..cfd8878e1 100644 --- a/crates/lib/src/install/baseline.rs +++ b/crates/lib/src/install/baseline.rs @@ -484,7 +484,8 @@ pub(crate) fn install_create_rootfs( } } - bootc_mount::mount(&rootdev_path, &physical_root_path)?; + let fstype = &root_filesystem.to_string(); + bootc_mount::mount_typed(&rootdev_path, fstype, &physical_root_path)?; let target_rootfs = Dir::open_ambient_dir(&physical_root_path, cap_std::ambient_authority())?; crate::lsm::ensure_dir_labeled(&target_rootfs, "", Some("/".into()), 0o755.into(), sepolicy)?; let physical_root = Dir::open_ambient_dir(&physical_root_path, cap_std::ambient_authority())?; @@ -492,7 +493,7 @@ pub(crate) fn install_create_rootfs( // Create the underlying mount point directory, which should be labeled crate::lsm::ensure_dir_labeled(&target_rootfs, "boot", None, 0o755.into(), sepolicy)?; if let Some(bootdev) = bootdev { - bootc_mount::mount(&bootdev.path(), &bootfs)?; + bootc_mount::mount_typed(&bootdev.path(), fstype, &bootfs)?; } // And we want to label the root mount of /boot crate::lsm::ensure_dir_labeled(&target_rootfs, "boot", None, 0o755.into(), sepolicy)?; diff --git a/crates/mount/src/mount.rs b/crates/mount/src/mount.rs index 67eba4a68..c5f7eee16 100644 --- a/crates/mount/src/mount.rs +++ b/crates/mount/src/mount.rs @@ -145,6 +145,19 @@ pub fn mount(dev: &str, target: &Utf8Path) -> Result<()> { .run_inherited_with_cmd_context() } +/// Mount a device with an explicit filesystem type. +/// +/// This avoids relying on the `mount` utility's blkid auto-detection, +/// which can fail in certain container environments (e.g. when the +/// required filesystem kernel module is not yet loaded and the blkid +/// probe doesn't work, causing mount to fall back to iterating +/// `/etc/filesystems` and `/proc/filesystems`). +pub fn mount_typed(dev: &str, fstype: &str, target: &Utf8Path) -> Result<()> { + Command::new("mount") + .args(["-t", fstype, dev, target.as_str()]) + .run_inherited_with_cmd_context() +} + /// If the fsid of the passed path matches the fsid of the same path rooted /// at /proc/1/root, it is assumed that these are indeed the same mounted /// filesystem between container and host.