blob: 9f121321cd3cef05669cae80047571bd9810d6f8 [file] [log] [blame]
Alan Stokes9e2c5d52021-07-21 11:29:10 +01001/*
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
17//! A tool to start a standalone compsvc server, either in the host using Binder or in a VM using
18//! RPC binder over vsock.
19//!
20//! Example:
21//! $ compsvc /system/bin/sleep
22
23mod common;
24mod compsvc;
Alan Stokes7ec4e7f2021-07-21 11:29:10 +010025mod signer;
Alan Stokes9e2c5d52021-07-21 11:29:10 +010026
27use crate::common::{SERVICE_NAME, VSOCK_PORT};
28use anyhow::{bail, Context, Result};
29use binder::unstable_api::AsNative;
30use compos_aidl_interface::binder::{add_service, ProcessState};
31use log::debug;
32
33struct Config {
34 task_bin: String,
35 rpc_binder: bool,
36 debuggable: bool,
37}
38
39fn parse_args() -> Result<Config> {
40 #[rustfmt::skip]
41 let matches = clap::App::new("compsvc")
42 .arg(clap::Arg::with_name("debug")
43 .long("debug"))
44 .arg(clap::Arg::with_name("task_bin")
45 .required(true))
46 .arg(clap::Arg::with_name("rpc_binder")
47 .long("rpc-binder"))
48 .get_matches();
49
50 Ok(Config {
51 task_bin: matches.value_of("task_bin").unwrap().to_string(),
52 rpc_binder: matches.is_present("rpc_binder"),
53 debuggable: matches.is_present("debug"),
54 })
55}
56
57fn main() -> Result<()> {
58 android_logger::init_once(
59 android_logger::Config::default().with_tag("compsvc").with_min_level(log::Level::Debug),
60 );
61
62 let config = parse_args()?;
Alan Stokes7ec4e7f2021-07-21 11:29:10 +010063 let mut service = compsvc::new_binder(config.task_bin, config.debuggable, None).as_binder();
Alan Stokes9e2c5d52021-07-21 11:29:10 +010064 if config.rpc_binder {
65 debug!("compsvc is starting as a rpc service.");
66 // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
67 // Plus the binder objects are threadsafe.
68 let retval = unsafe {
69 binder_rpc_unstable_bindgen::RunRpcServer(
70 service.as_native_mut() as *mut binder_rpc_unstable_bindgen::AIBinder,
71 VSOCK_PORT,
72 )
73 };
74 if retval {
75 debug!("RPC server has shut down gracefully");
76 Ok(())
77 } else {
78 bail!("Premature termination of RPC server");
79 }
80 } else {
81 ProcessState::start_thread_pool();
82 debug!("compsvc is starting as a local service.");
83 add_service(SERVICE_NAME, service)
84 .with_context(|| format!("Failed to register service {}", SERVICE_NAME))?;
85 ProcessState::join_thread_pool();
86 bail!("Unexpected exit after join_thread_pool")
87 }
88}