Flush data to instance disk using BLKFLSBUF
Previously, we used fsync which works only for file descriptors that
are not by page cache. Since the instance disk is directly opened as a
block device, fsync didn't work. Fixing the issue by using BLKFLSBUF
instead.
Bug: 208639280
Test: atest MicrodroidTestApp
Change-Id: I782bc9d1d59d302fedecc72f471abde601162830
diff --git a/microdroid_manager/src/ioutil.rs b/microdroid_manager/src/ioutil.rs
index 8ab2413..8ac3712 100644
--- a/microdroid_manager/src/ioutil.rs
+++ b/microdroid_manager/src/ioutil.rs
@@ -14,11 +14,13 @@
//! IO utilities
-use anyhow::{anyhow, Result};
+use anyhow::{anyhow, bail, Result};
use log::debug;
use std::fmt::Debug;
use std::fs::File;
use std::io;
+use std::os::unix::fs::FileTypeExt;
+use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::thread;
use std::time::{Duration, Instant};
@@ -45,6 +47,20 @@
}
}
+// From include/uapi/linux/fs.h
+const BLK: u8 = 0x12;
+const BLKFLSBUF: u8 = 97;
+nix::ioctl_none!(_blkflsbuf, BLK, BLKFLSBUF);
+
+pub fn blkflsbuf(f: &mut File) -> Result<()> {
+ if !f.metadata()?.file_type().is_block_device() {
+ bail!("{:?} is not a block device", f.as_raw_fd());
+ }
+ // SAFETY: The file is kept open until the end of this function.
+ unsafe { _blkflsbuf(f.as_raw_fd()) }?;
+ Ok(())
+}
+
#[cfg(test)]
mod tests {
use super::*;