composd: replace FD holder of File with OwnedFd
Originally, the FDs are owned by the local variable in `run_in_vm`.
Now they are owned by FdServerConfig.
Test: TH
Bug: 243500154
Change-Id: I639295838f0f35736aae82035d8ce215077778be
diff --git a/compos/composd/src/fd_server_helper.rs b/compos/composd/src/fd_server_helper.rs
index 24dc9e7..777ec27 100644
--- a/compos/composd/src/fd_server_helper.rs
+++ b/compos/composd/src/fd_server_helper.rs
@@ -23,7 +23,7 @@
use nix::unistd::pipe2;
use std::fs::File;
use std::io::Read;
-use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
+use std::os::unix::io::{AsRawFd, FromRawFd, OwnedFd};
use std::path::Path;
const FD_SERVER_BIN: &str = "/apex/com.android.virt/bin/fd_server";
@@ -32,13 +32,13 @@
#[derive(Default)]
pub struct FdServerConfig {
/// List of file FDs exposed for read-only operations.
- pub ro_file_fds: Vec<RawFd>,
+ pub ro_file_fds: Vec<OwnedFd>,
/// List of file FDs exposed for read-write operations.
- pub rw_file_fds: Vec<RawFd>,
+ pub rw_file_fds: Vec<OwnedFd>,
/// List of directory FDs exposed for read-only operations.
- pub ro_dir_fds: Vec<RawFd>,
+ pub ro_dir_fds: Vec<OwnedFd>,
/// List of directory FDs exposed for read-write operations.
- pub rw_dir_fds: Vec<RawFd>,
+ pub rw_dir_fds: Vec<OwnedFd>,
}
impl FdServerConfig {
@@ -53,25 +53,29 @@
fn do_spawn_fd_server(self, ready_file: File) -> Result<Minijail> {
let mut inheritable_fds = Vec::new();
let mut args = vec![FD_SERVER_BIN.to_string()];
- for fd in self.ro_file_fds {
+ for fd in &self.ro_file_fds {
+ let raw_fd = fd.as_raw_fd();
args.push("--ro-fds".to_string());
- args.push(fd.to_string());
- inheritable_fds.push(fd);
+ args.push(raw_fd.to_string());
+ inheritable_fds.push(raw_fd);
}
- for fd in self.rw_file_fds {
+ for fd in &self.rw_file_fds {
+ let raw_fd = fd.as_raw_fd();
args.push("--rw-fds".to_string());
- args.push(fd.to_string());
- inheritable_fds.push(fd);
+ args.push(raw_fd.to_string());
+ inheritable_fds.push(raw_fd);
}
- for fd in self.ro_dir_fds {
+ for fd in &self.ro_dir_fds {
+ let raw_fd = fd.as_raw_fd();
args.push("--ro-dirs".to_string());
- args.push(fd.to_string());
- inheritable_fds.push(fd);
+ args.push(raw_fd.to_string());
+ inheritable_fds.push(raw_fd);
}
- for fd in self.rw_dir_fds {
+ for fd in &self.rw_dir_fds {
+ let raw_fd = fd.as_raw_fd();
args.push("--rw-dirs".to_string());
- args.push(fd.to_string());
- inheritable_fds.push(fd);
+ args.push(raw_fd.to_string());
+ inheritable_fds.push(raw_fd);
}
let ready_fd = ready_file.as_raw_fd();
args.push("--ready-fd".to_string());
diff --git a/compos/composd/src/odrefresh_task.rs b/compos/composd/src/odrefresh_task.rs
index 100fc50..5c926b1 100644
--- a/compos/composd/src/odrefresh_task.rs
+++ b/compos/composd/src/odrefresh_task.rs
@@ -32,9 +32,9 @@
};
use log::{error, info, warn};
use rustutils::system_properties;
-use std::fs::{remove_dir_all, File, OpenOptions};
+use std::fs::{remove_dir_all, OpenOptions};
use std::os::unix::fs::OpenOptionsExt;
-use std::os::unix::io::AsRawFd;
+use std::os::unix::io::{AsRawFd, OwnedFd};
use std::path::Path;
use std::sync::{Arc, Mutex};
use std::thread;
@@ -152,14 +152,19 @@
.with_context(|| format!("Failed to delete {}", target_path.display()))?;
}
- let staging_dir = open_dir(composd_native::palette_create_odrefresh_staging_directory()?)?;
- let system_dir = open_dir(Path::new("/system"))?;
- let output_dir = open_dir(output_root)?;
+ let staging_dir_fd = open_dir(composd_native::palette_create_odrefresh_staging_directory()?)?;
+ let system_dir_fd = open_dir(Path::new("/system"))?;
+ let output_dir_fd = open_dir(output_root)?;
+
+ // Get the raw FD before passing the ownership, since borrowing will violate the borrow check.
+ let system_dir_raw_fd = system_dir_fd.as_raw_fd();
+ let output_dir_raw_fd = output_dir_fd.as_raw_fd();
+ let staging_dir_raw_fd = staging_dir_fd.as_raw_fd();
// Spawn a fd_server to serve the FDs.
let fd_server_config = FdServerConfig {
- ro_dir_fds: vec![system_dir.as_raw_fd()],
- rw_dir_fds: vec![staging_dir.as_raw_fd(), output_dir.as_raw_fd()],
+ ro_dir_fds: vec![system_dir_fd],
+ rw_dir_fds: vec![staging_dir_fd, output_dir_fd],
..Default::default()
};
let fd_server_raii = fd_server_config.into_fd_server()?;
@@ -169,9 +174,9 @@
system_properties::read("dalvik.vm.systemservercompilerfilter")?.unwrap_or_default();
let exit_code = service.odrefresh(
compilation_mode,
- system_dir.as_raw_fd(),
- output_dir.as_raw_fd(),
- staging_dir.as_raw_fd(),
+ system_dir_raw_fd,
+ output_dir_raw_fd,
+ staging_dir_raw_fd,
target_dir_name,
&zygote_arch,
&system_server_compiler_filter,
@@ -181,12 +186,13 @@
ExitCode::from_i32(exit_code.into())
}
-/// Returns an owned FD of the directory. It currently returns a `File` as a FD owner, but
-/// it's better to use `std::os::unix::io::OwnedFd` once/if it becomes standard.
-fn open_dir(path: &Path) -> Result<File> {
- OpenOptions::new()
- .custom_flags(libc::O_DIRECTORY)
- .read(true) // O_DIRECTORY can only be opened with read
- .open(path)
- .with_context(|| format!("Failed to open {:?} directory as path fd", path))
+/// Returns an `OwnedFD` of the directory.
+fn open_dir(path: &Path) -> Result<OwnedFd> {
+ Ok(OwnedFd::from(
+ OpenOptions::new()
+ .custom_flags(libc::O_DIRECTORY)
+ .read(true) // O_DIRECTORY can only be opened with read
+ .open(path)
+ .with_context(|| format!("Failed to open {:?} directory as path fd", path))?,
+ ))
}