summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYi Kong <yikong@google.com>2021-03-23 08:53:29 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2021-03-23 08:53:29 +0000
commitf7186fb1694e55899907d45a7432ec1a12aeb36a (patch)
tree6add3f2dfd9c847bc5a08d7bb098d05747bef710
parentf58d5814e2dd851b9919234ab7c5d3c9b73d924e (diff)
parent037bde8973d04926c7b3265050211a060f24e42c (diff)
downloadextras-f7186fb1694e55899907d45a7432ec1a12aeb36a.tar.gz
Merge "profcollectd: Create reports with unique names"
-rw-r--r--profcollectd/binder/com/android/server/profcollect/IProfCollectd.aidl2
-rw-r--r--profcollectd/libprofcollectd/Android.bp3
-rw-r--r--profcollectd/libprofcollectd/config.rs52
-rw-r--r--profcollectd/libprofcollectd/lib.rs5
-rw-r--r--profcollectd/libprofcollectd/report.rs32
-rw-r--r--profcollectd/libprofcollectd/service.rs6
-rw-r--r--profcollectd/profcollectctl.rs3
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),