diff options
author | Yi Kong <yikong@google.com> | 2021-11-24 00:19:30 +0800 |
---|---|---|
committer | Yi Kong <yikong@google.com> | 2021-11-30 06:33:05 +0000 |
commit | c0e6b3f2b147fb889f7e8af2db21924622d8b621 (patch) | |
tree | e1df952ae97f6097ae4ec056c5b1169adb419753 | |
parent | 7735a98446856eff889c108cd626bb279d616866 (diff) | |
download | extras-c0e6b3f2b147fb889f7e8af2db21924622d8b621.tar.gz |
profcollectd: Limit storage space used
This prevents profcollect from exhausting all the device storage. We don't
count space used by packed reports or processed data since they are much
smaller (~30KB per trace).
Test: manual
Bug: 207426233
Bug: 207417653
Change-Id: I54c77bf7d5af57b5ab8d3a696b486c951fe79aa8
Merged-In: I54c77bf7d5af57b5ab8d3a696b486c951fe79aa8
-rw-r--r-- | profcollectd/libprofcollectd/config.rs | 6 | ||||
-rw-r--r-- | profcollectd/libprofcollectd/scheduler.rs | 36 |
2 files changed, 36 insertions, 6 deletions
diff --git a/profcollectd/libprofcollectd/config.rs b/profcollectd/libprofcollectd/config.rs index e8afb37f..ea1a67c8 100644 --- a/profcollectd/libprofcollectd/config.rs +++ b/profcollectd/libprofcollectd/config.rs @@ -56,6 +56,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 +72,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, + )?, }) } } 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) + }) +} |