Test: adb bugreport Bug: 368510043 Flag: EXEMPT use property flag: persist.vendor.modem.qms.kernel_metrics_collection Change-Id: I874157f12308194f38f67755abbcf2ba7efe3c7a
144 lines
4 KiB
Rust
144 lines
4 KiB
Rust
// Copyright 2024 Google LLC
|
|
|
|
//! The dump_modem binary is used to capture kernel/userspace logs in bugreport
|
|
|
|
use std::fs;
|
|
use std::str::FromStr;
|
|
|
|
const MODEM_STAT: &str = "/data/vendor/modem_stat/debug.txt";
|
|
const SSRDUMP_DIR: &str = "/data/vendor/ssrdump";
|
|
const RFSD_ERR_LOG_DIR: &str = "/data/vendor/log/rfsd";
|
|
const WAKEUP_EVENTS: &str = "/sys/devices/platform/cpif/wakeup_events";
|
|
const CPIF_LOGBUFFER: &str = "/dev/logbuffer_cpif";
|
|
const PCIE_EVENT_STATS: &str = "/sys/devices/platform/cpif/modem/pcie_event_stats";
|
|
const KERNEL_METRICS_DIR: &str = "/sys/kernel/pixel_metrics/modem";
|
|
|
|
fn handle_io_error(file: &str, err: std::io::Error) {
|
|
match err.kind() {
|
|
std::io::ErrorKind::NotFound => println!("{file} not found!"),
|
|
std::io::ErrorKind::PermissionDenied => println!("Permission denied to access {file}"),
|
|
_ => println!("I/O error accessing {file}: {err}"),
|
|
}
|
|
}
|
|
|
|
fn print_file(file: &str) -> Result<(), std::io::Error> {
|
|
fs::metadata(file)?;
|
|
|
|
let data = fs::read_to_string(file)?;
|
|
|
|
if data.is_empty() {
|
|
println!("{file} is empty");
|
|
} else {
|
|
print!("{data}");
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn print_file_and_handle_error(file: &str) {
|
|
if let Err(err) = print_file(file) {
|
|
handle_io_error(file, err);
|
|
}
|
|
}
|
|
|
|
fn print_matching_files_in_dir(dir: &str, filename: &str) {
|
|
let Ok(entries) = fs::read_dir(dir) else {
|
|
return println!("Cannot open directory {dir}");
|
|
};
|
|
|
|
for entry in entries {
|
|
let Ok(entry) = entry else {
|
|
continue;
|
|
};
|
|
if entry.path().is_file() && entry.file_name().to_string_lossy().starts_with(filename) {
|
|
if let Some(path_str) = entry.path().to_str() {
|
|
println!("{}", path_str);
|
|
print_file_and_handle_error(path_str);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn get_property(key: &str, default_value: i32) -> i32 {
|
|
let value = rustutils::system_properties::read(key)
|
|
.unwrap_or(None)
|
|
.unwrap_or(default_value.to_string());
|
|
i32::from_str(&value).unwrap_or(default_value)
|
|
}
|
|
|
|
// Capture modem stat log if it exists
|
|
fn modem_stat() {
|
|
println!("------ Modem Stat ------");
|
|
print_file_and_handle_error(MODEM_STAT);
|
|
println!();
|
|
}
|
|
|
|
// Capture crash signatures from all modem crashes
|
|
fn modem_ssr_history() {
|
|
println!("------ Modem SSR history ------");
|
|
print_matching_files_in_dir(SSRDUMP_DIR, "crashinfo_modem");
|
|
println!();
|
|
}
|
|
|
|
// Capture rfsd error logs from all existing log files
|
|
fn rfsd_error_log() {
|
|
println!("------ RFSD error log ------");
|
|
print_matching_files_in_dir(RFSD_ERR_LOG_DIR, "rfslog");
|
|
println!();
|
|
}
|
|
|
|
// Capture modem wakeup events if the sysfs attribute exists
|
|
fn wakeup_events() {
|
|
println!("------ Wakeup event counts ------");
|
|
print_file_and_handle_error(WAKEUP_EVENTS);
|
|
println!();
|
|
}
|
|
|
|
// Capture kernel driver logbuffer if it exists
|
|
fn cpif_logbuffer() {
|
|
println!("------ CPIF Logbuffer ------");
|
|
print_file_and_handle_error(CPIF_LOGBUFFER);
|
|
println!();
|
|
}
|
|
|
|
// Capture modem pcie stats if the sysfs attribute exists
|
|
fn pcie_event_stats() {
|
|
println!("------ PCIe event stats ------");
|
|
print_file_and_handle_error(PCIE_EVENT_STATS);
|
|
println!();
|
|
}
|
|
|
|
// Capture kernel metrics stats if the sysfs attribute exists
|
|
fn print_kernel_metrics() {
|
|
println!("------ Kernel Metrics ------");
|
|
|
|
let file_list = vec![
|
|
"modem_boot_duration",
|
|
"modem_wakeup_ap",
|
|
"pcie_link_state",
|
|
"pcie_link_duration",
|
|
"pcie_link_stats",
|
|
"pcie_link_updown",
|
|
];
|
|
|
|
for file in file_list {
|
|
println!("------ {} ------", file);
|
|
let file_path = format!("{}/{}", KERNEL_METRICS_DIR, file);
|
|
print_file_and_handle_error(&file_path);
|
|
println!();
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
modem_stat();
|
|
modem_ssr_history();
|
|
rfsd_error_log();
|
|
wakeup_events();
|
|
cpif_logbuffer();
|
|
pcie_event_stats();
|
|
|
|
let prop_value = get_property("persist.vendor.modem.qms.kernel_metrics_collection", 0);
|
|
if prop_value == 1 {
|
|
print_kernel_metrics();
|
|
}
|
|
}
|