Skip to content

Commit 0dbcf00

Browse files
Fabian Pfitznerhnez
authored andcommitted
waiting for device to exist
It might be possible that the storage device does not probe fast enough causing an error when trying to mount it. Thus, we should wait for it passively before proceeding with the code. Signed-off-by: Fabian Pfitzner <[email protected]> Co-authored-by: Leonard Göhrs <[email protected]>
1 parent b30d0df commit 0dbcf00

File tree

3 files changed

+28
-8
lines changed

3 files changed

+28
-8
lines changed

src/dmverity.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use nix::libc::dev_t;
1212
use nix::sys::stat::minor;
1313

1414
use crate::cmdline::CmdlineOptions;
15-
use crate::{read_file, Result};
15+
use crate::{read_file, wait_for_device, Result};
1616

1717
const DM_VERSION_MAJOR: u32 = 4;
1818

@@ -120,9 +120,7 @@ pub fn prepare_dmverity(options: &mut CmdlineOptions) -> Result<bool> {
120120
return Ok(false);
121121
}
122122
let root_device = options.root.as_ref().ok_or("No root device")?;
123-
if !Path::new(&root_device).exists() {
124-
return Ok(false);
125-
}
123+
wait_for_device(root_device)?;
126124

127125
let mut data_blocks = "";
128126
let mut data_sectors = "";

src/main.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use std::os::fd::{AsFd, AsRawFd, RawFd};
1212
use std::os::unix::ffi::OsStrExt;
1313
use std::panic::set_hook;
1414
use std::path::Path;
15+
use std::thread;
16+
use std::time;
1517

1618
use cmdline::{parse_cmdline, CmdlineOptions};
1719
#[cfg(feature = "dmverity")]
@@ -51,6 +53,21 @@ fn read_file(filename: &str) -> std::result::Result<String, String> {
5153
read_to_string(filename).map_err(|e| format!("Failed to read {filename}: {e}"))
5254
}
5355

56+
fn wait_for_device(root_device: &str) -> Result<()> {
57+
let duration = time::Duration::from_millis(5);
58+
let path = Path::new(&root_device);
59+
60+
for _ in 0..1000 {
61+
if path.exists() {
62+
return Ok(());
63+
}
64+
65+
thread::sleep(duration);
66+
}
67+
68+
Err("timout reached while waiting for the device".into())
69+
}
70+
5471
/*
5572
* Setup stdout/stderr. The kernel will create /dev/console in the
5673
* initramfs, so we can use that.

src/mount.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use log::debug;
77
use nix::mount::{mount, MsFlags};
88

99
use crate::cmdline::CmdlineOptions;
10-
use crate::{mkdir, Result};
10+
use crate::{mkdir, wait_for_device, Result};
1111

1212
pub fn do_mount(
1313
src: Option<&str>,
@@ -45,10 +45,15 @@ pub fn mount_apivfs(dst: &str, fstype: &str) -> Result<()> {
4545
}
4646

4747
pub fn mount_root(options: &CmdlineOptions) -> Result<()> {
48-
if options.root.is_none() {
49-
return Err("root= not found in /proc/cmdline".into());
48+
let root = options
49+
.root
50+
.as_ref()
51+
.ok_or("root= not found in /proc/cmdline")?;
52+
53+
match options.rootfstype.as_deref() {
54+
Some("nfs") | Some("9p") => (),
55+
_ => wait_for_device(root)?,
5056
}
51-
5257
mkdir("/root")?;
5358

5459
debug!(

0 commit comments

Comments
 (0)