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))?,
+    ))
 }