Skip to content

Commit

Permalink
Ensure /dev is mounted before losetup is called
Browse files Browse the repository at this point in the history
Not a race condition, but more of a timing issue. Just needed to make
sure the /dev mount was happening before any of the losetup calls.

Fixes #352

Signed-off-by: Brad P. Crochet <brad@redhat.com>

rh-pre-commit.version: 2.2.0
rh-pre-commit.check-secrets: ENABLED
  • Loading branch information
bcrochet committed Mar 26, 2024
1 parent cc98447 commit bb5a9ac
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
16 changes: 16 additions & 0 deletions lib/src/blockdev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::process::Command;

/// The mount path and type for devtmpfs
#[cfg(feature = "install")]
const DEV_MOUNT_POINT: &str = "/dev";

#[derive(Debug, Deserialize)]
struct DevicesOutput {
blockdevices: Vec<Device>,
Expand Down Expand Up @@ -80,9 +84,21 @@ pub(crate) struct LoopbackDevice {
pub(crate) dev: Option<Utf8PathBuf>,
}

// Ensure that `/dev` directory exists and is mounted.
fn ensure_dev_mounted() -> Result<()> {
crate::mount::ensure_mount(
"none",
DEV_MOUNT_POINT.into(),
crate::mount::FilesystemType::DevTmpFs,
)?;
Ok(())
}

impl LoopbackDevice {
// Create a new loopback block device targeting the provided file path.
pub(crate) fn new(path: &Path) -> Result<Self> {
// Ensure /dev exists and is mounted
ensure_dev_mounted()?;
let dev = Task::new("losetup", "losetup")
.args(["--show", "--direct-io=on", "-P", "--find"])
.arg(path)
Expand Down
5 changes: 5 additions & 0 deletions lib/src/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,11 @@ async fn prepare_install(

ensure_var()?;
setup_tmp_mounts()?;
crate::mount::ensure_mount(
"none",
Utf8Path::new("/dev"),
crate::mount::FilesystemType::DevTmpFs,
)?;

// Even though we require running in a container, the mounts we create should be specific
// to this process, so let's enter a private mountns to avoid leaking them.
Expand Down
24 changes: 24 additions & 0 deletions lib/src/mount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use anyhow::{anyhow, Context, Result};
use camino::Utf8Path;
use fn_error_context::context;
use serde::Deserialize;
use std::fmt;

use crate::task::Task;

Expand All @@ -17,6 +18,19 @@ pub(crate) struct Filesystem {
pub(crate) uuid: Option<String>,
}

#[derive(Deserialize, Debug)]
pub(crate) enum FilesystemType {
DevTmpFs,
}

impl fmt::Display for FilesystemType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
FilesystemType::DevTmpFs => write!(f, "devtmpfs"),
}
}
}

#[derive(Deserialize, Debug)]
pub(crate) struct Findmnt {
pub(crate) filesystems: Vec<Filesystem>,
Expand Down Expand Up @@ -57,3 +71,13 @@ pub(crate) fn mount(dev: &str, target: &Utf8Path) -> Result<()> {
[dev, target.as_str()],
)
}

/// Create the target directory if it does not exist, then mount the specified filesystem
pub(crate) fn ensure_mount(dev: &str, target: &Utf8Path, fstype: FilesystemType) -> Result<()> {
std::fs::create_dir_all(target)?;
Task::new(format!("Mounting {fstype} {target}"), "mount")
.args(["-t", format!("{fstype}").as_str(), dev, target.as_str()])
.quiet()
.run()?;
Ok(())
}

0 comments on commit bb5a9ac

Please sign in to comment.