Merge changes I87868e87,I191fabee,Ib7d1491e
* changes:
Placeholder API for encrypted storage
Persistent vm_payload_service connection
Remove onPayloadStdio
diff --git a/compos/common/compos_client.rs b/compos/common/compos_client.rs
index 02459b2..601c6fc 100644
--- a/compos/common/compos_client.rs
+++ b/compos/common/compos_client.rs
@@ -32,10 +32,8 @@
use log::{info, warn};
use rustutils::system_properties;
use std::fs::{self, File};
-use std::io::{BufRead, BufReader};
use std::num::NonZeroU32;
use std::path::{Path, PathBuf};
-use std::thread;
use vmclient::{DeathReason, ErrorCode, VmInstance, VmWaitError};
/// This owns an instance of the CompOS VM.
@@ -244,13 +242,6 @@
log::info!("VM payload started, cid = {}", cid);
}
- fn on_payload_stdio(&self, cid: i32, stream: &File) {
- if let Err(e) = start_logging(stream) {
- log::warn!("Can't log vm output: {}", e);
- };
- log::info!("VM payload forwarded its stdio, cid = {}", cid);
- }
-
fn on_payload_ready(&self, cid: i32) {
log::info!("VM payload ready, cid = {}", cid);
}
@@ -267,19 +258,3 @@
log::warn!("VM died, cid = {}, reason = {:?}", cid, death_reason);
}
}
-
-fn start_logging(file: &File) -> Result<()> {
- let reader = BufReader::new(file.try_clone().context("Cloning file failed")?);
- thread::spawn(move || {
- for line in reader.lines() {
- match line {
- Ok(line) => info!("VM: {}", line),
- Err(e) => {
- warn!("Reading VM output failed: {}", e);
- break;
- }
- }
- }
- });
- Ok(())
-}
diff --git a/compos/src/compsvc_main.rs b/compos/src/compsvc_main.rs
index c280956..a4e3903 100644
--- a/compos/src/compsvc_main.rs
+++ b/compos/src/compsvc_main.rs
@@ -24,10 +24,10 @@
use anyhow::{bail, Result};
use compos_common::COMPOS_VSOCK_PORT;
-use log::{debug, error, warn};
+use log::{debug, error};
use rpcbinder::run_vsock_rpc_server;
use std::panic;
-use vm_payload_bindgen::{AVmPayload_notifyPayloadReady, AVmPayload_setupStdioProxy};
+use vm_payload_bindgen::AVmPayload_notifyPayloadReady;
fn main() {
if let Err(e) = try_main() {
@@ -44,10 +44,6 @@
panic::set_hook(Box::new(|panic_info| {
error!("{}", panic_info);
}));
- // Redirect stdio to the host.
- if !unsafe { AVmPayload_setupStdioProxy() } {
- warn!("Failed to setup stdio proxy");
- }
let service = compsvc::new_binder()?.as_binder();
debug!("compsvc is starting as a rpc service.");
diff --git a/demo/java/com/android/microdroid/demo/MainActivity.java b/demo/java/com/android/microdroid/demo/MainActivity.java
index ebc2bb3..8e870ea 100644
--- a/demo/java/com/android/microdroid/demo/MainActivity.java
+++ b/demo/java/com/android/microdroid/demo/MainActivity.java
@@ -42,7 +42,6 @@
import com.android.microdroid.testservice.ITestService;
import java.io.BufferedReader;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -172,13 +171,6 @@
public void onPayloadStarted(VirtualMachine vm) {}
@Override
- public void onPayloadStdio(VirtualMachine vm, ParcelFileDescriptor stream) {
- mPayloadOutput.postValue("(Payload connected standard output...)");
- InputStream input = new FileInputStream(stream.getFileDescriptor());
- mService.execute(new Reader("payload", mPayloadOutput, input));
- }
-
- @Override
public void onPayloadReady(VirtualMachine vm) {
// This check doesn't 100% prevent race condition or UI hang.
// However, it's fine for demo.
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachine.java b/javalib/src/android/system/virtualmachine/VirtualMachine.java
index d9c75c0..4435576 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachine.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachine.java
@@ -642,12 +642,6 @@
}
@Override
- public void onPayloadStdio(int cid, ParcelFileDescriptor stream) {
- executeCallback(
- (cb) -> cb.onPayloadStdio(VirtualMachine.this, stream));
- }
-
- @Override
public void onPayloadReady(int cid) {
executeCallback((cb) -> cb.onPayloadReady(VirtualMachine.this));
}
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java b/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java
index 26b8ba2..1f94a8b 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineCallback.java
@@ -137,9 +137,6 @@
/** Called when the payload starts in the VM. */
void onPayloadStarted(@NonNull VirtualMachine vm);
- /** Called when the payload creates a standard input/output stream. */
- void onPayloadStdio(@NonNull VirtualMachine vm, @NonNull ParcelFileDescriptor stream);
-
/**
* Called when the payload in the VM is ready to serve. See
* {@link VirtualMachine#connectToVsockServer(int)}.
diff --git a/microdroid/vm_payload/include/vm_payload.h b/microdroid/vm_payload/include/vm_payload.h
index d5853a1..48518ff 100644
--- a/microdroid/vm_payload/include/vm_payload.h
+++ b/microdroid/vm_payload/include/vm_payload.h
@@ -56,8 +56,9 @@
void (*on_ready)(void *param), void *param);
/**
- * Get a secret that is uniquely bound to this VM instance. The secrets are 32-byte values and the
- * value associated with an identifier will not change over the lifetime of the VM instance.
+ * Get a secret that is uniquely bound to this VM instance. The secrets are
+ * values up to 32 bytes long and the value associated with an identifier will
+ * not change over the lifetime of the VM instance.
*
* \param identifier identifier of the secret to return.
* \param identifier_size size of the secret identifier.
@@ -81,12 +82,16 @@
const char *AVmPayload_getApkContentsPath(void);
/**
- * Initiates a socket connection with the host and duplicates stdin, stdout and
- * stderr file descriptors to the socket.
+ * Gets the path to the encrypted persistent storage for the VM, if any. This is
+ * a directory under which any files or directories created will be stored on
+ * behalf of the VM by the host app. All data is encrypted using a key known
+ * only to the VM, so the host cannot decrypt it, but may delete it.
*
- * \return true on success and false on failure. If unsuccessful, the stdio FDs
- * may be in an inconsistent state.
+ * \return the path to the APK contents, or NULL if no encrypted storage was
+ * requested in the VM configuration. If non-null the returned string should not
+ * be deleted or freed by the application and remains valid for the lifetime of
+ * the VM.
*/
-bool AVmPayload_setupStdioProxy();
+const char *AVmPayload_getEncryptedStoragePath(void);
__END_DECLS
diff --git a/microdroid/vm_payload/src/lib.rs b/microdroid/vm_payload/src/lib.rs
index 65b59bf..be6cf93 100644
--- a/microdroid/vm_payload/src/lib.rs
+++ b/microdroid/vm_payload/src/lib.rs
@@ -18,5 +18,5 @@
pub use vm_payload_service::{
AVmPayload_getDiceAttestationCdi, AVmPayload_getDiceAttestationChain,
- AVmPayload_getVmInstanceSecret, AVmPayload_notifyPayloadReady, AVmPayload_setupStdioProxy,
+ AVmPayload_getVmInstanceSecret, AVmPayload_notifyPayloadReady,
};
diff --git a/microdroid/vm_payload/src/vm_payload_service.rs b/microdroid/vm_payload/src/vm_payload_service.rs
index e89f730..88484cc 100644
--- a/microdroid/vm_payload/src/vm_payload_service.rs
+++ b/microdroid/vm_payload/src/vm_payload_service.rs
@@ -21,24 +21,46 @@
use lazy_static::lazy_static;
use log::{error, info, Level};
use rpcbinder::{get_unix_domain_rpc_interface, run_vsock_rpc_server};
-use std::io;
use std::ffi::CString;
-use std::fs::File;
use std::os::raw::{c_char, c_void};
-use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd};
+use std::ptr;
+use std::sync::Mutex;
lazy_static! {
static ref VM_APK_CONTENTS_PATH_C: CString =
CString::new(VM_APK_CONTENTS_PATH).expect("CString::new failed");
+ static ref PAYLOAD_CONNECTION: Mutex<Option<Strong<dyn IVmPayloadService>>> = Mutex::default();
+}
+
+/// Return a connection to the payload service in Microdroid Manager. Uses the existing connection
+/// if there is one, otherwise attempts to create a new one.
+fn get_vm_payload_service() -> Result<Strong<dyn IVmPayloadService>> {
+ let mut connection = PAYLOAD_CONNECTION.lock().unwrap();
+ if let Some(strong) = &*connection {
+ Ok(strong.clone())
+ } else {
+ let new_connection: Strong<dyn IVmPayloadService> = get_unix_domain_rpc_interface(
+ VM_PAYLOAD_SERVICE_SOCKET_NAME,
+ )
+ .context(format!("Failed to connect to service: {}", VM_PAYLOAD_SERVICE_SOCKET_NAME))?;
+ *connection = Some(new_connection.clone());
+ Ok(new_connection)
+ }
+}
+
+/// Make sure our logging goes to logcat. It is harmless to call this more than once.
+fn initialize_logging() {
+ android_logger::init_once(
+ android_logger::Config::default().with_tag("vm_payload").with_min_level(Level::Debug),
+ );
}
/// Notifies the host that the payload is ready.
/// Returns true if the notification succeeds else false.
#[no_mangle]
pub extern "C" fn AVmPayload_notifyPayloadReady() -> bool {
- android_logger::init_once(
- android_logger::Config::default().with_tag("vm_payload").with_min_level(Level::Debug),
- );
+ initialize_logging();
+
if let Err(e) = try_notify_payload_ready() {
error!("{:?}", e);
false
@@ -77,6 +99,8 @@
on_ready: Option<unsafe extern "C" fn(param: *mut c_void)>,
param: *mut c_void,
) -> bool {
+ initialize_logging();
+
// SAFETY: AIBinder returned has correct reference count, and the ownership can
// safely be taken by new_spibinder.
let service = new_spibinder(service);
@@ -109,6 +133,8 @@
secret: *mut u8,
size: usize,
) -> bool {
+ initialize_logging();
+
let identifier = std::slice::from_raw_parts(identifier, identifier_size);
match try_get_vm_instance_secret(identifier, size) {
Err(e) => {
@@ -148,6 +174,8 @@
size: usize,
total: *mut usize,
) -> bool {
+ initialize_logging();
+
match try_get_dice_attestation_chain() {
Err(e) => {
error!("{:?}", e);
@@ -182,6 +210,8 @@
size: usize,
total: *mut usize,
) -> bool {
+ initialize_logging();
+
match try_get_dice_attestation_cdi() {
Err(e) => {
error!("{:?}", e);
@@ -201,41 +231,13 @@
(*VM_APK_CONTENTS_PATH_C).as_ptr()
}
+/// Gets the path to the VM's encrypted storage.
+#[no_mangle]
+pub extern "C" fn AVmPayload_getEncryptedStoragePath() -> *const c_char {
+ // TODO(b/254454578): Return a real path if storage is present
+ ptr::null()
+}
+
fn try_get_dice_attestation_cdi() -> Result<Vec<u8>> {
get_vm_payload_service()?.getDiceAttestationCdi().context("Cannot get attestation CDI")
}
-
-/// Creates a socket connection with the host and duplicates standard I/O
-/// file descriptors of the payload to that socket. Then notifies the host.
-#[no_mangle]
-pub extern "C" fn AVmPayload_setupStdioProxy() -> bool {
- if let Err(e) = try_setup_stdio_proxy() {
- error!("{:?}", e);
- false
- } else {
- info!("Successfully set up stdio proxy to the host");
- true
- }
-}
-
-fn dup2(old_fd: &File, new_fd: BorrowedFd) -> Result<(), io::Error> {
- // SAFETY - ownership does not change, only modifies the underlying raw FDs.
- match unsafe { libc::dup2(old_fd.as_raw_fd(), new_fd.as_raw_fd()) } {
- -1 => Err(io::Error::last_os_error()),
- _ => Ok(()),
- }
-}
-
-fn try_setup_stdio_proxy() -> Result<()> {
- let fd =
- get_vm_payload_service()?.setupStdioProxy().context("Could not connect a host socket")?;
- dup2(fd.as_ref(), io::stdin().as_fd()).context("Failed to dup stdin")?;
- dup2(fd.as_ref(), io::stdout().as_fd()).context("Failed to dup stdout")?;
- dup2(fd.as_ref(), io::stderr().as_fd()).context("Failed to dup stderr")?;
- Ok(())
-}
-
-fn get_vm_payload_service() -> Result<Strong<dyn IVmPayloadService>> {
- get_unix_domain_rpc_interface(VM_PAYLOAD_SERVICE_SOCKET_NAME)
- .context(format!("Failed to connect to service: {}", VM_PAYLOAD_SERVICE_SOCKET_NAME))
-}
diff --git a/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl b/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
index 1141965..f8e7d34 100644
--- a/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
+++ b/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
@@ -16,8 +16,6 @@
package android.system.virtualization.payload;
-import android.os.ParcelFileDescriptor;
-
/**
* This interface regroups the tasks that payloads delegate to
* Microdroid Manager for execution.
@@ -63,16 +61,4 @@
* @throws SecurityException if the use of test APIs is not permitted.
*/
byte[] getDiceAttestationCdi();
-
- /**
- * Sets up a standard I/O proxy to the host.
- *
- * Creates a socket with the host and notifies its listeners that the stdio
- * proxy is ready.
- *
- * Temporarily uses a random free port allocated by the OS.
- * @return a file descriptor that the payload should dup() its standard I/O
- * file descriptors to.
- */
- ParcelFileDescriptor setupStdioProxy();
}
diff --git a/microdroid_manager/src/vm_payload_service.rs b/microdroid_manager/src/vm_payload_service.rs
index 126a8a9..fcfc79d 100644
--- a/microdroid_manager/src/vm_payload_service.rs
+++ b/microdroid_manager/src/vm_payload_service.rs
@@ -18,18 +18,15 @@
use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::{
BnVmPayloadService, IVmPayloadService, VM_PAYLOAD_SERVICE_SOCKET_NAME};
use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::IVirtualMachineService::IVirtualMachineService;
-use anyhow::{bail, Context, Result};
-use binder::{Interface, BinderFeatures, ExceptionCode, ParcelFileDescriptor, Status, Strong};
+use anyhow::{bail, Result};
+use binder::{Interface, BinderFeatures, ExceptionCode, Status, Strong};
use log::{error, info};
use openssl::hkdf::hkdf;
use openssl::md::Md;
use rpcbinder::run_init_unix_domain_rpc_server;
-use std::fs::File;
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
-use std::os::unix::io::{FromRawFd, IntoRawFd};
-use vsock::VsockListener;
/// Implementation of `IVmPayloadService`.
struct VmPayloadService {
@@ -70,16 +67,6 @@
self.check_restricted_apis_allowed()?;
Ok(self.dice.cdi_attest.to_vec())
}
-
- fn setupStdioProxy(&self) -> binder::Result<ParcelFileDescriptor> {
- let f = self.setup_payload_stdio_proxy().map_err(|e| {
- Status::new_service_specific_error_str(
- -1,
- Some(format!("Failed to create stdio proxy: {:?}", e)),
- )
- })?;
- Ok(ParcelFileDescriptor::new(f))
- }
}
impl Interface for VmPayloadService {}
@@ -102,22 +89,6 @@
Err(Status::new_exception_str(ExceptionCode::SECURITY, Some("Use of restricted APIs")))
}
}
-
- fn setup_payload_stdio_proxy(&self) -> Result<File> {
- // Instead of a predefined port in the host, we open up a port in the guest and have
- // the host connect to it. This makes it possible to have per-app instances of VS.
- const ANY_PORT: u32 = u32::MAX; // (u32)-1
- let listener = VsockListener::bind_with_cid_port(libc::VMADDR_CID_ANY, ANY_PORT)
- .context("Failed to create vsock listener")?;
- let addr = listener.local_addr().context("Failed to resolve listener port")?;
- self.virtual_machine_service
- .connectPayloadStdioProxy(addr.port() as i32)
- .context("Failed to connect to the host")?;
- let (stream, _) =
- listener.accept().context("Failed to accept vsock connection from the host")?;
- // SAFETY: ownership is transferred from stream to the new File
- Ok(unsafe { File::from_raw_fd(stream.into_raw_fd()) })
- }
}
/// Registers the `IVmPayloadService` service.
diff --git a/tests/aidl/com/android/microdroid/testservice/ITestService.aidl b/tests/aidl/com/android/microdroid/testservice/ITestService.aidl
index e8c435f..eda4f75 100644
--- a/tests/aidl/com/android/microdroid/testservice/ITestService.aidl
+++ b/tests/aidl/com/android/microdroid/testservice/ITestService.aidl
@@ -36,4 +36,7 @@
/* get the APK contents path. */
String getApkContentsPath();
+
+ /* get the encrypted storage path. */
+ String getEncryptedStoragePath();
}
diff --git a/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java b/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
index 6f44ff3..24e2049 100644
--- a/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
+++ b/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
@@ -229,9 +229,6 @@
public void onPayloadStarted(VirtualMachine vm) {}
@Override
- public void onPayloadStdio(VirtualMachine vm, ParcelFileDescriptor stream) {}
-
- @Override
public void onPayloadReady(VirtualMachine vm) {}
@Override
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
index eb719b8..da7c7ec 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -27,7 +27,6 @@
import android.content.Context;
import android.os.Build;
-import android.os.ParcelFileDescriptor;
import android.os.ServiceSpecificException;
import android.os.SystemProperties;
import android.system.virtualmachine.VirtualMachine;
@@ -122,6 +121,7 @@
assertThat(testResults.mAppRunProp).isEqualTo("true");
assertThat(testResults.mSublibRunProp).isEqualTo("true");
assertThat(testResults.mApkContentsPath).isEqualTo("/mnt/apk");
+ assertThat(testResults.mEncryptedStoragePath).isEqualTo("");
}
@Test
@@ -708,6 +708,7 @@
String mSublibRunProp;
String mExtraApkTestProp;
String mApkContentsPath;
+ String mEncryptedStoragePath;
}
private TestResults runVmTestService(VirtualMachine vm) throws Exception {
@@ -729,6 +730,8 @@
testResults.mExtraApkTestProp =
testService.readProperty("debug.microdroid.test.extra_apk");
testResults.mApkContentsPath = testService.getApkContentsPath();
+ testResults.mEncryptedStoragePath =
+ testService.getEncryptedStoragePath();
} catch (Exception e) {
testResults.mException = e;
}
@@ -747,13 +750,6 @@
Log.i(TAG, "onPayloadStarted");
payloadStarted.complete(true);
}
-
- @Override
- public void onPayloadStdio(VirtualMachine vm, ParcelFileDescriptor stream) {
- Log.i(TAG, "onPayloadStdio");
- logVmOutput(
- TAG, new FileInputStream(stream.getFileDescriptor()), "Payload");
- }
};
listener.runToFinish(TAG, vm);
assertThat(payloadStarted.getNow(false)).isTrue();
diff --git a/tests/testapk/src/native/testbinary.cpp b/tests/testapk/src/native/testbinary.cpp
index 1b18ce9..694f452 100644
--- a/tests/testapk/src/native/testbinary.cpp
+++ b/tests/testapk/src/native/testbinary.cpp
@@ -123,6 +123,16 @@
*out = path;
return ndk::ScopedAStatus::ok();
}
+
+ ndk::ScopedAStatus getEncryptedStoragePath(std::string* out) override {
+ const char* path_c = AVmPayload_getEncryptedStoragePath();
+ if (path_c == nullptr) {
+ out->clear();
+ } else {
+ *out = path_c;
+ }
+ return ndk::ScopedAStatus::ok();
+ }
};
auto testService = ndk::SharedRefBase::make<TestService>();
@@ -158,9 +168,6 @@
} // Anonymous namespace
extern "C" int AVmPayload_main() {
- // Forward standard I/O to the host.
- AVmPayload_setupStdioProxy();
-
// disable buffering to communicate seamlessly
setvbuf(stdin, nullptr, _IONBF, 0);
setvbuf(stdout, nullptr, _IONBF, 0);
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualMachineCallback.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualMachineCallback.aidl
index 521cf12..a329fa6 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualMachineCallback.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualMachineCallback.aidl
@@ -29,11 +29,6 @@
void onPayloadStarted(int cid);
/**
- * Called when the payload provides access to its standard input/output via a socket.
- */
- void onPayloadStdio(int cid, in ParcelFileDescriptor fd);
-
- /**
* Called when the payload in the VM is ready to serve.
*/
void onPayloadReady(int cid);
diff --git a/virtualizationservice/aidl/android/system/virtualmachineservice/IVirtualMachineService.aidl b/virtualizationservice/aidl/android/system/virtualmachineservice/IVirtualMachineService.aidl
index deee662..f2d92af 100644
--- a/virtualizationservice/aidl/android/system/virtualmachineservice/IVirtualMachineService.aidl
+++ b/virtualizationservice/aidl/android/system/virtualmachineservice/IVirtualMachineService.aidl
@@ -50,9 +50,4 @@
* Notifies that an error has occurred inside the VM.
*/
void notifyError(ErrorCode errorCode, in String message);
-
- /**
- * Notifies that the guest has started a stdio proxy on the given port.
- */
- void connectPayloadStdioProxy(int port);
}
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 2ec39e8..cfcfa2b 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -953,16 +953,6 @@
}
}
- /// Call all registered callbacks to notify that the payload has provided a standard I/O proxy.
- pub fn notify_payload_stdio(&self, cid: Cid, fd: ParcelFileDescriptor) {
- let callbacks = &*self.0.lock().unwrap();
- for callback in callbacks {
- if let Err(e) = callback.onPayloadStdio(cid as i32, &fd) {
- error!("Error notifying payload stdio event from VM CID {}: {:?}", cid, e);
- }
- }
- }
-
/// Call all registered callbacks to say that the VM has died.
pub fn callback_on_died(&self, cid: Cid, reason: DeathReason) {
let callbacks = &*self.0.lock().unwrap();
@@ -1187,27 +1177,6 @@
))
}
}
-
- fn connectPayloadStdioProxy(&self, port: i32) -> binder::Result<()> {
- let cid = self.cid;
- if let Some(vm) = self.state.lock().unwrap().get_vm(cid) {
- info!("VM with CID {} started a stdio proxy", cid);
- let stream = VsockStream::connect_with_cid_port(cid, port as u32).map_err(|e| {
- Status::new_service_specific_error_str(
- -1,
- Some(format!("Failed to connect to guest stdio proxy: {:?}", e)),
- )
- })?;
- vm.callbacks.notify_payload_stdio(cid, vsock_stream_to_pfd(stream));
- Ok(())
- } else {
- error!("connectPayloadStdioProxy is called from an unknown CID {}", cid);
- Err(Status::new_service_specific_error_str(
- -1,
- Some(format!("cannot find a VM with CID {}", cid)),
- ))
- }
- }
}
impl VirtualMachineService {
diff --git a/vm/src/run.rs b/vm/src/run.rs
index 7cd5a19..1f0433d 100644
--- a/vm/src/run.rs
+++ b/vm/src/run.rs
@@ -27,7 +27,7 @@
use binder::ParcelFileDescriptor;
use microdroid_payload_config::VmPayloadConfig;
use std::fs::File;
-use std::io::{self, BufRead, BufReader};
+use std::io;
use std::os::unix::io::{AsRawFd, FromRawFd};
use std::path::{Path, PathBuf};
use vmclient::{ErrorCode, VmInstance};
@@ -280,20 +280,6 @@
eprintln!("payload started");
}
- fn on_payload_stdio(&self, _cid: i32, stream: &File) {
- eprintln!("connecting payload stdio...");
- // Show the output of the payload
- let mut reader = BufReader::new(stream.try_clone().unwrap());
- std::thread::spawn(move || loop {
- let mut s = String::new();
- match reader.read_line(&mut s) {
- Ok(0) => break,
- Ok(_) => print!("{}", s),
- Err(e) => eprintln!("error reading from virtual machine: {}", e),
- };
- });
- }
-
fn on_payload_ready(&self, _cid: i32) {
eprintln!("payload is ready");
}
diff --git a/vmclient/src/lib.rs b/vmclient/src/lib.rs
index 1dd553c..20b7f02 100644
--- a/vmclient/src/lib.rs
+++ b/vmclient/src/lib.rs
@@ -80,9 +80,6 @@
/// clients.
fn on_payload_ready(&self, cid: i32) {}
- /// Called by the payload to forward its standard I/O streams to the host.
- fn on_payload_stdio(&self, cid: i32, fd: &File);
-
/// Called when the payload has exited in the VM. `exit_code` is the exit code of the payload
/// process.
fn on_payload_finished(&self, cid: i32, exit_code: i32) {}
@@ -280,13 +277,6 @@
Ok(())
}
- fn onPayloadStdio(&self, cid: i32, stream: &ParcelFileDescriptor) -> BinderResult<()> {
- if let Some(ref callback) = self.client_callback {
- callback.on_payload_stdio(cid, stream.as_ref());
- }
- Ok(())
- }
-
fn onPayloadReady(&self, cid: i32) -> BinderResult<()> {
self.state.notify_state(VirtualMachineState::READY);
if let Some(ref callback) = self.client_callback {