Skip to content

waiting for device to exist #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

N3xp7im3
Copy link

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. Depending on which features are enabled we have to wait at different code paths.

@michaelolbrich
Copy link
Owner

The clippy error is also present in main. It changed with the latest rust version. That will need a separate fix.

@michaelolbrich
Copy link
Owner

Please rebase. That should fix the failed tests.

@N3xp7im3 N3xp7im3 force-pushed the wait-for-device branch 3 times, most recently from 994221e to 50f25cd Compare April 17, 2025 15:33
@N3xp7im3 N3xp7im3 requested a review from michaelolbrich April 25, 2025 09:08
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]>
@@ -49,6 +49,13 @@ pub fn mount_root(options: &CmdlineOptions) -> Result<()> {
return Err("root= not found in /proc/cmdline".into());
}

if options.rootfstype != Some("nfs".to_string()) &&
options.rootfstype != Some("9p".to_string())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cargo fmt complains about that. But maybe there is a better way to do this?
@hnez do you have any suggestions?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I've posted my reply as a separate comment - I must have clicked the wrong buttons)

Comment on lines +52 to +58
if options.rootfstype != Some("nfs".to_string()) &&
options.rootfstype != Some("9p".to_string())
{
let root_device = options.root.as_ref().ok_or("No root device argument")?;
wait_for_device(root_device)?;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if options.rootfstype != Some("nfs".to_string()) &&
options.rootfstype != Some("9p".to_string())
{
let root_device = options.root.as_ref().ok_or("No root device argument")?;
wait_for_device(root_device)?;
}
match options.rootfstype.as_deref() {
Some("nfs") | Some("9p") => (),
_ => wait_for_device(root)?,
}

This relies on a change I made above which I can not format as suggestion here. My local mount_root looks like this:

pub fn mount_root(options: &CmdlineOptions) -> Result<()> {
    let root = options
        .root
        .as_ref()
        .ok_or("root= not found in /proc/cmdline")?;

    match options.rootfstype.as_deref() {
        Some("nfs") | Some("9p") => (),
        _ => wait_for_device(root)?,
    }

    mkdir("/root")?;

    debug!(
        "Mounting rootfs {} -> /root as {} with flags = {:#x}, data = '{}'",
        root,
        options.rootfstype.as_deref().unwrap_or_default(),
        options.rootfsflags.bits(),
        options.rootflags.as_deref().unwrap_or_default()
    );
    do_mount(
        Some(root),
        "/root",
        options.rootfstype.as_deref(),
        options.rootfsflags,
        options.rootflags.as_deref(),
    )?;

    Ok(())
}

Comment on lines +56 to +69
fn wait_for_device(root_device: &str) -> Result<()> {
let mut counter = 0;
while !Path::new(&root_device).exists() {
let duration = time::Duration::from_millis(5);

if counter > 1000 {
return Err("timout reached while waiting for the device".into());
}

thread::sleep(duration);
counter += 1;
}
Ok(())
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main.rs already contains a few helper functions like this one, so adding this one there is consistent.
But I think they should be moved somewhere else in the future (utils.rs?) to de-clutter the main.rs (it is the entrypoint for newcomers to a project and should thus, in my opinion, be the easiest file to read).

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. We have #6 do move stuff into a separate file. But that PR tried to do too much stuff at once and has not been merged so far.

Comment on lines +56 to +69
fn wait_for_device(root_device: &str) -> Result<()> {
let mut counter = 0;
while !Path::new(&root_device).exists() {
let duration = time::Duration::from_millis(5);

if counter > 1000 {
return Err("timout reached while waiting for the device".into());
}

thread::sleep(duration);
counter += 1;
}
Ok(())
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fn wait_for_device(root_device: &str) -> Result<()> {
let mut counter = 0;
while !Path::new(&root_device).exists() {
let duration = time::Duration::from_millis(5);
if counter > 1000 {
return Err("timout reached while waiting for the device".into());
}
thread::sleep(duration);
counter += 1;
}
Ok(())
}
fn wait_for_device(root_device: &str) -> Result<()> {
let duration = time::Duration::from_millis(5);
let path = Path::new(&root_device);
for _ in 0..1000 {
if path.exists() {
return Ok(());
}
thread::sleep(duration);
}
Err("timout reached while waiting for the device".into())
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants