Merge "Fix microdroid boot with newer crosvm"
diff --git a/microdroid/Android.bp b/microdroid/Android.bp
index 39a612f..a0215c3 100644
--- a/microdroid/Android.bp
+++ b/microdroid/Android.bp
@@ -35,6 +35,10 @@
target: "/system/etc",
name: "etc",
},
+ {
+ target: "/system/bin",
+ name: "bin",
+ },
]
android_system_image {
@@ -88,6 +92,12 @@
"microdroid_keystore2_key_contexts",
"microdroid_compatibility_matrix",
"microdroid_manifest",
+
+ // TODO(b/195425111) these four should be added automatically
+ "android.hardware.security.secureclock-V1-ndk",
+ "android.hardware.security.sharedsecret-V1-ndk",
+ "libcrypto",
+ "liblzma",
] + microdroid_shell_and_utilities,
multilib: {
common: {
diff --git a/microdroid/init.rc b/microdroid/init.rc
index 043577d..d43ab22 100644
--- a/microdroid/init.rc
+++ b/microdroid/init.rc
@@ -117,17 +117,9 @@
# The bind+remount combination allows this to work in containers.
mount rootfs rootfs / remount bind ro nodev
- start keystore2
-
-on late-fs
- start vendor.keymint-microdroid
-
# TODO(b/185767624): change the hard-coded size?
mount tmpfs tmpfs /data noatime nosuid nodev rw size=128M
-on post-fs-data
- mark_post_data
-
# We chown/chmod /data again so because mount is run as root + defaults
chown system system /data
chmod 0771 /data
@@ -135,6 +127,21 @@
# We restorecon /data in case the userdata partition has been reset.
restorecon /data
+ # set up keystore directory structure first so that we can end early boot
+ # and start apexd
+ mkdir /data/misc 01771 system misc
+ mkdir /data/misc/keystore 0700 keystore keystore
+ # work around b/183668221
+ restorecon /data/misc /data/misc/keystore
+
+ start keystore2
+
+on late-fs
+ start vendor.keymint-microdroid
+
+on post-fs-data
+ mark_post_data
+
mkdir /data/vendor 0771 root root
mkdir /data/vendor_ce 0771 root root
mkdir /data/vendor_de 0771 root root
@@ -148,13 +155,6 @@
start tombstoned
- # set up keystore directory structure first so that we can end early boot
- # and start apexd
- mkdir /data/misc 01771 system misc
- mkdir /data/misc/keystore 0700 keystore keystore
- # work around b/183668221
- restorecon /data/misc /data/misc/keystore
-
# Boot level 30
# odsign signing keys have MAX_BOOT_LEVEL=30
# This is currently the earliest boot level, but we start at 30
diff --git a/microdroid_manager/Android.bp b/microdroid_manager/Android.bp
index 4ea156a..0ea5d87 100644
--- a/microdroid_manager/Android.bp
+++ b/microdroid_manager/Android.bp
@@ -16,9 +16,9 @@
"libmicrodroid_metadata",
"libmicrodroid_payload_config",
"libprotobuf",
+ "librustutils",
"libserde",
"libserde_json",
- "libsystem_properties-rust",
"libvsock",
],
init_rc: ["microdroid_manager.rc"],
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index 9efa68a..2586737 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -20,13 +20,13 @@
use anyhow::{anyhow, bail, Result};
use log::{error, info, warn};
use microdroid_payload_config::{Task, TaskType, VmPayloadConfig};
+use rustutils::system_properties::PropertyWatcher;
use std::fs::{self, File};
use std::os::unix::io::{FromRawFd, IntoRawFd};
use std::path::Path;
use std::process::{Command, Stdio};
use std::str;
use std::time::Duration;
-use system_properties::PropertyWatcher;
use vsock::VsockStream;
const WAIT_TIMEOUT: Duration = Duration::from_secs(10);
@@ -40,7 +40,7 @@
let config = load_config(Path::new(&metadata.payload_config_path))?;
let fake_secret = "This is a placeholder for a value that is derived from the images that are loaded in the VM.";
- if let Err(err) = system_properties::write("ro.vmsecret.keymint", fake_secret) {
+ if let Err(err) = rustutils::system_properties::write("ro.vmsecret.keymint", fake_secret) {
warn!("failed to set ro.vmsecret.keymint: {}", err);
}
diff --git a/tests/hostside/java/android/virt/test/MicrodroidTestCase.java b/tests/hostside/java/android/virt/test/MicrodroidTestCase.java
index c05a841..8881c51 100644
--- a/tests/hostside/java/android/virt/test/MicrodroidTestCase.java
+++ b/tests/hostside/java/android/virt/test/MicrodroidTestCase.java
@@ -69,13 +69,8 @@
assertThat(runOnMicrodroid("getprop", "debug.microdroid.app.run"), is("true"));
assertThat(runOnMicrodroid("getprop", "debug.microdroid.app.sublib.run"), is("true"));
- // Manually execute the library and check the output
- final String microdroidLauncher = "system/bin/microdroid_launcher";
- assertThat(
- runOnMicrodroid(microdroidLauncher, testLib, "arg1", "arg2"),
- is("Hello Microdroid " + testLib + " arg1 arg2"));
-
- // Check that keystore was found by the payload
+ // Check that keystore was found by the payload. Wait until the property is set.
+ tryRunOnMicrodroid("watch -e \"getprop debug.microdroid.test.keystore | grep '^$'\"");
assertThat(runOnMicrodroid("getprop", "debug.microdroid.test.keystore"), is("PASS"));
shutdownMicrodroid(getDevice(), cid);
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 64d3913..dc38075 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -128,14 +128,13 @@
let config = config.as_ref();
let zero_filler_path = temporary_directory.join("zero.img");
- let zero_filler_file = write_zero_filler(&zero_filler_path).map_err(|e| {
+ write_zero_filler(&zero_filler_path).map_err(|e| {
error!("Failed to make composite image: {}", e);
new_binder_exception(
ExceptionCode::SERVICE_SPECIFIC,
format!("Failed to make composite image: {}", e),
)
})?;
- indirect_files.push(zero_filler_file);
// Assemble disk images if needed.
let disks = config
@@ -291,7 +290,7 @@
Ok(())
}
-fn write_zero_filler(zero_filler_path: &Path) -> Result<File> {
+fn write_zero_filler(zero_filler_path: &Path) -> Result<()> {
let file = OpenOptions::new()
.create_new(true)
.read(true)
@@ -299,7 +298,7 @@
.open(zero_filler_path)
.with_context(|| "Failed to create zero.img")?;
file.set_len(ZERO_FILLER_SIZE)?;
- Ok(file)
+ Ok(())
}
/// Given the configuration for a disk image, assembles the `DiskFile` to pass to crosvm.
diff --git a/virtualizationservice/src/composite.rs b/virtualizationservice/src/composite.rs
index 685d0e6..ded0053 100644
--- a/virtualizationservice/src/composite.rs
+++ b/virtualizationservice/src/composite.rs
@@ -290,9 +290,9 @@
/// Constructs a composite disk image for the given list of partitions, and opens it ready to use.
///
-/// Returns the composite disk image file, and a list of FD mappings which must be applied to any
-/// process which wants to use it. This is necessary because the composite image contains paths of
-/// the form `/proc/self/fd/N` for the partition images.
+/// Returns the composite disk image file, and a list of files whose file descriptors must be passed
+/// to any process which wants to use it. This is necessary because the composite image contains
+/// paths of the form `/proc/self/fd/N` for the partition images.
pub fn make_composite_image(
partitions: &[Partition],
zero_filler_path: &Path,
@@ -300,7 +300,7 @@
header_path: &Path,
footer_path: &Path,
) -> Result<(File, Vec<File>), Error> {
- let (partitions, files) = convert_partitions(partitions)?;
+ let (partitions, mut files) = convert_partitions(partitions)?;
let mut composite_image = OpenOptions::new()
.create_new(true)
@@ -316,13 +316,16 @@
OpenOptions::new().create_new(true).read(true).write(true).open(footer_path).with_context(
|| format!("Failed to create composite image header {:?}", footer_path),
)?;
+ let zero_filler_file = File::open(&zero_filler_path).with_context(|| {
+ format!("Failed to open composite image zero filler {:?}", zero_filler_path)
+ })?;
create_composite_disk(
&partitions,
- zero_filler_path,
- header_path,
+ &fd_path_for_file(&zero_filler_file),
+ &fd_path_for_file(&header_file),
&mut header_file,
- footer_path,
+ &fd_path_for_file(&footer_file),
&mut footer_file,
&mut composite_image,
)?;
@@ -331,12 +334,16 @@
let composite_image = File::open(&output_path)
.with_context(|| format!("Failed to open composite image {:?}", output_path))?;
+ files.push(header_file);
+ files.push(footer_file);
+ files.push(zero_filler_file);
+
Ok((composite_image, files))
}
/// Given the AIDL config containing a list of partitions, with a [`ParcelFileDescriptor`] for each
-/// partition, return the list of file descriptors which must be passed to the composite disk image
-/// partition configuration for it.
+/// partition, returns the corresponding list of PartitionInfo and the list of files whose file
+/// descriptors must be passed to any process using the composite image.
fn convert_partitions(partitions: &[Partition]) -> Result<(Vec<PartitionInfo>, Vec<File>), Error> {
// File descriptors to pass to child process.
let mut files = vec![];
@@ -353,12 +360,12 @@
.try_clone()
.context("Failed to clone partition image file descriptor")?;
let size = get_partition_size(&file)?;
- let fd = file.as_raw_fd();
+ let path = fd_path_for_file(&file);
files.push(file);
Ok(PartitionInfo {
label: partition.label.to_owned(),
- path: format!("/proc/self/fd/{}", fd).into(),
+ path,
partition_type: ImagePartitionType::LinuxFilesystem,
writable: partition.writable,
size,
@@ -369,6 +376,11 @@
Ok((partitions, files))
}
+fn fd_path_for_file(file: &File) -> PathBuf {
+ let fd = file.as_raw_fd();
+ format!("/proc/self/fd/{}", fd).into()
+}
+
/// Find the size of the partition image in the given file by parsing the header.
///
/// This will work for raw, QCOW2, composite and Android sparse images.