1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2022 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker
5*bb4ee6a4SAndroid Build Coastguard Worker //! Contains shared code between the broker & its children, specifically any IPC messages or common
6*bb4ee6a4SAndroid Build Coastguard Worker //! bootstrapping code.
7*bb4ee6a4SAndroid Build Coastguard Worker
8*bb4ee6a4SAndroid Build Coastguard Worker use std::fs::File;
9*bb4ee6a4SAndroid Build Coastguard Worker use std::fs::OpenOptions;
10*bb4ee6a4SAndroid Build Coastguard Worker use std::path::PathBuf;
11*bb4ee6a4SAndroid Build Coastguard Worker
12*bb4ee6a4SAndroid Build Coastguard Worker use anyhow::Context;
13*bb4ee6a4SAndroid Build Coastguard Worker use base::enable_high_res_timers;
14*bb4ee6a4SAndroid Build Coastguard Worker use base::syslog;
15*bb4ee6a4SAndroid Build Coastguard Worker use base::syslog::LogArgs;
16*bb4ee6a4SAndroid Build Coastguard Worker use base::EnabledHighResTimer;
17*bb4ee6a4SAndroid Build Coastguard Worker use base::FromRawDescriptor;
18*bb4ee6a4SAndroid Build Coastguard Worker use base::IntoRawDescriptor;
19*bb4ee6a4SAndroid Build Coastguard Worker use base::SafeDescriptor;
20*bb4ee6a4SAndroid Build Coastguard Worker use base::SendTube;
21*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "process-invariants")]
22*bb4ee6a4SAndroid Build Coastguard Worker pub use broker_ipc_product::init_broker_process_invariants;
23*bb4ee6a4SAndroid Build Coastguard Worker use broker_ipc_product::init_child_crash_reporting;
24*bb4ee6a4SAndroid Build Coastguard Worker use broker_ipc_product::product_child_setup;
25*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "process-invariants")]
26*bb4ee6a4SAndroid Build Coastguard Worker pub use broker_ipc_product::EmulatorProcessInvariants;
27*bb4ee6a4SAndroid Build Coastguard Worker use broker_ipc_product::ProductAttributes;
28*bb4ee6a4SAndroid Build Coastguard Worker use serde::Deserialize;
29*bb4ee6a4SAndroid Build Coastguard Worker use serde::Serialize;
30*bb4ee6a4SAndroid Build Coastguard Worker
31*bb4ee6a4SAndroid Build Coastguard Worker /// Arguments that are common to all devices & helper processes.
32*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Serialize, Deserialize)]
33*bb4ee6a4SAndroid Build Coastguard Worker pub struct CommonChildStartupArgs {
34*bb4ee6a4SAndroid Build Coastguard Worker log_args: LogArgs,
35*bb4ee6a4SAndroid Build Coastguard Worker syslog_file: Option<SafeDescriptor>,
36*bb4ee6a4SAndroid Build Coastguard Worker metrics_tube: Option<SendTube>,
37*bb4ee6a4SAndroid Build Coastguard Worker product_attrs: ProductAttributes,
38*bb4ee6a4SAndroid Build Coastguard Worker }
39*bb4ee6a4SAndroid Build Coastguard Worker
40*bb4ee6a4SAndroid Build Coastguard Worker impl CommonChildStartupArgs {
41*bb4ee6a4SAndroid Build Coastguard Worker #[allow(clippy::new_without_default)]
new( log_args: &LogArgs, syslog_path: Option<PathBuf>, #[cfg(feature = "crash-report")] _crash_attrs: crash_report::CrashReportAttributes, #[cfg(feature = "process-invariants")] _process_invariants: EmulatorProcessInvariants, metrics_tube: Option<SendTube>, ) -> anyhow::Result<Self>42*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(
43*bb4ee6a4SAndroid Build Coastguard Worker log_args: &LogArgs,
44*bb4ee6a4SAndroid Build Coastguard Worker syslog_path: Option<PathBuf>,
45*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "crash-report")] _crash_attrs: crash_report::CrashReportAttributes,
46*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "process-invariants")] _process_invariants: EmulatorProcessInvariants,
47*bb4ee6a4SAndroid Build Coastguard Worker metrics_tube: Option<SendTube>,
48*bb4ee6a4SAndroid Build Coastguard Worker ) -> anyhow::Result<Self> {
49*bb4ee6a4SAndroid Build Coastguard Worker Ok(Self {
50*bb4ee6a4SAndroid Build Coastguard Worker log_args: log_args.clone(),
51*bb4ee6a4SAndroid Build Coastguard Worker product_attrs: ProductAttributes {},
52*bb4ee6a4SAndroid Build Coastguard Worker metrics_tube,
53*bb4ee6a4SAndroid Build Coastguard Worker syslog_file: log_file_from_path(syslog_path)?,
54*bb4ee6a4SAndroid Build Coastguard Worker })
55*bb4ee6a4SAndroid Build Coastguard Worker }
56*bb4ee6a4SAndroid Build Coastguard Worker }
57*bb4ee6a4SAndroid Build Coastguard Worker
58*bb4ee6a4SAndroid Build Coastguard Worker pub struct ChildLifecycleCleanup {
59*bb4ee6a4SAndroid Build Coastguard Worker _timer_resolution: Box<dyn EnabledHighResTimer>,
60*bb4ee6a4SAndroid Build Coastguard Worker }
61*bb4ee6a4SAndroid Build Coastguard Worker
62*bb4ee6a4SAndroid Build Coastguard Worker /// Initializes crash reporting, metrics, logging, and product specific features
63*bb4ee6a4SAndroid Build Coastguard Worker /// for a process.
64*bb4ee6a4SAndroid Build Coastguard Worker ///
65*bb4ee6a4SAndroid Build Coastguard Worker /// Returns a value that should be dropped when the process exits.
common_child_setup(args: CommonChildStartupArgs) -> anyhow::Result<ChildLifecycleCleanup>66*bb4ee6a4SAndroid Build Coastguard Worker pub fn common_child_setup(args: CommonChildStartupArgs) -> anyhow::Result<ChildLifecycleCleanup> {
67*bb4ee6a4SAndroid Build Coastguard Worker // Logging must initialize first in case there are other startup errors.
68*bb4ee6a4SAndroid Build Coastguard Worker let mut cfg = syslog::LogConfig {
69*bb4ee6a4SAndroid Build Coastguard Worker log_args: args.log_args,
70*bb4ee6a4SAndroid Build Coastguard Worker ..Default::default()
71*bb4ee6a4SAndroid Build Coastguard Worker };
72*bb4ee6a4SAndroid Build Coastguard Worker if let Some(log_file_descriptor) = args.syslog_file {
73*bb4ee6a4SAndroid Build Coastguard Worker let log_file =
74*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
75*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we are taking ownership of a SafeDescriptor.
76*bb4ee6a4SAndroid Build Coastguard Worker unsafe { File::from_raw_descriptor(log_file_descriptor.into_raw_descriptor()) };
77*bb4ee6a4SAndroid Build Coastguard Worker cfg.pipe = Some(Box::new(log_file));
78*bb4ee6a4SAndroid Build Coastguard Worker cfg.log_args.stderr = false;
79*bb4ee6a4SAndroid Build Coastguard Worker } else {
80*bb4ee6a4SAndroid Build Coastguard Worker cfg.log_args.stderr = true;
81*bb4ee6a4SAndroid Build Coastguard Worker }
82*bb4ee6a4SAndroid Build Coastguard Worker syslog::init_with(cfg)?;
83*bb4ee6a4SAndroid Build Coastguard Worker
84*bb4ee6a4SAndroid Build Coastguard Worker // Crash reporting should start as early as possible, in case other startup tasks fail.
85*bb4ee6a4SAndroid Build Coastguard Worker init_child_crash_reporting(&args.product_attrs);
86*bb4ee6a4SAndroid Build Coastguard Worker
87*bb4ee6a4SAndroid Build Coastguard Worker // Initialize anything product specific.
88*bb4ee6a4SAndroid Build Coastguard Worker product_child_setup(&args.product_attrs)?;
89*bb4ee6a4SAndroid Build Coastguard Worker
90*bb4ee6a4SAndroid Build Coastguard Worker if let Some(metrics_tube) = args.metrics_tube {
91*bb4ee6a4SAndroid Build Coastguard Worker metrics::initialize(metrics_tube);
92*bb4ee6a4SAndroid Build Coastguard Worker }
93*bb4ee6a4SAndroid Build Coastguard Worker
94*bb4ee6a4SAndroid Build Coastguard Worker let timer_resolution = enable_high_res_timers().context("failed to enable high res timer")?;
95*bb4ee6a4SAndroid Build Coastguard Worker
96*bb4ee6a4SAndroid Build Coastguard Worker Ok(ChildLifecycleCleanup {
97*bb4ee6a4SAndroid Build Coastguard Worker _timer_resolution: timer_resolution,
98*bb4ee6a4SAndroid Build Coastguard Worker })
99*bb4ee6a4SAndroid Build Coastguard Worker }
100*bb4ee6a4SAndroid Build Coastguard Worker
log_file_from_path(path: Option<PathBuf>) -> anyhow::Result<Option<SafeDescriptor>>101*bb4ee6a4SAndroid Build Coastguard Worker pub(crate) fn log_file_from_path(path: Option<PathBuf>) -> anyhow::Result<Option<SafeDescriptor>> {
102*bb4ee6a4SAndroid Build Coastguard Worker Ok(match path {
103*bb4ee6a4SAndroid Build Coastguard Worker Some(path) => Some(SafeDescriptor::from(
104*bb4ee6a4SAndroid Build Coastguard Worker OpenOptions::new()
105*bb4ee6a4SAndroid Build Coastguard Worker .append(true)
106*bb4ee6a4SAndroid Build Coastguard Worker .create(true)
107*bb4ee6a4SAndroid Build Coastguard Worker .open(path.as_path())
108*bb4ee6a4SAndroid Build Coastguard Worker .context(format!("failed to open log file {}", path.display()))?,
109*bb4ee6a4SAndroid Build Coastguard Worker )),
110*bb4ee6a4SAndroid Build Coastguard Worker None => None,
111*bb4ee6a4SAndroid Build Coastguard Worker })
112*bb4ee6a4SAndroid Build Coastguard Worker }
113