blob: 3a794eee30e9bdd07b926f97986e66bf0ae7b92c [file] [log] [blame]
Victor Hsieh272aa242021-02-01 14:19:20 -08001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Victor Hsieh51789de2021-08-06 16:50:49 -070017//! compsvc is a service to run compilation tasks in a PVM upon request. It is able to set up
Victor Hsiehebb1d902021-08-06 13:00:18 -070018//! file descriptors backed by authfs (via authfs_service) and pass the file descriptors to the
Victor Hsieh51789de2021-08-06 16:50:49 -070019//! actual compiler.
Victor Hsieh272aa242021-02-01 14:19:20 -080020
Victor Hsiehec38ae22022-02-10 00:06:26 +000021use anyhow::{bail, Context, Result};
Victor Hsieh9ed27182021-08-25 15:52:42 -070022use std::default::Default;
Victor Hsiehec38ae22022-02-10 00:06:26 +000023use std::fs::read_dir;
24use std::path::{Path, PathBuf};
Victor Hsieh272aa242021-02-01 14:19:20 -080025
Victor Hsiehec38ae22022-02-10 00:06:26 +000026use crate::artifact_signer::ArtifactSigner;
Victor Hsieh616f8222022-01-14 13:06:32 -080027use crate::compilation::{odrefresh, OdrefreshContext};
Alan Stokes16fb8552022-02-10 15:07:27 +000028use crate::compos_key;
Alan Stokes6542fdd2022-02-17 15:21:46 +000029use compos_aidl_interface::aidl::com::android::compos::ICompOsService::{
30 BnCompOsService, CompilationMode::CompilationMode, ICompOsService,
Victor Hsieh272aa242021-02-01 14:19:20 -080031};
Alan Stokes6542fdd2022-02-17 15:21:46 +000032use compos_aidl_interface::binder::{BinderFeatures, Interface, Result as BinderResult, Strong};
33use compos_common::binder::to_binder_result;
Alan Stokes46a1dff2021-12-14 10:56:05 +000034use compos_common::odrefresh::ODREFRESH_PATH;
Victor Hsieh272aa242021-02-01 14:19:20 -080035
Victor Hsiehebb1d902021-08-06 13:00:18 -070036const AUTHFS_SERVICE_NAME: &str = "authfs_service";
Alan Stokes9e2c5d52021-07-21 11:29:10 +010037
Victor Hsieha64194b2021-08-06 17:43:36 -070038/// Constructs a binder object that implements ICompOsService.
Victor Hsieh9ebf7ee2021-09-03 16:14:14 -070039pub fn new_binder() -> Result<Strong<dyn ICompOsService>> {
Alan Stokes6542fdd2022-02-17 15:21:46 +000040 let service = CompOsService { odrefresh_path: PathBuf::from(ODREFRESH_PATH) };
Victor Hsieha64194b2021-08-06 17:43:36 -070041 Ok(BnCompOsService::new_binder(service, BinderFeatures::default()))
Alan Stokes9e2c5d52021-07-21 11:29:10 +010042}
43
Victor Hsieha64194b2021-08-06 17:43:36 -070044struct CompOsService {
Victor Hsiehf9968692021-11-18 11:34:39 -080045 odrefresh_path: PathBuf,
Victor Hsieh272aa242021-02-01 14:19:20 -080046}
47
Victor Hsieha64194b2021-08-06 17:43:36 -070048impl Interface for CompOsService {}
Victor Hsieh272aa242021-02-01 14:19:20 -080049
Victor Hsieha64194b2021-08-06 17:43:36 -070050impl ICompOsService for CompOsService {
Victor Hsiehf9968692021-11-18 11:34:39 -080051 fn odrefresh(
52 &self,
Alan Stokes2d2e4db2022-01-28 16:41:52 +000053 compilation_mode: CompilationMode,
Victor Hsiehf9968692021-11-18 11:34:39 -080054 system_dir_fd: i32,
55 output_dir_fd: i32,
Alan Stokes9646db92021-12-14 13:22:33 +000056 staging_dir_fd: i32,
57 target_dir_name: &str,
Victor Hsiehf9968692021-11-18 11:34:39 -080058 zygote_arch: &str,
Victor Hsieh9bfbc5f2021-12-16 11:45:10 -080059 system_server_compiler_filter: &str,
Alan Stokes9646db92021-12-14 13:22:33 +000060 ) -> BinderResult<i8> {
Alan Stokes126fd512021-12-16 15:00:01 +000061 let context = to_binder_result(OdrefreshContext::new(
Alan Stokes2d2e4db2022-01-28 16:41:52 +000062 compilation_mode,
Victor Hsiehf9968692021-11-18 11:34:39 -080063 system_dir_fd,
64 output_dir_fd,
Alan Stokes9646db92021-12-14 13:22:33 +000065 staging_dir_fd,
Alan Stokes46a1dff2021-12-14 10:56:05 +000066 target_dir_name,
Victor Hsiehf9968692021-11-18 11:34:39 -080067 zygote_arch,
Victor Hsieh9bfbc5f2021-12-16 11:45:10 -080068 system_server_compiler_filter,
Alan Stokes126fd512021-12-16 15:00:01 +000069 ))?;
Alan Stokes46a1dff2021-12-14 10:56:05 +000070
Alan Stokes6542fdd2022-02-17 15:21:46 +000071 let authfs_service = authfs_aidl_interface::binder::get_interface(AUTHFS_SERVICE_NAME)?;
Alan Stokes126fd512021-12-16 15:00:01 +000072 let exit_code = to_binder_result(
Victor Hsiehec38ae22022-02-10 00:06:26 +000073 odrefresh(&self.odrefresh_path, context, authfs_service, |output_dir| {
74 // authfs only shows us the files we created, so it's ok to just sign everything
75 // under the output directory.
76 let mut artifact_signer = ArtifactSigner::new(&output_dir);
77 add_artifacts(&output_dir, &mut artifact_signer)?;
78
Alan Stokes16fb8552022-02-10 15:07:27 +000079 artifact_signer.write_info_and_signature(&output_dir.join("compos.info"))
Victor Hsiehec38ae22022-02-10 00:06:26 +000080 })
81 .context("odrefresh failed"),
Alan Stokes126fd512021-12-16 15:00:01 +000082 )?;
Alan Stokes46a1dff2021-12-14 10:56:05 +000083 Ok(exit_code as i8)
Victor Hsiehf9968692021-11-18 11:34:39 -080084 }
85
Alan Stokes16fb8552022-02-10 15:07:27 +000086 fn getPublicKey(&self) -> BinderResult<Vec<u8>> {
87 to_binder_result(compos_key::get_public_key())
88 }
Victor Hsieh272aa242021-02-01 14:19:20 -080089}
Victor Hsiehebb1d902021-08-06 13:00:18 -070090
Victor Hsiehec38ae22022-02-10 00:06:26 +000091fn add_artifacts(target_dir: &Path, artifact_signer: &mut ArtifactSigner) -> Result<()> {
92 for entry in
93 read_dir(&target_dir).with_context(|| format!("Traversing {}", target_dir.display()))?
94 {
95 let entry = entry?;
96 let file_type = entry.file_type()?;
97 if file_type.is_dir() {
98 add_artifacts(&entry.path(), artifact_signer)?;
99 } else if file_type.is_file() {
100 artifact_signer.add_artifact(&entry.path())?;
101 } else {
102 // authfs shouldn't create anything else, but just in case
103 bail!("Unexpected file type in artifacts: {:?}", entry);
104 }
105 }
106 Ok(())
107}