dumpstate: Use thread to dump modem logs

Bug: 150185396

Change-Id: I9d989d5e42158b8d85dfd05761eca2516be9a1d6
This commit is contained in:
Hungyen Weng
2020-02-25 13:04:00 +08:00
committed by Cyan_Hsieh
parent 51d10663f5
commit e7b7e29dab
2 changed files with 59 additions and 64 deletions

View File

@@ -24,6 +24,7 @@
#include <hidl/HidlBinderSupport.h>
#include <log/log.h>
#include <pthread.h>
#include <string.h>
#define _SVID_SOURCE
@@ -65,34 +66,8 @@ namespace implementation {
#define TCPDUMP_LOG_PREFIX "tcpdump"
#define EXTENDED_LOG_PREFIX "extended_log_"
static bool isModemLoggingEnabled() {
return android::base::GetBoolProperty(DIAG_MDLOG_PERSIST_PROPERTY, false);
}
static bool isModemLoggingRunning() {
return android::base::GetBoolProperty(DIAG_MDLOG_STATUS_PROPERTY, false);
}
static void stopModemLogging() {
if (PropertiesHelper::IsUserBuild()) {
return;
}
android::base::SetProperty(DIAG_MDLOG_PROPERTY, "false");
ALOGD("Stopping diag_mdlog...\n");
}
static void startModemLogging() {
if (PropertiesHelper::IsUserBuild()) {
return;
}
ALOGD("Starting diag_mdlog...\n");
android::base::SetProperty(DIAG_MDLOG_PROPERTY, "true");
}
void DumpstateDevice::dumpLogs(int fd, std::string srcDir, std::string destDir,
int maxFileNum, const char *logPrefix) {
static void dumpLogs(int fd, std::string srcDir, std::string destDir,
int maxFileNum, const char *logPrefix) {
struct dirent **dirent_list = NULL;
int num_entries = scandir(srcDir.c_str(),
&dirent_list,
@@ -137,39 +112,61 @@ void DumpstateDevice::dumpLogs(int fd, std::string srcDir, std::string destDir,
free(dirent_list);
}
void DumpstateDevice::dumpModem(int fd, int fdModem)
static void *dumpModemThread(void *data)
{
long fdModem = (long)data;
ALOGD("dumpModemThread started\n");
std::string modemLogDir = android::base::GetProperty(MODEM_LOG_LOC_PROPERTY, "");
if (modemLogDir.empty()) {
ALOGD("No modem log place is set");
return;
return NULL;
}
std::string filePrefix = android::base::GetProperty(MODEM_LOG_PREFIX_PROPERTY, "");
if (filePrefix.empty()) {
ALOGD("Modem log prefix is not set");
return;
return NULL;
}
sleep(1);
ALOGD("Waited modem for 1 second to flush logs");
const std::string modemLogCombined = modemLogDir + "/" + filePrefix + "all.tar";
const std::string modemLogAllDir = modemLogDir + "/modem_log";
RunCommandToFd(fd, "MKDIR MODEM LOG", {"/vendor/bin/mkdir", "-p", modemLogAllDir.c_str()}, CommandOptions::WithTimeout(2).Build());
RunCommandToFd(STDOUT_FILENO, "MKDIR MODEM LOG", {"/vendor/bin/mkdir", "-p", modemLogAllDir.c_str()}, CommandOptions::WithTimeout(2).Build());
const std::string diagLogDir = "/data/vendor/radio/diag_logs/logs";
const std::string diagPoweronLogPath = "/data/vendor/radio/diag_logs/logs/diag_poweron_log.qmdl";
if (isModemLoggingEnabled()) {
if (isModemLoggingRunning()) {
ALOGD("diag_mdlog is running");
bool diagLogEnabled = android::base::GetBoolProperty(DIAG_MDLOG_PERSIST_PROPERTY, false);
if (diagLogEnabled) {
bool diagLogStarted = android::base::GetBoolProperty( DIAG_MDLOG_STATUS_PROPERTY, false);
if (diagLogStarted) {
android::base::SetProperty(DIAG_MDLOG_PROPERTY, "false");
ALOGD("Stopping diag_mdlog...\n");
if (android::base::WaitForProperty(DIAG_MDLOG_STATUS_PROPERTY, "false", std::chrono::seconds(10))) {
ALOGD("diag_mdlog exited");
} else {
ALOGE("Waited mdlog timeout after 10 second");
}
} else {
ALOGD("diag_mdlog is not running");
}
dumpLogs(fd, diagLogDir, modemLogAllDir, android::base::GetIntProperty(DIAG_MDLOG_NUMBER_BUGREPORT, 100), DIAG_LOG_PREFIX);
dumpLogs(STDOUT_FILENO, diagLogDir, modemLogAllDir, android::base::GetIntProperty(DIAG_MDLOG_NUMBER_BUGREPORT, 100), DIAG_LOG_PREFIX);
if (diagLogStarted) {
ALOGD("Restarting diag_mdlog...");
android::base::SetProperty(DIAG_MDLOG_PROPERTY, "true");
}
}
RunCommandToFd(fd, "CP MODEM POWERON LOG", {"/vendor/bin/cp", diagPoweronLogPath.c_str(), modemLogAllDir.c_str()}, CommandOptions::WithTimeout(2).Build());
RunCommandToFd(STDOUT_FILENO, "CP MODEM POWERON LOG", {"/vendor/bin/cp", diagPoweronLogPath.c_str(), modemLogAllDir.c_str()}, CommandOptions::WithTimeout(2).Build());
if (!PropertiesHelper::IsUserBuild()) {
char cmd[256] = { 0 };
@@ -204,27 +201,26 @@ void DumpstateDevice::dumpModem(int fd, int fdModem)
};
bool tcpdumpEnabled = android::base::GetBoolProperty(TCPDUMP_PERSIST_PROPERTY, false);
if (tcpdumpEnabled) {
dumpLogs(fd, tcpdumpLogDir, modemLogAllDir, android::base::GetIntProperty(TCPDUMP_NUMBER_BUGREPORT, 5), TCPDUMP_LOG_PREFIX);
dumpLogs(STDOUT_FILENO, tcpdumpLogDir, modemLogAllDir, android::base::GetIntProperty(TCPDUMP_NUMBER_BUGREPORT, 5), TCPDUMP_LOG_PREFIX);
}
for (const auto& logFile : rilAndNetmgrLogs) {
RunCommandToFd(fd, "CP MODEM LOG", {"/vendor/bin/cp", logFile.c_str(), modemLogAllDir.c_str()}, CommandOptions::WithTimeout(2).Build());
RunCommandToFd(STDOUT_FILENO, "CP MODEM LOG", {"/vendor/bin/cp", logFile.c_str(), modemLogAllDir.c_str()}, CommandOptions::WithTimeout(2).Build());
}
//Dump IPA log
snprintf(cmd, sizeof(cmd),
"cat /d/ipc_logging/ipa/log > %s/ipa_log",
modemLogAllDir.c_str());
RunCommandToFd(fd, "Dump IPA log", {"/vendor/bin/sh", "-c", cmd});
RunCommandToFd(STDOUT_FILENO, "Dump IPA log", {"/vendor/bin/sh", "-c", cmd});
dumpLogs(fd, extendedLogDir, modemLogAllDir, 100, EXTENDED_LOG_PREFIX);
dumpLogs(STDOUT_FILENO, extendedLogDir, modemLogAllDir, 100, EXTENDED_LOG_PREFIX);
android::base::SetProperty(MODEM_EFS_DUMP_PROPERTY, "false");
}
RunCommandToFd(fd, "TAR LOG", {"/vendor/bin/tar", "cvf", modemLogCombined.c_str(), "-C", modemLogAllDir.c_str(), "."}, CommandOptions::WithTimeout(120).Build());
RunCommandToFd(fd, "CHG PERM", {"/vendor/bin/chmod", "a+w", modemLogCombined.c_str()}, CommandOptions::WithTimeout(2).Build());
RunCommandToFd(STDOUT_FILENO, "TAR LOG", {"/vendor/bin/tar", "cvf", modemLogCombined.c_str(), "-C", modemLogAllDir.c_str(), "."}, CommandOptions::WithTimeout(20).Build());
RunCommandToFd(STDOUT_FILENO, "CHG PERM", {"/vendor/bin/chmod", "a+w", modemLogCombined.c_str()}, CommandOptions::WithTimeout(2).Build());
std::vector<uint8_t> buffer(65536);
android::base::unique_fd fdLog(TEMP_FAILURE_RETRY(open(modemLogCombined.c_str(), O_RDONLY | O_CLOEXEC | O_NONBLOCK)));
@@ -249,8 +245,12 @@ void DumpstateDevice::dumpModem(int fd, int fdModem)
}
}
RunCommandToFd(fd, "RM MODEM DIR", { "/vendor/bin/rm", "-r", modemLogAllDir.c_str()}, CommandOptions::WithTimeout(2).Build());
RunCommandToFd(fd, "RM LOG", { "/vendor/bin/rm", modemLogCombined.c_str()}, CommandOptions::WithTimeout(2).Build());
RunCommandToFd(STDOUT_FILENO, "RM MODEM DIR", { "/vendor/bin/rm", "-r", modemLogAllDir.c_str()}, CommandOptions::WithTimeout(2).Build());
RunCommandToFd(STDOUT_FILENO, "RM LOG", { "/vendor/bin/rm", modemLogCombined.c_str()}, CommandOptions::WithTimeout(2).Build());
ALOGD("dumpModemThread finished\n");
return NULL;
}
static void DumpTouch(int fd) {
@@ -450,13 +450,18 @@ Return<DumpstateStatus> DumpstateDevice::dumpstateBoard_1_1(const hidl_handle& h
return DumpstateStatus::ILLEGAL_ARGUMENT;
}
bool modemLogging = isModemLoggingRunning();
RunCommandToFd(fd, "Notify modem", {"/vendor/bin/modem_svc", "-s"}, CommandOptions::WithTimeout(1).Build());
if (isModemLoggingEnabled() && modemLogging) {
stopModemLogging();
pthread_t modemThreadHandle = 0;
if (handle->numFds < 2) {
ALOGE("no FD for modem\n");
} else {
int fdModem = handle->data[1];
if (pthread_create(&modemThreadHandle, NULL, dumpModemThread, (void *)((long)fdModem)) != 0) {
ALOGE("could not create thread for dumpModem\n");
}
}
RunCommandToFd(fd, "Notify modem", {"/vendor/bin/modem_svc", "-s"}, CommandOptions::WithTimeout(1).Build());
RunCommandToFd(fd, "VENDOR PROPERTIES", {"/vendor/bin/getprop"});
DumpFileToFd(fd, "SoC serial number", "/sys/devices/soc0/serial_number");
DumpFileToFd(fd, "CPU present", "/sys/devices/system/cpu/present");
@@ -524,16 +529,6 @@ Return<DumpstateStatus> DumpstateDevice::dumpstateBoard_1_1(const hidl_handle& h
// Slower dump put later in case stuck the rest of dump
// Timeout after 3s as TZ log missing EOF
RunCommandToFd(fd, "QSEE logs", {"/vendor/bin/sh", "-c", "/vendor/bin/timeout 3 cat /d/tzdbg/qsee_log"});
if (handle->numFds < 2) {
ALOGE("no FD for modem\n");
} else {
int fdModem = handle->data[1];
dumpModem(fd, fdModem);
}
if (isModemLoggingEnabled() && modemLogging) {
startModemLogging();
}
// Citadel info
RunCommandToFd(fd, "Citadel VERSION", {"/vendor/bin/hw/citadel_updater", "-lv"});
@@ -546,6 +541,10 @@ Return<DumpstateStatus> DumpstateDevice::dumpstateBoard_1_1(const hidl_handle& h
// Keep this at the end as very long on not for humans
DumpFileToFd(fd, "WLAN FW Log Symbol Table", "/vendor/firmware/Data.msc");
if (modemThreadHandle) {
pthread_join(modemThreadHandle, NULL);
}
return DumpstateStatus::OK;
}

View File

@@ -48,10 +48,6 @@ struct DumpstateDevice : public IDumpstateDevice {
const uint64_t timeoutMillis) override;
Return<void> setVerboseLoggingEnabled(const bool enable) override;
Return<bool> getVerboseLoggingEnabled() override;
void dumpLogs(int fd, std::string srcDir, std::string destDir, int maxFileNum,
const char *logPrefix);
void dumpModem(int fd, int fdModem);
};
} // namespace implementation