diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-12-01 00:09:23 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2021-12-01 00:09:23 +0000 |
commit | d4fe8c9ec29cac309e8f3dfc47d064f7c433ce10 (patch) | |
tree | 65239b8e4ece24724d798a698406673fffb3e88a | |
parent | 24cdacf479c95cb4a8ae8e8686f40cc7be2e4249 (diff) | |
parent | 970ba98ee22d24d42c5f1ee05aa8ec25fe90ea36 (diff) | |
download | extras-d4fe8c9ec29cac309e8f3dfc47d064f7c433ce10.tar.gz |
Snap for 7956453 from 970ba98ee22d24d42c5f1ee05aa8ec25fe90ea36 to sc-d2-release
Change-Id: I8934ca003c18c5c6cfda22892765e26eaa17ca09
-rw-r--r-- | profcollectd/libprofcollectd/config.rs | 25 | ||||
-rw-r--r-- | profcollectd/libprofcollectd/lib.rs | 6 | ||||
-rw-r--r-- | profcollectd/libprofcollectd/scheduler.rs | 36 | ||||
-rw-r--r-- | profcollectd/libprofcollectd/service.rs | 13 | ||||
-rw-r--r-- | profcollectd/profcollectctl.rs | 7 | ||||
-rw-r--r-- | profcollectd/profcollectd.rc | 12 |
6 files changed, 78 insertions, 21 deletions
diff --git a/profcollectd/libprofcollectd/config.rs b/profcollectd/libprofcollectd/config.rs index e8afb37f..902b5b5e 100644 --- a/profcollectd/libprofcollectd/config.rs +++ b/profcollectd/libprofcollectd/config.rs @@ -22,6 +22,7 @@ use macaddr::MacAddr6; use rand::Rng; use serde::{Deserialize, Serialize}; use std::error::Error; +use std::fs::{read_dir, remove_file}; use std::path::Path; use std::str::FromStr; use std::time::Duration; @@ -31,6 +32,7 @@ const PROFCOLLECT_NODE_ID_PROPERTY: &str = "persist.profcollectd.node_id"; pub const REPORT_RETENTION_SECS: u64 = 14 * 24 * 60 * 60; // 14 days. +// Static configs that cannot be changed. lazy_static! { pub static ref TRACE_OUTPUT_DIR: &'static Path = Path::new("/data/misc/profcollectd/trace/"); pub static ref PROFILE_OUTPUT_DIR: &'static Path = Path::new("/data/misc/profcollectd/output/"); @@ -42,6 +44,7 @@ lazy_static! { Path::new("/data/misc/profcollectd/output/config.json"); } +/// Dynamic configs, stored in config.json. #[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)] pub struct Config { /// Version of config file scheme, always equals to 1. @@ -56,6 +59,8 @@ pub struct Config { pub sampling_period: Duration, /// An optional filter to limit which binaries to or not to profile. pub binary_filter: String, + /// Maximum size of the trace directory. + pub max_trace_limit: u64, } impl Config { @@ -70,6 +75,10 @@ impl Config { )?), sampling_period: Duration::from_millis(get_device_config("sampling_period", 500)?), binary_filter: get_device_config("binary_filter", "".to_string())?, + max_trace_limit: get_device_config( + "max_trace_limit", + /* 512MB */ 512 * 1024 * 1024, + )?, }) } } @@ -138,3 +147,19 @@ fn generate_random_node_id() -> MacAddr6 { node_id[0] |= 0x1; MacAddr6::from(node_id) } + +pub fn clear_data() -> Result<()> { + fn remove_files(path: &Path) -> Result<()> { + read_dir(path)? + .filter_map(|e| e.ok()) + .map(|e| e.path()) + .filter(|e| e.is_file()) + .try_for_each(remove_file)?; + Ok(()) + } + + remove_files(&TRACE_OUTPUT_DIR)?; + remove_files(&PROFILE_OUTPUT_DIR)?; + remove_files(&REPORT_OUTPUT_DIR)?; + Ok(()) +} diff --git a/profcollectd/libprofcollectd/lib.rs b/profcollectd/libprofcollectd/lib.rs index f417bd8c..5892e259 100644 --- a/profcollectd/libprofcollectd/lib.rs +++ b/profcollectd/libprofcollectd/lib.rs @@ -91,6 +91,12 @@ pub fn report() -> Result<String> { Ok(get_profcollectd_service()?.report()?) } +/// Clear all local data. +pub fn reset() -> Result<()> { + config::clear_data()?; + Ok(()) +} + /// Inits logging for Android pub fn init_logging() { let min_log_level = if cfg!(feature = "test") { log::Level::Info } else { log::Level::Error }; diff --git a/profcollectd/libprofcollectd/scheduler.rs b/profcollectd/libprofcollectd/scheduler.rs index cfd0381f..b83bc457 100644 --- a/profcollectd/libprofcollectd/scheduler.rs +++ b/profcollectd/libprofcollectd/scheduler.rs @@ -16,6 +16,8 @@ //! ProfCollect tracing scheduler. +use std::fs; +use std::path::Path; use std::sync::mpsc::{sync_channel, SyncSender}; use std::sync::Arc; use std::sync::Mutex; @@ -59,11 +61,13 @@ impl Scheduler { Ok(_) => break, Err(_) => { // Did not receive a termination signal, initiate trace event. - trace_provider.lock().unwrap().trace( - &TRACE_OUTPUT_DIR, - "periodic", - &config.sampling_period, - ); + if check_space_limit(*TRACE_OUTPUT_DIR, &config).unwrap() { + trace_provider.lock().unwrap().trace( + &TRACE_OUTPUT_DIR, + "periodic", + &config.sampling_period, + ); + } } } } @@ -83,7 +87,9 @@ impl Scheduler { pub fn one_shot(&self, config: &Config, tag: &str) -> Result<()> { let trace_provider = self.trace_provider.clone(); - trace_provider.lock().unwrap().trace(&TRACE_OUTPUT_DIR, tag, &config.sampling_period); + if check_space_limit(*TRACE_OUTPUT_DIR, config)? { + trace_provider.lock().unwrap().trace(&TRACE_OUTPUT_DIR, tag, &config.sampling_period); + } Ok(()) } @@ -106,3 +112,21 @@ impl Scheduler { self.trace_provider.lock().unwrap().get_name() } } + +/// Run if space usage is under limit. +fn check_space_limit(path: &Path, config: &Config) -> Result<bool> { + let ret = dir_size(path)? <= config.max_trace_limit; + if !ret { + log::error!("trace storage exhausted."); + } + Ok(ret) +} + +/// Returns the size of a directory, non-recursive. +fn dir_size(path: &Path) -> Result<u64> { + fs::read_dir(path)?.try_fold(0, |acc, file| { + let metadata = file?.metadata()?; + let size = if metadata.is_file() { metadata.len() } else { 0 }; + Ok(acc + size) + }) +} diff --git a/profcollectd/libprofcollectd/service.rs b/profcollectd/libprofcollectd/service.rs index 04f30f89..a7fdce73 100644 --- a/profcollectd/libprofcollectd/service.rs +++ b/profcollectd/libprofcollectd/service.rs @@ -21,15 +21,15 @@ use binder::public_api::Result as BinderResult; use binder::Status; use profcollectd_aidl_interface::aidl::com::android::server::profcollect::IProfCollectd::IProfCollectd; use std::ffi::CString; -use std::fs::{copy, create_dir, read_dir, read_to_string, remove_dir_all, remove_file, write}; +use std::fs::{copy, read_dir, read_to_string, remove_file, write}; use std::path::PathBuf; use std::str::FromStr; use std::sync::{Mutex, MutexGuard}; use std::time::Duration; use crate::config::{ - Config, BETTERBUG_CACHE_DIR_PREFIX, BETTERBUG_CACHE_DIR_SUFFIX, CONFIG_FILE, - PROFILE_OUTPUT_DIR, REPORT_OUTPUT_DIR, REPORT_RETENTION_SECS, TRACE_OUTPUT_DIR, + clear_data, Config, BETTERBUG_CACHE_DIR_PREFIX, BETTERBUG_CACHE_DIR_SUFFIX, CONFIG_FILE, + PROFILE_OUTPUT_DIR, REPORT_OUTPUT_DIR, REPORT_RETENTION_SECS, }; use crate::report::{get_report_ts, pack_report}; use crate::scheduler::Scheduler; @@ -147,11 +147,8 @@ impl ProfcollectdBinderService { .is_none(); if config_changed { - log::info!("Config change detected, clearing traces."); - remove_dir_all(*PROFILE_OUTPUT_DIR)?; - remove_dir_all(*TRACE_OUTPUT_DIR)?; - create_dir(*PROFILE_OUTPUT_DIR)?; - create_dir(*TRACE_OUTPUT_DIR)?; + log::info!("Config change detected, resetting profcollect."); + clear_data()?; write(*CONFIG_FILE, &new_config.to_string())?; } diff --git a/profcollectd/profcollectctl.rs b/profcollectd/profcollectctl.rs index c825f550..6778465e 100644 --- a/profcollectd/profcollectctl.rs +++ b/profcollectd/profcollectctl.rs @@ -29,8 +29,9 @@ command: stop Terminate periodic collection. once Request an one-off trace. process Convert traces to perf profiles. - report Create a report containing all profiles. reconfig Refresh configuration. + report Create a report containing all profiles. + reset Clear all local data. help Print this message. "#; @@ -65,6 +66,10 @@ fn main() -> Result<()> { let path = libprofcollectd::report().context("Failed to create profile report.")?; println!("Report created at: {}", &path); } + "reset" => { + libprofcollectd::reset().context("Failed to reset.")?; + println!("Reset done."); + } "help" => println!("{}", &HELP_MSG), arg => bail!("Unknown argument: {}\n{}", &arg, &HELP_MSG), } diff --git a/profcollectd/profcollectd.rc b/profcollectd/profcollectd.rc index 1100bd2e..b92fccba 100644 --- a/profcollectd/profcollectd.rc +++ b/profcollectd/profcollectd.rc @@ -6,15 +6,15 @@ service profcollectd /system/bin/profcollectd group root wakelock writepid /dev/cpuset/system-background/tasks -on property:persist.device_config.profcollect_native_boot.enabled=true - start profcollectd - -on property:persist.profcollectd.enabled_override=true - start profcollectd - on post-fs-data # Create directory for profcollectd. mkdir /data/misc/profcollectd 0770 shell shell mkdir /data/misc/profcollectd/trace 0770 shell shell mkdir /data/misc/profcollectd/output 0770 shell shell mkdir /data/misc/profcollectd/report 0770 shell shell + +on boot && property:persist.device_config.profcollect_native_boot.enabled=true + start profcollectd + +on boot && property:persist.device_config.profcollect_native_boot.enabled= + exec_background - root shell -- /system/bin/profcollectctl reset |