xref: /aosp_15_r20/system/core/init/libprefetch/prefetch/src/args.rs (revision 00c7fec1bb09f3284aad6a6f96d2f63dfc3650ad)
1 // Copyright (C) 2024 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 pub(crate) static DEFAULT_IO_DEPTH: u16 = 2;
16 pub(crate) static DEFAULT_MAX_FDS: u16 = 128;
17 pub(crate) static DEFAULT_EXIT_ON_ERROR: bool = false;
18 
19 mod args_argh;
20 use args_argh as args_internal;
21 
22 use std::path::Path;
23 use std::path::PathBuf;
24 use std::process::exit;
25 
26 pub use args_internal::OutputFormat;
27 pub use args_internal::ReplayArgs;
28 #[cfg(target_os = "android")]
29 pub use args_internal::StartArgs;
30 pub use args_internal::TracerType;
31 pub use args_internal::{DumpArgs, MainArgs, RecordArgs, SubCommands};
32 use serde::Deserialize;
33 use serde::Serialize;
34 
35 use crate::Error;
36 use log::error;
37 
38 // Deserialized form of the config file
39 #[derive(Clone, Debug, Default, Deserialize, Serialize, Eq, PartialEq)]
40 pub struct ConfigFile {
41     // Files to be excluded in prefetch. These files might have been
42     // added in the record file while recording,but we do not want to
43     // replay these files. These can be two types of files:
44     // 1) installation-specific files (e.g. files in /data) and
45     // 2) large files which we do not want to load in replay (e.g. APK files).
46     pub files_to_exclude_regex: Vec<String>,
47     // Files that are not in the record file, but need to be loaded during replay
48     pub additional_replay_files: Vec<String>,
49 }
50 
verify_and_fix(args: &mut MainArgs) -> Result<(), Error>51 fn verify_and_fix(args: &mut MainArgs) -> Result<(), Error> {
52     match &mut args.nested {
53         SubCommands::Record(arg) => {
54             if arg.debug && arg.int_path.is_none() {
55                 arg.int_path = Some(PathBuf::from(format!("{}.int", arg.path.to_str().unwrap())));
56             }
57 
58             if let Some(p) = &arg.int_path {
59                 ensure_path_doesnt_exist(p)?;
60             }
61         }
62         SubCommands::Replay(arg) => {
63             ensure_path_exists(&arg.path)?;
64             if !arg.config_path.as_os_str().is_empty() {
65                 ensure_path_exists(&arg.config_path)?;
66             }
67         }
68         SubCommands::Dump(arg) => {
69             ensure_path_exists(&arg.path)?;
70         }
71         #[cfg(target_os = "android")]
72         SubCommands::Start(_arg) => return Ok(()),
73     }
74     Ok(())
75 }
76 
77 /// Returns error if the given path at `p` exist.
ensure_path_doesnt_exist(p: &Path) -> Result<(), Error>78 pub(crate) fn ensure_path_doesnt_exist(p: &Path) -> Result<(), Error> {
79     if p.exists() {
80         Err(Error::InvalidArgs {
81             arg_name: "path".to_string(),
82             arg_value: p.display().to_string(),
83             error: "Path already exists".to_string(),
84         })
85     } else {
86         Ok(())
87     }
88 }
89 
90 /// Returns error if the given path at `p` doesn't exist.
ensure_path_exists(p: &Path) -> Result<(), Error>91 pub(crate) fn ensure_path_exists(p: &Path) -> Result<(), Error> {
92     if p.is_file() {
93         Ok(())
94     } else {
95         Err(Error::InvalidArgs {
96             arg_name: "path".to_string(),
97             arg_value: p.display().to_string(),
98             error: "Path does not exist".to_string(),
99         })
100     }
101 }
102 
103 /// Builds `MainArgs` from command line arguments. On error prints error/help message
104 /// and exits.
args_from_env() -> MainArgs105 pub fn args_from_env() -> MainArgs {
106     let mut args = args_internal::args_from_env();
107     if let Err(e) = verify_and_fix(&mut args) {
108         error!("failed to verify args: {}", e);
109         exit(1);
110     }
111     args
112 }
113