diff options
author | Yi Kong <yikong@google.com> | 2021-03-23 08:53:29 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2021-03-23 08:53:29 +0000 |
commit | f7186fb1694e55899907d45a7432ec1a12aeb36a (patch) | |
tree | 6add3f2dfd9c847bc5a08d7bb098d05747bef710 | |
parent | f58d5814e2dd851b9919234ab7c5d3c9b73d924e (diff) | |
parent | 037bde8973d04926c7b3265050211a060f24e42c (diff) | |
download | extras-f7186fb1694e55899907d45a7432ec1a12aeb36a.tar.gz |
Merge "profcollectd: Create reports with unique names"
-rw-r--r-- | profcollectd/binder/com/android/server/profcollect/IProfCollectd.aidl | 2 | ||||
-rw-r--r-- | profcollectd/libprofcollectd/Android.bp | 3 | ||||
-rw-r--r-- | profcollectd/libprofcollectd/config.rs | 52 | ||||
-rw-r--r-- | profcollectd/libprofcollectd/lib.rs | 5 | ||||
-rw-r--r-- | profcollectd/libprofcollectd/report.rs | 32 | ||||
-rw-r--r-- | profcollectd/libprofcollectd/service.rs | 6 | ||||
-rw-r--r-- | profcollectd/profcollectctl.rs | 3 |
7 files changed, 85 insertions, 18 deletions
diff --git a/profcollectd/binder/com/android/server/profcollect/IProfCollectd.aidl b/profcollectd/binder/com/android/server/profcollect/IProfCollectd.aidl index 9bbe4a5c..bd3b76f8 100644 --- a/profcollectd/binder/com/android/server/profcollect/IProfCollectd.aidl +++ b/profcollectd/binder/com/android/server/profcollect/IProfCollectd.aidl @@ -22,6 +22,6 @@ interface IProfCollectd { void terminate(); void trace_once(@utf8InCpp String tag); void process(boolean blocking); - void report(); + @utf8InCpp String report(); @utf8InCpp String get_supported_provider(); } diff --git a/profcollectd/libprofcollectd/Android.bp b/profcollectd/libprofcollectd/Android.bp index 3c709a2f..2e37af9e 100644 --- a/profcollectd/libprofcollectd/Android.bp +++ b/profcollectd/libprofcollectd/Android.bp @@ -47,8 +47,11 @@ rust_library { "libchrono", "liblazy_static", "liblog_rust", + "libmacaddr", + "librand", "libserde", // Remove once b/179041241 is fixed. "libserde_json", + "libuuid", "libzip", ], rlibs: [ diff --git a/profcollectd/libprofcollectd/config.rs b/profcollectd/libprofcollectd/config.rs index e72fa47a..c0f91d53 100644 --- a/profcollectd/libprofcollectd/config.rs +++ b/profcollectd/libprofcollectd/config.rs @@ -18,6 +18,8 @@ use anyhow::Result; use lazy_static::lazy_static; +use macaddr::MacAddr6; +use rand::Rng; use serde::{Deserialize, Serialize}; use std::error::Error; use std::path::Path; @@ -25,6 +27,7 @@ use std::str::FromStr; use std::time::Duration; const PROFCOLLECT_CONFIG_NAMESPACE: &str = "profcollect_native_boot"; +const PROFCOLLECT_NODE_ID_PROPERTY: &str = "persist.profcollectd.node_id"; lazy_static! { pub static ref TRACE_OUTPUT_DIR: &'static Path = Path::new("/data/misc/profcollectd/trace/"); @@ -40,6 +43,8 @@ lazy_static! { pub struct Config { /// Version of config file scheme, always equals to 1. version: u32, + /// Application specific node ID. + pub node_id: MacAddr6, /// Device build fingerprint. pub build_fingerprint: String, /// Interval between collections. @@ -54,7 +59,8 @@ impl Config { pub fn from_env() -> Result<Self> { Ok(Config { version: 1, - build_fingerprint: get_build_fingerprint(), + node_id: get_or_initialise_node_id()?, + build_fingerprint: get_build_fingerprint()?, collection_interval: Duration::from_secs(get_device_config( "collection_interval", 600, @@ -78,20 +84,54 @@ impl FromStr for Config { } } -fn get_build_fingerprint() -> String { - profcollect_libbase_rust::get_property("ro.build.fingerprint", "unknown").to_string() +fn get_or_initialise_node_id() -> Result<MacAddr6> { + let mut node_id = get_property(&PROFCOLLECT_NODE_ID_PROPERTY, MacAddr6::nil())?; + if node_id.is_nil() { + node_id = generate_random_node_id(); + set_property(&PROFCOLLECT_NODE_ID_PROPERTY, node_id); + } + + Ok(node_id) +} + +fn get_build_fingerprint() -> Result<String> { + get_property("ro.build.fingerprint", "unknown".to_string()) } -fn get_device_config<T>(key: &str, default: T) -> Result<T> +fn get_device_config<T>(key: &str, default_value: T) -> Result<T> where T: FromStr + ToString, T::Err: Error + Send + Sync + 'static, { - let default = default.to_string(); + let default_value = default_value.to_string(); let config = profcollect_libflags_rust::get_server_configurable_flag( &PROFCOLLECT_CONFIG_NAMESPACE, &key, - &default, + &default_value, ); Ok(T::from_str(&config)?) } + +fn get_property<T>(key: &str, default_value: T) -> Result<T> +where + T: FromStr + ToString, + T::Err: Error + Send + Sync + 'static, +{ + let default_value = default_value.to_string(); + let value = profcollect_libbase_rust::get_property(&key, &default_value); + Ok(T::from_str(&value)?) +} + +fn set_property<T>(key: &str, value: T) +where + T: ToString, +{ + let value = value.to_string(); + profcollect_libbase_rust::set_property(&key, &value); +} + +fn generate_random_node_id() -> MacAddr6 { + let mut node_id = rand::thread_rng().gen::<[u8; 6]>(); + node_id[0] |= 0x1; + MacAddr6::from(node_id) +} diff --git a/profcollectd/libprofcollectd/lib.rs b/profcollectd/libprofcollectd/lib.rs index c6a4f2ff..4929da5c 100644 --- a/profcollectd/libprofcollectd/lib.rs +++ b/profcollectd/libprofcollectd/lib.rs @@ -83,9 +83,8 @@ pub fn process() -> Result<()> { } /// Process traces and report profile. -pub fn report() -> Result<()> { - get_profcollectd_service().report()?; - Ok(()) +pub fn report() -> Result<String> { + Ok(get_profcollectd_service().report()?) } /// Inits logging for Android diff --git a/profcollectd/libprofcollectd/report.rs b/profcollectd/libprofcollectd/report.rs index b3c8c96a..218ec875 100644 --- a/profcollectd/libprofcollectd/report.rs +++ b/profcollectd/libprofcollectd/report.rs @@ -17,21 +17,34 @@ //! Pack profiles into reports. use anyhow::{anyhow, Result}; +use lazy_static::lazy_static; +use macaddr::MacAddr6; use std::fs::{read_dir, remove_file, File}; use std::io::{Read, Write}; use std::path::{Path, PathBuf}; +use std::time::SystemTime; +use uuid::v1::{Context, Timestamp}; +use uuid::Uuid; use zip::write::FileOptions; use zip::ZipWriter; -pub fn pack_report(profile: &Path, report: &Path) -> Result<()> { - // TODO: Allow multiple profiles to be queued for upload. +use crate::config::Config; + +lazy_static! { + pub static ref UUID_CONTEXT: Context = Context::new(0); +} + +pub fn pack_report(profile: &Path, report: &Path, config: &Config) -> Result<String> { let mut report = PathBuf::from(report); - report.push("report.zip"); + report.push(get_report_filename(&config.node_id)?); + report.set_extension("zip"); + let report_path = + report.to_str().ok_or_else(|| anyhow!("Malformed report path: {}", report.display()))?; // Remove the current report file if exists. remove_file(&report).ok(); - let report = File::create(report)?; + let report = File::create(&report)?; let options = FileOptions::default(); let mut zip = ZipWriter::new(report); @@ -52,5 +65,14 @@ pub fn pack_report(profile: &Path, report: &Path) -> Result<()> { Ok(()) })?; zip.finish()?; - Ok(()) + + Ok(report_path.to_string()) +} + +fn get_report_filename(node_id: &MacAddr6) -> Result<String> { + let since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?; + let ts = + Timestamp::from_unix(&*UUID_CONTEXT, since_epoch.as_secs(), since_epoch.subsec_nanos()); + let uuid = Uuid::new_v1(ts, &node_id.as_bytes())?; + Ok(uuid.to_string()) } diff --git a/profcollectd/libprofcollectd/service.rs b/profcollectd/libprofcollectd/service.rs index d3413b84..3a6b8d13 100644 --- a/profcollectd/libprofcollectd/service.rs +++ b/profcollectd/libprofcollectd/service.rs @@ -79,9 +79,11 @@ impl IProfCollectd for ProfcollectdBinderService { .context("Failed to process profiles.") .map_err(err_to_binder_status) } - fn report(&self) -> BinderResult<()> { + fn report(&self) -> BinderResult<String> { self.process(true)?; - pack_report(&PROFILE_OUTPUT_DIR, &REPORT_OUTPUT_DIR) + + let lock = &mut *self.lock(); + pack_report(&PROFILE_OUTPUT_DIR, &REPORT_OUTPUT_DIR, &lock.config) .context("Failed to create profile report.") .map_err(err_to_binder_status) } diff --git a/profcollectd/profcollectctl.rs b/profcollectd/profcollectctl.rs index 97213172..c825f550 100644 --- a/profcollectd/profcollectctl.rs +++ b/profcollectd/profcollectctl.rs @@ -62,7 +62,8 @@ fn main() -> Result<()> { } "report" => { println!("Creating profile report"); - libprofcollectd::report().context("Failed to create profile report.")?; + let path = libprofcollectd::report().context("Failed to create profile report.")?; + println!("Report created at: {}", &path); } "help" => println!("{}", &HELP_MSG), arg => bail!("Unknown argument: {}\n{}", &arg, &HELP_MSG), |