Add method to open vsock connection to VM.
Bug: 195411982
Test: atest VirtualizationTestCases MicrodroidHostTestCases
Change-Id: I37b4073b7faa5a7bd6b9c5b15241c1757408d19b
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualMachine.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualMachine.aidl
index 33c9716..081580c 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualMachine.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualMachine.aidl
@@ -32,4 +32,7 @@
* we might miss some events that happen before the registration is done.
*/
void registerCallback(IVirtualMachineCallback callback);
+
+ /** Open a vsock connection to the CID of the VM on the given port. */
+ ParcelFileDescriptor connectVsock(int port);
}
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index dc38075..96e3c44 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -517,6 +517,23 @@
self.instance.callbacks.add(callback.clone());
Ok(())
}
+
+ fn connectVsock(&self, port: i32) -> binder::Result<ParcelFileDescriptor> {
+ if !self.instance.running() {
+ return Err(new_binder_exception(
+ ExceptionCode::SERVICE_SPECIFIC,
+ "VM is no longer running",
+ ));
+ }
+ let stream =
+ VsockStream::connect_with_cid_port(self.instance.cid, port as u32).map_err(|e| {
+ new_binder_exception(
+ ExceptionCode::SERVICE_SPECIFIC,
+ format!("Failed to connect: {}", e),
+ )
+ })?;
+ Ok(vsock_stream_to_pfd(stream))
+ }
}
impl Drop for VirtualMachine {
@@ -535,9 +552,7 @@
/// Call all registered callbacks to notify that the payload has started.
pub fn notify_payload_started(&self, cid: Cid, stream: VsockStream) {
let callbacks = &*self.0.lock().unwrap();
- // SAFETY: ownership is transferred from stream to f
- let f = unsafe { File::from_raw_fd(stream.into_raw_fd()) };
- let pfd = ParcelFileDescriptor::new(f);
+ let pfd = vsock_stream_to_pfd(stream);
for callback in callbacks {
if let Err(e) = callback.onPayloadStarted(cid as i32, &pfd) {
error!("Error notifying payload start event from VM CID {}: {}", cid, e);
@@ -641,6 +656,13 @@
})
}
+/// Converts a `VsockStream` to a `ParcelFileDescriptor`.
+fn vsock_stream_to_pfd(stream: VsockStream) -> ParcelFileDescriptor {
+ // SAFETY: ownership is transferred from stream to f
+ let f = unsafe { File::from_raw_fd(stream.into_raw_fd()) };
+ ParcelFileDescriptor::new(f)
+}
+
/// Constructs a new Binder error `Status` with the given `ExceptionCode` and message.
fn new_binder_exception<T: AsRef<str>>(exception: ExceptionCode, message: T) -> Status {
Status::new_exception(exception, CString::new(message.as_ref()).ok().as_deref())