Add `vm console` command to connect to serial console
`vm console` automatically connects to the first available VM.
`vm console CID` connects to the specified VM.
* Must also pass the `-t` flag to adb-shell to ensure adbd allocates a
tty.
Bug: 335362012
Test: Launch FC and connect to serial console
adb shell -t /apex/com.android.virt/bin/vm console
Change-Id: If5f1537d8994593ab7fa026bf98986c6a8c83cb5
diff --git a/vm/src/main.rs b/vm/src/main.rs
index a250c35..3c0887c 100644
--- a/vm/src/main.rs
+++ b/vm/src/main.rs
@@ -24,15 +24,18 @@
};
#[cfg(not(llpvm_changes))]
use anyhow::anyhow;
-use anyhow::{Context, Error};
+use anyhow::{bail, Context, Error};
use binder::{ProcessState, Strong};
use clap::{Args, Parser};
use create_idsig::command_create_idsig;
use create_partition::command_create_partition;
use run::{command_run, command_run_app, command_run_microdroid};
use serde::Serialize;
+use std::io::{self, IsTerminal};
use std::num::NonZeroU16;
+use std::os::unix::process::CommandExt;
use std::path::{Path, PathBuf};
+use std::process::Command;
#[derive(Args, Default)]
/// Collection of flags that are at VM level and therefore applicable to all subcommands
@@ -324,6 +327,11 @@
/// Path to idsig of the APK
path: PathBuf,
},
+ /// Connect to the serial console of a VM
+ Console {
+ /// CID of the VM
+ cid: Option<i32>,
+ },
}
fn parse_debug_level(s: &str) -> Result<DebugLevel, String> {
@@ -386,6 +394,7 @@
Opt::CreateIdsig { apk, path } => {
command_create_idsig(get_service()?.as_ref(), &apk, &path)
}
+ Opt::Console { cid } => command_console(cid),
}
}
@@ -450,6 +459,21 @@
Ok(())
}
+fn command_console(cid: Option<i32>) -> Result<(), Error> {
+ if !io::stdin().is_terminal() {
+ bail!("Stdin must be a terminal (tty). Use 'adb shell -t' to force allocate tty.");
+ }
+ let mut vms = get_service()?.debugListVms().context("Failed to get list of VMs")?;
+ if let Some(cid) = cid {
+ vms.retain(|vm_info| vm_info.cid == cid);
+ }
+ let host_console_name = vms
+ .into_iter()
+ .find_map(|vm_info| vm_info.hostConsoleName)
+ .context("Failed to get VM with console")?;
+ Err(Command::new("microcom").arg(host_console_name).exec().into())
+}
+
#[cfg(test)]
mod tests {
use super::*;