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/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index f69cad4..0b11416 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -287,11 +287,15 @@
.held_contexts
.iter()
.filter_map(|(_, inst)| Weak::upgrade(inst))
- .map(|vm| VirtualMachineDebugInfo {
- cid: vm.cid as i32,
- temporaryDirectory: vm.get_temp_dir().to_string_lossy().to_string(),
- requesterUid: vm.requester_uid as i32,
- requesterPid: vm.requester_debug_pid,
+ .map(|vm| {
+ let vm = vm.lock().unwrap();
+ VirtualMachineDebugInfo {
+ cid: vm.cid as i32,
+ temporaryDirectory: vm.get_temp_dir().to_string_lossy().to_string(),
+ requesterUid: vm.requester_uid as i32,
+ requesterPid: vm.requester_debug_pid,
+ hostConsoleName: vm.host_console_name.clone(),
+ }
})
.collect();
Ok(cids)
@@ -660,6 +664,8 @@
requester_uid: uid_t,
/// PID of the client who requested this VM instance.
requester_debug_pid: pid_t,
+ /// Name of the host console.
+ host_console_name: Option<String>,
}
impl GlobalVmInstance {
@@ -674,7 +680,7 @@
struct GlobalState {
/// VM contexts currently allocated to running VMs. A CID is never recycled as long
/// as there is a strong reference held by a GlobalVmContext.
- held_contexts: HashMap<Cid, Weak<GlobalVmInstance>>,
+ held_contexts: HashMap<Cid, Weak<Mutex<GlobalVmInstance>>>,
/// Cached read-only FD of VM DTBO file. Also serves as a lock for creating the file.
dtbo_file: Mutex<Option<File>>,
@@ -754,8 +760,13 @@
self.held_contexts.retain(|_, instance| instance.strong_count() > 0);
let cid = self.get_next_available_cid()?;
- let instance = Arc::new(GlobalVmInstance { cid, requester_uid, requester_debug_pid });
- create_temporary_directory(&instance.get_temp_dir(), Some(requester_uid))?;
+ let instance = Arc::new(Mutex::new(GlobalVmInstance {
+ cid,
+ requester_uid,
+ requester_debug_pid,
+ ..Default::default()
+ }));
+ create_temporary_directory(&instance.lock().unwrap().get_temp_dir(), Some(requester_uid))?;
self.held_contexts.insert(cid, Arc::downgrade(&instance));
let binder = GlobalVmContext { instance, ..Default::default() };
@@ -835,7 +846,7 @@
#[derive(Debug, Default)]
struct GlobalVmContext {
/// Strong reference to the context's instance data structure.
- instance: Arc<GlobalVmInstance>,
+ instance: Arc<Mutex<GlobalVmInstance>>,
/// Keeps our service process running as long as this VM context exists.
#[allow(dead_code)]
lazy_service_guard: LazyServiceGuard,
@@ -845,11 +856,16 @@
impl IGlobalVmContext for GlobalVmContext {
fn getCid(&self) -> binder::Result<i32> {
- Ok(self.instance.cid as i32)
+ Ok(self.instance.lock().unwrap().cid as i32)
}
fn getTemporaryDirectory(&self) -> binder::Result<String> {
- Ok(self.instance.get_temp_dir().to_string_lossy().to_string())
+ Ok(self.instance.lock().unwrap().get_temp_dir().to_string_lossy().to_string())
+ }
+
+ fn setHostConsoleName(&self, pathname: &str) -> binder::Result<()> {
+ self.instance.lock().unwrap().host_console_name = Some(pathname.to_string());
+ Ok(())
}
}