Print actual file names rather than /proc/self/fd/NN
When virtualization service spawns a crosvm process, it doesn't pass
path to the disk files, but opens those files by itself and passes
/proc/self/fd/N paths where N is the open FD. This however makes the
logs difficult to understand.
This CL annotates those /proc/self/fd/N paths with their original paths
when printing the commandline arguments for the crosvm process.
Following is an example log:
```
I VirtualizationService: virtualizationservice::crosvm: Running crosvm
with args: ["--extended-status", "--log-level", "info,disk=off", "run",
"--disable-sandbox", "--no-balloon", "--cid", "10", "--mem", "88",
"--cpus", "1",
"--serial=type=file,path=/proc/self/fd/24,hardware=serial,num=1",
"--serial=type=file,path=/proc/self/fd/15,hardware=serial,num=2",
"--serial=type=file,path=/proc/self/fd/24,hardware=virtio-console,num=1",
"--serial=type=file,path=/proc/self/fd/52 (/data/misc/virtualizationservice/10/ramdump),hardware=virtio-console,num=2",
"--serial=type=file,path=/proc/self/fd/25,hardware=virtio-console,num=3",
"--initrd", "/proc/self/fd/58 (/apex/com.android.virt/etc/microdroid_initrd_full_debuggable.img)",
"--disk", "/proc/self/fd/42 (/data/misc/virtualizationservice/10/composite-0.img)",
"--rwdisk", "/proc/self/fd/47 (/data/misc/virtualizationservice/10/composite-1.img)",
"--disk", "/proc/self/fd/56 (/data/misc/virtualizationservice/10/composite-2.img)",
"/proc/self/fd/57 (/apex/com.android.virt/etc/fs/microdroid_kernel)",
"--socket", "/proc/self/fd/16"]
```
Bug: 251751405
Test: start a VM and see the log
Change-Id: I4ae3bf50c942426164f2f5cc45b8d6bb8e68b85b
diff --git a/virtualizationservice/src/crosvm.rs b/virtualizationservice/src/crosvm.rs
index f3abee0..f5c894a 100644
--- a/virtualizationservice/src/crosvm.rs
+++ b/virtualizationservice/src/crosvm.rs
@@ -23,6 +23,7 @@
use log::{debug, error, info};
use semver::{Version, VersionReq};
use nix::{fcntl::OFlag, unistd::pipe2};
+use regex::{Captures, Regex};
use shared_child::SharedChild;
use std::borrow::Cow;
use std::fs::{remove_dir_all, File};
@@ -546,7 +547,8 @@
debug!("Preserving FDs {:?}", preserved_fds);
command.preserved_fds(preserved_fds);
- info!("Running {:?}", command);
+ print_crosvm_args(&command);
+
let result = SharedChild::spawn(&mut command)?;
debug!("Spawned crosvm({}).", result.id());
Ok(result)
@@ -573,6 +575,31 @@
Ok(())
}
+/// Print arguments of the crosvm command. In doing so, /proc/self/fd/XX is annotated with the
+/// actual file path if the FD is backed by a regular file. If not, the /proc path is printed
+/// unmodified.
+fn print_crosvm_args(command: &Command) {
+ let re = Regex::new(r"/proc/self/fd/[\d]+").unwrap();
+ info!(
+ "Running crosvm with args: {:?}",
+ command
+ .get_args()
+ .map(|s| s.to_string_lossy())
+ .map(|s| {
+ re.replace_all(&s, |caps: &Captures| {
+ let path = &caps[0];
+ if let Ok(realpath) = std::fs::canonicalize(path) {
+ format!("{} ({})", path, realpath.to_string_lossy())
+ } else {
+ path.to_owned()
+ }
+ })
+ .into_owned()
+ })
+ .collect::<Vec<_>>()
+ );
+}
+
/// Adds the file descriptor for `file` to `preserved_fds`, and returns a string of the form
/// "/proc/self/fd/N" where N is the file descriptor.
fn add_preserved_fd(preserved_fds: &mut Vec<RawFd>, file: &dyn AsRawFd) -> String {