Skip to content

Commit

Permalink
Ensure that efivarfs is mounted in the container
Browse files Browse the repository at this point in the history
Especially on ARM, which utilizes UEFI for booting in most cases, it is
important that the /sys/firmware/efi/efivars be mounted and populated,
otherwise bootc will fail to complete a to-filesystem installation.

This patch attempts a mount as long as the hosts efivars directory has
an entry, signifying the system is at least capable of UEFI.

Note that it is sufficient to just attempt to mount efivars. If it's
already mounted elsewhere, it triggers the mount to be made at the /sys
location.

Fixes #291

Signed-off-by: Brad P. Crochet <brad@redhat.com>
  • Loading branch information
bcrochet committed Feb 12, 2024
1 parent d37f481 commit 408f16e
Showing 1 changed file with 41 additions and 0 deletions.
41 changes: 41 additions & 0 deletions lib/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use std::io::BufWriter;
use std::io::Write;
use std::os::fd::AsFd;
use std::os::unix::process::CommandExt;
use std::path::Path;
use std::process::Command;
use std::str::FromStr;
use std::sync::Arc;
Expand Down Expand Up @@ -859,6 +860,44 @@ pub(crate) fn setup_tmp_mounts() -> Result<()> {
Ok(())
}

/// By default, podman/docker etc. when passed `--privileged` mount `/sys` as read-only,
/// but non-recursively. We selectively grab sub-filesystems that we need.
#[context("Ensuring sys mounts")]
pub(crate) fn setup_sys_mounts() -> Result<()> {
tracing::debug!("Setting up sys mounts");

let root_efivars = "/sys/firmware/efi/efivars";
let efivars = format!("/proc/1/root/{root_efivars}");
// Does efivars even exist in the host? If not, we are
// not dealing with an EFI system
if !Path::new(efivars.as_str()).try_exists()? {
return Ok(());
}

// Now, let's find out if it's populated
if std::fs::read_dir(efivars)?.next().is_none() {
return Ok(());
}

// First of all, does the container already have the mount?
let path = Utf8Path::new(root_efivars);
if path.try_exists()? {
tracing::debug!("Check if efivarfs already mount");
let inspect = crate::mount::inspect_filesystem(path);
if inspect.is_ok() {
tracing::trace!("Already have efivarfs {root_efivars}");
return Ok(());
}
}

// This means the host has this mounted, so we should mount it too
Task::new_and_run(
"Mounting efivarfs /sys/firmware/efi/efivars",
"mount",
["-t", "efivarfs", "efivars", "/sys/firmware/efi/efivars"],
)
}

/// Verify that we can load the manifest of the target image
#[context("Verifying fetch")]
async fn verify_target_fetch(imgref: &ostree_container::OstreeImageReference) -> Result<()> {
Expand Down Expand Up @@ -954,6 +993,8 @@ async fn prepare_install(
super::cli::ensure_self_unshared_mount_namespace().await?;
}

setup_sys_mounts()?;

// Now, deal with SELinux state.
let (override_disable_selinux, setenforce_guard) =
reexecute_self_for_selinux_if_needed(&source, config_opts.disable_selinux)?;
Expand Down

0 comments on commit 408f16e

Please sign in to comment.