summaryrefslogtreecommitdiff
path: root/profcollectd
diff options
context:
space:
mode:
authorYi Kong <yikong@google.com>2021-07-20 16:55:39 +0800
committerYi Kong <yikong@google.com>2021-07-20 09:15:02 +0000
commit8dffc1208417a18870b33ce92c03a8f77da8dbee (patch)
tree01a9ef12775d5a6efd115cac5773bfe45787decf /profcollectd
parentf7180ec6c5369eca8c4924a7b8b341de6076bb2d (diff)
downloadextras-8dffc1208417a18870b33ce92c03a8f77da8dbee.tar.gz
profcollectd: Remove reports past retention period
Manually generated profcollect reports (through `profcollectctl report`) and reports that failed to upload for whatever reason need to be cleaned up periodically, to save disk space as well as to minimise privacy leak surface. Test: manual Bug: 178561556 Change-Id: I54f09d1738f7b3c3b763251af83133bda5c214ae
Diffstat (limited to 'profcollectd')
-rw-r--r--profcollectd/libprofcollectd/config.rs2
-rw-r--r--profcollectd/libprofcollectd/report.rs11
-rw-r--r--profcollectd/libprofcollectd/service.rs31
3 files changed, 40 insertions, 4 deletions
diff --git a/profcollectd/libprofcollectd/config.rs b/profcollectd/libprofcollectd/config.rs
index c3ab45cf..11098fe1 100644
--- a/profcollectd/libprofcollectd/config.rs
+++ b/profcollectd/libprofcollectd/config.rs
@@ -29,6 +29,8 @@ use std::time::Duration;
const PROFCOLLECT_CONFIG_NAMESPACE: &str = "profcollect_native_boot";
const PROFCOLLECT_NODE_ID_PROPERTY: &str = "persist.profcollectd.node_id";
+pub const REPORT_RETENTION_SECS: u64 = 14 * 24 * 60 * 60; // 14 days.
+
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/");
diff --git a/profcollectd/libprofcollectd/report.rs b/profcollectd/libprofcollectd/report.rs
index c37993b7..a67d500b 100644
--- a/profcollectd/libprofcollectd/report.rs
+++ b/profcollectd/libprofcollectd/report.rs
@@ -23,7 +23,7 @@ use std::fs::{self, File, Permissions};
use std::io::{Read, Write};
use std::os::unix::fs::PermissionsExt;
use std::path::{Path, PathBuf};
-use std::time::SystemTime;
+use std::time::{Duration, SystemTime};
use uuid::v1::{Context, Timestamp};
use uuid::Uuid;
use zip::write::FileOptions;
@@ -82,3 +82,12 @@ fn get_report_filename(node_id: &MacAddr6) -> Result<String> {
let uuid = Uuid::new_v1(ts, &node_id.as_bytes())?;
Ok(uuid.to_string())
}
+
+/// Get report creation timestamp through its filename (version 1 UUID).
+pub fn get_report_ts(filename: &str) -> Result<SystemTime> {
+ let uuid_ts = Uuid::parse_str(filename)?
+ .to_timestamp()
+ .ok_or_else(|| anyhow!("filename is not a valid V1 UUID."))?
+ .to_unix();
+ Ok(SystemTime::UNIX_EPOCH + Duration::new(uuid_ts.0, uuid_ts.1))
+}
diff --git a/profcollectd/libprofcollectd/service.rs b/profcollectd/libprofcollectd/service.rs
index 0b9cca1e..04f30f89 100644
--- a/profcollectd/libprofcollectd/service.rs
+++ b/profcollectd/libprofcollectd/service.rs
@@ -21,16 +21,17 @@ 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_to_string, remove_dir_all, remove_file, write};
+use std::fs::{copy, create_dir, read_dir, read_to_string, remove_dir_all, 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, TRACE_OUTPUT_DIR,
+ PROFILE_OUTPUT_DIR, REPORT_OUTPUT_DIR, REPORT_RETENTION_SECS, TRACE_OUTPUT_DIR,
};
-use crate::report::pack_report;
+use crate::report::{get_report_ts, pack_report};
use crate::scheduler::Scheduler;
fn err_to_binder_status(msg: Error) -> Status {
@@ -155,6 +156,30 @@ impl ProfcollectdBinderService {
write(*CONFIG_FILE, &new_config.to_string())?;
}
+ // Clear profile reports out of rentention period.
+ for report in read_dir(*REPORT_OUTPUT_DIR)? {
+ let report = report?.path();
+ let report_name = report
+ .file_stem()
+ .and_then(|f| f.to_str())
+ .ok_or_else(|| anyhow!("Malformed path {}", report.display()))?;
+ let report_ts = get_report_ts(report_name);
+ if let Err(e) = report_ts {
+ log::error!(
+ "Cannot decode creation timestamp for report {}, caused by {}, deleting",
+ report_name,
+ e
+ );
+ remove_file(report)?;
+ continue;
+ }
+ let report_age = report_ts.unwrap().elapsed()?;
+ if report_age > Duration::from_secs(REPORT_RETENTION_SECS) {
+ log::info!("Report {} past rentention period, deleting", report_name);
+ remove_file(report)?;
+ }
+ }
+
Ok(ProfcollectdBinderService {
lock: Mutex::new(Lock { scheduler: new_scheduler, config: new_config }),
})