Merge "Add a function connecting to vsock to LLNDK libavf" into main am: dc5f3113ce

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Virtualization/+/3399219

Change-Id: Ia94df503a539a1843f1bac7e536a90ceb53cab14
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/libs/libavf/include/android/virtualization.h b/libs/libavf/include/android/virtualization.h
index 85bf3a2..7ab7431 100644
--- a/libs/libavf/include/android/virtualization.h
+++ b/libs/libavf/include/android/virtualization.h
@@ -323,6 +323,19 @@
 int AVirtualMachine_stop(AVirtualMachine* _Nonnull vm) __INTRODUCED_IN(36);
 
 /**
+ * Open a vsock connection to the VM on the given port. The caller takes ownership of the returned
+ * file descriptor, and is responsible for closing the file descriptor.
+ *
+ * This operation is synchronous and `AVirtualMachine_connectVsock` may block.
+ *
+ * \param vm a handle on a virtual machine.
+ * \param port a vsock port number.
+ *
+ * \return If successful, it returns a valid file descriptor. Otherwise, it returns `-EIO`.
+ */
+int AVirtualMachine_connectVsock(AVirtualMachine* _Nonnull vm, uint32_t port) __INTRODUCED_IN(36);
+
+/**
  * Wait until a virtual machine stops or the given timeout elapses.
  *
  * \param vm a handle on a virtual machine.
diff --git a/libs/libavf/libavf.map.txt b/libs/libavf/libavf.map.txt
index f476566..efc368a 100644
--- a/libs/libavf/libavf.map.txt
+++ b/libs/libavf/libavf.map.txt
@@ -16,6 +16,7 @@
     AVirtualMachine_createRaw; # apex llndk
     AVirtualMachine_start; # apex llndk
     AVirtualMachine_stop; # apex llndk
+    AVirtualMachine_connectVsock; # apex llndk
     AVirtualMachine_waitForStop; # apex llndk
     AVirtualMachine_destroy; # apex llndk
   local:
diff --git a/libs/libavf/src/lib.rs b/libs/libavf/src/lib.rs
index 5988fae..56cdfb7 100644
--- a/libs/libavf/src/lib.rs
+++ b/libs/libavf/src/lib.rs
@@ -16,7 +16,7 @@
 
 use std::ffi::CStr;
 use std::fs::File;
-use std::os::fd::FromRawFd;
+use std::os::fd::{FromRawFd, IntoRawFd};
 use std::os::raw::{c_char, c_int};
 use std::ptr;
 use std::time::Duration;
@@ -353,6 +353,21 @@
     }
 }
 
+/// Open a vsock connection to the CID of the virtual machine on the given vsock port.
+///
+/// # Safety
+/// `vm` must be a pointer returned by `AVirtualMachine_create`.
+#[no_mangle]
+pub unsafe extern "C" fn AVirtualMachine_connectVsock(vm: *const VmInstance, port: u32) -> c_int {
+    // SAFETY: `vm` is assumed to be a valid, non-null pointer returned by
+    // `AVirtualMachine_createRaw`. It's the only reference to the object.
+    let vm = unsafe { &*vm };
+    match vm.connect_vsock(port) {
+        Ok(pfd) => pfd.into_raw_fd(),
+        Err(_) => -libc::EIO,
+    }
+}
+
 fn death_reason_to_stop_reason(death_reason: DeathReason) -> AVirtualMachineStopReason {
     match death_reason {
         DeathReason::VirtualizationServiceDied => {
diff --git a/libs/libvmclient/src/lib.rs b/libs/libvmclient/src/lib.rs
index c0baea5..8dd3cd3 100644
--- a/libs/libvmclient/src/lib.rs
+++ b/libs/libvmclient/src/lib.rs
@@ -312,6 +312,11 @@
             }
         })
     }
+
+    /// Opens a vsock connection to the CID of the VM on the given vsock port.
+    pub fn connect_vsock(&self, port: u32) -> BinderResult<ParcelFileDescriptor> {
+        self.vm.connectVsock(port as i32)
+    }
 }
 
 impl Debug for VmInstance {