Skip to content

Commit

Permalink
Wait for ueventd to create loop device on Android
Browse files Browse the repository at this point in the history
  • Loading branch information
tiann committed Feb 12, 2023
1 parent 64a8ddb commit 4baedb0
Showing 1 changed file with 23 additions and 1 deletion.
24 changes: 23 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,10 @@ impl LoopControl {
LOOP_CTL_GET_FREE as IoctlRequest,
)
})?;
LoopDevice::open(&format!("{}{}", LOOP_PREFIX, dev_num))
let dev = format!("{}{}", LOOP_PREFIX, dev_num);
#[cfg(target_os = "android")]
wait_for_device(&dev);
LoopDevice::open(&dev)
}

/// Add and opens a new loop device.
Expand Down Expand Up @@ -512,3 +515,22 @@ fn ioctl_to_error(ret: i32) -> io::Result<i32> {
Ok(ret)
}
}

// Android doesn't use devtmpfs. Instead device nodes under /dev are
// created by userspace daemon ueventd. There could be a noticeable delay
// between LOOP_CTL_GET_FREE issued and loop device created, so we need to
// wait until it is created and then continue.
// The timeout (5s) and time quantum (20ms) is picked randomly, it bares no
// special meaning but they worked fine empirically.
#[cfg(target_os = "android")]
fn wait_for_device<P: AsRef<Path>>(device: P) {
let start = std::time::Instant::now();
let timeout = std::time::Duration::from_secs(5);
let quantum = std::time::Duration::from_millis(20);
while !device.as_ref().exists() {
if start.elapsed() > timeout {
break;
}
std::thread::sleep(quantum);
}
}

0 comments on commit 4baedb0

Please sign in to comment.