Use --force-compile for tests
The test uses --force-compile outside the VM, so we also need to inside the VM. But we want --compile for the normal case of compilation, so we only produce exactly the required artifacts. That means we have to pass whether we are testing or not from the host to guest, so lots of plumbing is needed. (Also figured out how to solve a problem with type deduction that the me of a few months ago was baffled by.) Bug: 211458160 Test: atest ComposTestCase Change-Id: Ie7e36bc3fab40744e9f9ea5e5928126899d9060d
This commit is contained in:
parent
4382754aa8
commit
2d2e4dba53
|
@ -28,6 +28,7 @@ rust_defaults {
|
|||
"libprotobuf",
|
||||
"libregex",
|
||||
"libring",
|
||||
"librustutils",
|
||||
"libscopeguard",
|
||||
],
|
||||
prefer_rlib: true,
|
||||
|
|
|
@ -20,6 +20,17 @@ import com.android.compos.CompOsKeyData;
|
|||
|
||||
/** {@hide} */
|
||||
interface ICompOsService {
|
||||
/**
|
||||
* What type of compilation to perform.
|
||||
*/
|
||||
@Backing(type="int")
|
||||
enum CompilationMode {
|
||||
/** Compile artifacts required by the current set of APEXes for use on reboot. */
|
||||
NORMAL_COMPILE = 0,
|
||||
/** Compile a full set of artifacts for test purposes. */
|
||||
TEST_COMPILE = 1,
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the service with the supplied encrypted private key blob. The key cannot be
|
||||
* changed once initialized, so once initiailzed, a repeated call will fail with
|
||||
|
@ -37,6 +48,7 @@ interface ICompOsService {
|
|||
* through systemDirFd over AuthFS), and *CLASSPATH derived in the VM, to generate the same
|
||||
* odrefresh output artifacts to the output directory (through outputDirFd).
|
||||
*
|
||||
* @param compilationMode The type of compilation to be performed
|
||||
* @param systemDirFd An fd referring to /system
|
||||
* @param outputDirFd An fd referring to the output directory, ART_APEX_DATA
|
||||
* @param stagingDirFd An fd referring to the staging directory, e.g. ART_APEX_DATA/staging
|
||||
|
@ -46,8 +58,9 @@ interface ICompOsService {
|
|||
* @param systemServerCompilerFilter The compiler filter used to compile system server
|
||||
* @return odrefresh exit code
|
||||
*/
|
||||
byte odrefresh(int systemDirFd, int outputDirFd, int stagingDirFd, String targetDirName,
|
||||
String zygoteArch, String systemServerCompilerFilter);
|
||||
byte odrefresh(CompilationMode compilation_mode, int systemDirFd, int outputDirFd,
|
||||
int stagingDirFd, String targetDirName, String zygoteArch,
|
||||
String systemServerCompilerFilter);
|
||||
|
||||
/**
|
||||
* Generate a new public/private key pair suitable for signing CompOs output files.
|
||||
|
|
|
@ -23,7 +23,9 @@ use android_system_composd::aidl::android::system::composd::{
|
|||
};
|
||||
use android_system_composd::binder::{Interface, Result as BinderResult, Strong};
|
||||
use anyhow::{Context, Result};
|
||||
use compos_aidl_interface::aidl::com::android::compos::ICompOsService::ICompOsService;
|
||||
use compos_aidl_interface::aidl::com::android::compos::ICompOsService::{
|
||||
CompilationMode::CompilationMode, ICompOsService,
|
||||
};
|
||||
use compos_common::odrefresh::ExitCode;
|
||||
use log::{error, warn};
|
||||
use rustutils::system_properties;
|
||||
|
@ -68,6 +70,7 @@ impl OdrefreshTask {
|
|||
|
||||
pub fn start(
|
||||
comp_os: Arc<CompOsInstance>,
|
||||
compilation_mode: CompilationMode,
|
||||
target_dir_name: String,
|
||||
callback: &Strong<dyn ICompilationTaskCallback>,
|
||||
) -> Result<OdrefreshTask> {
|
||||
|
@ -75,14 +78,19 @@ impl OdrefreshTask {
|
|||
let task = RunningTask { comp_os, callback: callback.clone() };
|
||||
let task = OdrefreshTask { running_task: Arc::new(Mutex::new(Some(task))) };
|
||||
|
||||
task.clone().start_thread(service, target_dir_name);
|
||||
task.clone().start_thread(service, compilation_mode, target_dir_name);
|
||||
|
||||
Ok(task)
|
||||
}
|
||||
|
||||
fn start_thread(self, service: Strong<dyn ICompOsService>, target_dir_name: String) {
|
||||
fn start_thread(
|
||||
self,
|
||||
service: Strong<dyn ICompOsService>,
|
||||
compilation_mode: CompilationMode,
|
||||
target_dir_name: String,
|
||||
) {
|
||||
thread::spawn(move || {
|
||||
let exit_code = run_in_vm(service, &target_dir_name);
|
||||
let exit_code = run_in_vm(service, compilation_mode, &target_dir_name);
|
||||
|
||||
let task = self.take();
|
||||
// We don't do the callback if cancel has already happened.
|
||||
|
@ -106,7 +114,11 @@ impl OdrefreshTask {
|
|||
}
|
||||
}
|
||||
|
||||
fn run_in_vm(service: Strong<dyn ICompOsService>, target_dir_name: &str) -> Result<ExitCode> {
|
||||
fn run_in_vm(
|
||||
service: Strong<dyn ICompOsService>,
|
||||
compilation_mode: CompilationMode,
|
||||
target_dir_name: &str,
|
||||
) -> Result<ExitCode> {
|
||||
let output_root = Path::new(ART_APEX_DATA);
|
||||
|
||||
// We need to remove the target directory because odrefresh running in compos will create it
|
||||
|
@ -134,6 +146,7 @@ fn run_in_vm(service: Strong<dyn ICompOsService>, target_dir_name: &str) -> Resu
|
|||
let system_server_compiler_filter =
|
||||
system_properties::read("dalvik.vm.systemservercompilerfilter").unwrap_or_default();
|
||||
let exit_code = service.odrefresh(
|
||||
compilation_mode,
|
||||
system_dir.as_raw_fd(),
|
||||
output_dir.as_raw_fd(),
|
||||
staging_dir.as_raw_fd(),
|
||||
|
|
|
@ -28,6 +28,7 @@ use android_system_composd::binder::{
|
|||
self, BinderFeatures, ExceptionCode, Interface, Status, Strong, ThreadState,
|
||||
};
|
||||
use anyhow::{Context, Result};
|
||||
use compos_aidl_interface::aidl::com::android::compos::ICompOsService::CompilationMode::CompilationMode;
|
||||
use compos_common::binder::to_binder_result;
|
||||
use rustutils::{users::AID_ROOT, users::AID_SYSTEM};
|
||||
use std::sync::Arc;
|
||||
|
@ -72,7 +73,12 @@ impl IsolatedCompilationService {
|
|||
let comp_os = self.instance_manager.start_pending_instance().context("Starting CompOS")?;
|
||||
|
||||
let target_dir_name = "compos-pending".to_owned();
|
||||
let task = OdrefreshTask::start(comp_os, target_dir_name, callback)?;
|
||||
let task = OdrefreshTask::start(
|
||||
comp_os,
|
||||
CompilationMode::NORMAL_COMPILE,
|
||||
target_dir_name,
|
||||
callback,
|
||||
)?;
|
||||
|
||||
Ok(BnCompilationTask::new_binder(task, BinderFeatures::default()))
|
||||
}
|
||||
|
@ -84,7 +90,12 @@ impl IsolatedCompilationService {
|
|||
let comp_os = self.instance_manager.start_test_instance().context("Starting CompOS")?;
|
||||
|
||||
let target_dir_name = "test-artifacts".to_owned();
|
||||
let task = OdrefreshTask::start(comp_os, target_dir_name, callback)?;
|
||||
let task = OdrefreshTask::start(
|
||||
comp_os,
|
||||
CompilationMode::TEST_COMPILE,
|
||||
target_dir_name,
|
||||
callback,
|
||||
)?;
|
||||
|
||||
Ok(BnCompilationTask::new_binder(task, BinderFeatures::default()))
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ use anyhow::{anyhow, bail, Context, Result};
|
|||
use log::{debug, info, warn};
|
||||
use minijail::{self, Minijail};
|
||||
use regex::Regex;
|
||||
use rustutils::system_properties;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
|
@ -35,11 +36,13 @@ use authfs_aidl_interface::aidl::com::android::virt::fs::{
|
|||
IAuthFsService::IAuthFsService,
|
||||
};
|
||||
use authfs_aidl_interface::binder::Strong;
|
||||
use compos_aidl_interface::aidl::com::android::compos::ICompOsService::CompilationMode::CompilationMode;
|
||||
use compos_common::odrefresh::ExitCode;
|
||||
|
||||
const FD_SERVER_PORT: i32 = 3264; // TODO: support dynamic port
|
||||
|
||||
pub struct OdrefreshContext<'a> {
|
||||
compilation_mode: CompilationMode,
|
||||
system_dir_fd: i32,
|
||||
output_dir_fd: i32,
|
||||
staging_dir_fd: i32,
|
||||
|
@ -50,6 +53,7 @@ pub struct OdrefreshContext<'a> {
|
|||
|
||||
impl<'a> OdrefreshContext<'a> {
|
||||
pub fn new(
|
||||
compilation_mode: CompilationMode,
|
||||
system_dir_fd: i32,
|
||||
output_dir_fd: i32,
|
||||
staging_dir_fd: i32,
|
||||
|
@ -57,6 +61,13 @@ impl<'a> OdrefreshContext<'a> {
|
|||
zygote_arch: &'a str,
|
||||
system_server_compiler_filter: &'a str,
|
||||
) -> Result<Self> {
|
||||
if compilation_mode != CompilationMode::NORMAL_COMPILE {
|
||||
let debuggable = system_properties::read_bool("ro.boot.microdroid.debuggable", false)?;
|
||||
if !debuggable {
|
||||
bail!("Requested compilation mode only available in debuggable VMs");
|
||||
}
|
||||
}
|
||||
|
||||
if system_dir_fd < 0 || output_dir_fd < 0 || staging_dir_fd < 0 {
|
||||
bail!("The remote FDs are expected to be non-negative");
|
||||
}
|
||||
|
@ -75,6 +86,7 @@ impl<'a> OdrefreshContext<'a> {
|
|||
// CompOS.
|
||||
|
||||
Ok(Self {
|
||||
compilation_mode,
|
||||
system_dir_fd,
|
||||
output_dir_fd,
|
||||
staging_dir_fd,
|
||||
|
@ -143,18 +155,21 @@ pub fn odrefresh(
|
|||
));
|
||||
}
|
||||
|
||||
args.push("--compile".to_string());
|
||||
let compile_flag = match context.compilation_mode {
|
||||
CompilationMode::NORMAL_COMPILE => "--compile",
|
||||
CompilationMode::TEST_COMPILE => "--force-compile",
|
||||
other => bail!("Unknown compilation mode {:?}", other),
|
||||
};
|
||||
args.push(compile_flag.to_string());
|
||||
|
||||
debug!("Running odrefresh with args: {:?}", &args);
|
||||
let jail = spawn_jailed_task(odrefresh_path, &args, &odrefresh_vars.into_env())
|
||||
.context("Spawn odrefresh")?;
|
||||
let exit_code = match jail.wait() {
|
||||
Ok(_) => Result::<u8>::Ok(0),
|
||||
Err(minijail::Error::ReturnCode(exit_code)) => Ok(exit_code),
|
||||
Err(e) => {
|
||||
bail!("Unexpected minijail error: {}", e)
|
||||
}
|
||||
}?;
|
||||
Ok(_) => 0,
|
||||
Err(minijail::Error::ReturnCode(exit_code)) => exit_code,
|
||||
Err(e) => bail!("Unexpected minijail error: {}", e),
|
||||
};
|
||||
|
||||
let exit_code = ExitCode::from_i32(exit_code.into())?;
|
||||
info!("odrefresh exited with {:?}", exit_code);
|
||||
|
|
|
@ -31,7 +31,7 @@ use crate::signing_key::{Signer, SigningKey};
|
|||
use authfs_aidl_interface::aidl::com::android::virt::fs::IAuthFsService::IAuthFsService;
|
||||
use compos_aidl_interface::aidl::com::android::compos::{
|
||||
CompOsKeyData::CompOsKeyData,
|
||||
ICompOsService::{BnCompOsService, ICompOsService},
|
||||
ICompOsService::{BnCompOsService, CompilationMode::CompilationMode, ICompOsService},
|
||||
};
|
||||
use compos_aidl_interface::binder::{
|
||||
BinderFeatures, ExceptionCode, Interface, Result as BinderResult, Strong,
|
||||
|
@ -82,6 +82,7 @@ impl ICompOsService for CompOsService {
|
|||
|
||||
fn odrefresh(
|
||||
&self,
|
||||
compilation_mode: CompilationMode,
|
||||
system_dir_fd: i32,
|
||||
output_dir_fd: i32,
|
||||
staging_dir_fd: i32,
|
||||
|
@ -90,6 +91,7 @@ impl ICompOsService for CompOsService {
|
|||
system_server_compiler_filter: &str,
|
||||
) -> BinderResult<i8> {
|
||||
let context = to_binder_result(OdrefreshContext::new(
|
||||
compilation_mode,
|
||||
system_dir_fd,
|
||||
output_dir_fd,
|
||||
staging_dir_fd,
|
||||
|
|
Loading…
Reference in New Issue