fastboot: Add a command to get current kernel logs.

This adds "fastboot getvar dmesg", usable only in userspace fastboot,
and only on unlocked devices. This is to debug flashing failures when
serial log access is not available.

Bug: 230269532
Test: fastboot getvar dmesg
Change-Id: Ic57881e362efe3f0687f41ab986d30b3a59dc4e4
This commit is contained in:
David Anderson 2022-06-17 19:17:43 -07:00
parent cef4850d9f
commit ebc8fe19f8
4 changed files with 94 additions and 41 deletions

View file

@ -79,3 +79,4 @@
#define FB_VAR_SECURITY_PATCH_LEVEL "security-patch-level"
#define FB_VAR_TREBLE_ENABLED "treble-enabled"
#define FB_VAR_MAX_FETCH_SIZE "max-fetch-size"
#define FB_VAR_DMESG "dmesg"

View file

@ -112,52 +112,65 @@ static void GetAllVars(FastbootDevice* device, const std::string& name,
}
}
bool GetVarHandler(FastbootDevice* device, const std::vector<std::string>& args) {
const std::unordered_map<std::string, VariableHandlers> kVariableMap = {
{FB_VAR_VERSION, {GetVersion, nullptr}},
{FB_VAR_VERSION_BOOTLOADER, {GetBootloaderVersion, nullptr}},
{FB_VAR_VERSION_BASEBAND, {GetBasebandVersion, nullptr}},
{FB_VAR_VERSION_OS, {GetOsVersion, nullptr}},
{FB_VAR_VERSION_VNDK, {GetVndkVersion, nullptr}},
{FB_VAR_PRODUCT, {GetProduct, nullptr}},
{FB_VAR_SERIALNO, {GetSerial, nullptr}},
{FB_VAR_VARIANT, {GetVariant, nullptr}},
{FB_VAR_SECURE, {GetSecure, nullptr}},
{FB_VAR_UNLOCKED, {GetUnlocked, nullptr}},
{FB_VAR_MAX_DOWNLOAD_SIZE, {GetMaxDownloadSize, nullptr}},
{FB_VAR_CURRENT_SLOT, {::GetCurrentSlot, nullptr}},
{FB_VAR_SLOT_COUNT, {GetSlotCount, nullptr}},
{FB_VAR_HAS_SLOT, {GetHasSlot, GetAllPartitionArgsNoSlot}},
{FB_VAR_SLOT_SUCCESSFUL, {GetSlotSuccessful, nullptr}},
{FB_VAR_SLOT_UNBOOTABLE, {GetSlotUnbootable, nullptr}},
{FB_VAR_PARTITION_SIZE, {GetPartitionSize, GetAllPartitionArgsWithSlot}},
{FB_VAR_PARTITION_TYPE, {GetPartitionType, GetAllPartitionArgsWithSlot}},
{FB_VAR_IS_LOGICAL, {GetPartitionIsLogical, GetAllPartitionArgsWithSlot}},
{FB_VAR_IS_USERSPACE, {GetIsUserspace, nullptr}},
{FB_VAR_OFF_MODE_CHARGE_STATE, {GetOffModeChargeState, nullptr}},
{FB_VAR_BATTERY_VOLTAGE, {GetBatteryVoltage, nullptr}},
{FB_VAR_BATTERY_SOC_OK, {GetBatterySoCOk, nullptr}},
{FB_VAR_HW_REVISION, {GetHardwareRevision, nullptr}},
{FB_VAR_SUPER_PARTITION_NAME, {GetSuperPartitionName, nullptr}},
{FB_VAR_SNAPSHOT_UPDATE_STATUS, {GetSnapshotUpdateStatus, nullptr}},
{FB_VAR_CPU_ABI, {GetCpuAbi, nullptr}},
{FB_VAR_SYSTEM_FINGERPRINT, {GetSystemFingerprint, nullptr}},
{FB_VAR_VENDOR_FINGERPRINT, {GetVendorFingerprint, nullptr}},
{FB_VAR_DYNAMIC_PARTITION, {GetDynamicPartition, nullptr}},
{FB_VAR_FIRST_API_LEVEL, {GetFirstApiLevel, nullptr}},
{FB_VAR_SECURITY_PATCH_LEVEL, {GetSecurityPatchLevel, nullptr}},
{FB_VAR_TREBLE_ENABLED, {GetTrebleEnabled, nullptr}},
{FB_VAR_MAX_FETCH_SIZE, {GetMaxFetchSize, nullptr}},
};
const std::unordered_map<std::string, VariableHandlers> kVariableMap = {
{FB_VAR_VERSION, {GetVersion, nullptr}},
{FB_VAR_VERSION_BOOTLOADER, {GetBootloaderVersion, nullptr}},
{FB_VAR_VERSION_BASEBAND, {GetBasebandVersion, nullptr}},
{FB_VAR_VERSION_OS, {GetOsVersion, nullptr}},
{FB_VAR_VERSION_VNDK, {GetVndkVersion, nullptr}},
{FB_VAR_PRODUCT, {GetProduct, nullptr}},
{FB_VAR_SERIALNO, {GetSerial, nullptr}},
{FB_VAR_VARIANT, {GetVariant, nullptr}},
{FB_VAR_SECURE, {GetSecure, nullptr}},
{FB_VAR_UNLOCKED, {GetUnlocked, nullptr}},
{FB_VAR_MAX_DOWNLOAD_SIZE, {GetMaxDownloadSize, nullptr}},
{FB_VAR_CURRENT_SLOT, {::GetCurrentSlot, nullptr}},
{FB_VAR_SLOT_COUNT, {GetSlotCount, nullptr}},
{FB_VAR_HAS_SLOT, {GetHasSlot, GetAllPartitionArgsNoSlot}},
{FB_VAR_SLOT_SUCCESSFUL, {GetSlotSuccessful, nullptr}},
{FB_VAR_SLOT_UNBOOTABLE, {GetSlotUnbootable, nullptr}},
{FB_VAR_PARTITION_SIZE, {GetPartitionSize, GetAllPartitionArgsWithSlot}},
{FB_VAR_PARTITION_TYPE, {GetPartitionType, GetAllPartitionArgsWithSlot}},
{FB_VAR_IS_LOGICAL, {GetPartitionIsLogical, GetAllPartitionArgsWithSlot}},
{FB_VAR_IS_USERSPACE, {GetIsUserspace, nullptr}},
{FB_VAR_OFF_MODE_CHARGE_STATE, {GetOffModeChargeState, nullptr}},
{FB_VAR_BATTERY_VOLTAGE, {GetBatteryVoltage, nullptr}},
{FB_VAR_BATTERY_SOC_OK, {GetBatterySoCOk, nullptr}},
{FB_VAR_HW_REVISION, {GetHardwareRevision, nullptr}},
{FB_VAR_SUPER_PARTITION_NAME, {GetSuperPartitionName, nullptr}},
{FB_VAR_SNAPSHOT_UPDATE_STATUS, {GetSnapshotUpdateStatus, nullptr}},
{FB_VAR_CPU_ABI, {GetCpuAbi, nullptr}},
{FB_VAR_SYSTEM_FINGERPRINT, {GetSystemFingerprint, nullptr}},
{FB_VAR_VENDOR_FINGERPRINT, {GetVendorFingerprint, nullptr}},
{FB_VAR_DYNAMIC_PARTITION, {GetDynamicPartition, nullptr}},
{FB_VAR_FIRST_API_LEVEL, {GetFirstApiLevel, nullptr}},
{FB_VAR_SECURITY_PATCH_LEVEL, {GetSecurityPatchLevel, nullptr}},
{FB_VAR_TREBLE_ENABLED, {GetTrebleEnabled, nullptr}},
{FB_VAR_MAX_FETCH_SIZE, {GetMaxFetchSize, nullptr}},
};
static bool GetVarAll(FastbootDevice* device) {
for (const auto& [name, handlers] : kVariableMap) {
GetAllVars(device, name, handlers);
}
return true;
}
const std::unordered_map<std::string, std::function<bool(FastbootDevice*)>> kSpecialVars = {
{"all", GetVarAll},
{"dmesg", GetDmesg},
};
bool GetVarHandler(FastbootDevice* device, const std::vector<std::string>& args) {
if (args.size() < 2) {
return device->WriteFail("Missing argument");
}
// Special case: return all variables that we can.
if (args[1] == "all") {
for (const auto& [name, handlers] : kVariableMap) {
GetAllVars(device, name, handlers);
// "all" and "dmesg" are multiline and handled specially.
auto found_special = kSpecialVars.find(args[1]);
if (found_special != kSpecialVars.end()) {
if (!found_special->second(device)) {
return false;
}
return device->WriteOkay("");
}

View file

@ -17,6 +17,7 @@
#include "variables.h"
#include <inttypes.h>
#include <stdio.h>
#include <android-base/file.h>
#include <android-base/logging.h>
@ -28,6 +29,7 @@
#include <fs_mgr.h>
#include <liblp/liblp.h>
#include "constants.h"
#include "fastboot_device.h"
#include "flashing.h"
#include "utility.h"
@ -46,6 +48,7 @@ using ::android::hardware::fastboot::V1_0::Result;
using ::android::hardware::fastboot::V1_0::Status;
using IBootControl1_1 = ::android::hardware::boot::V1_1::IBootControl;
using namespace android::fs_mgr;
using namespace std::string_literals;
constexpr char kFastbootProtocolVersion[] = "0.4";
@ -518,3 +521,36 @@ bool GetMaxFetchSize(FastbootDevice* /* device */, const std::vector<std::string
*message = android::base::StringPrintf("0x%X", kMaxFetchSizeDefault);
return true;
}
bool GetDmesg(FastbootDevice* device) {
if (GetDeviceLockStatus()) {
return device->WriteFail("Cannot use when device flashing is locked");
}
std::unique_ptr<FILE, decltype(&::fclose)> fp(popen("/system/bin/dmesg", "re"), ::fclose);
if (!fp) {
PLOG(ERROR) << "popen /system/bin/dmesg";
return device->WriteFail("Unable to run dmesg: "s + strerror(errno));
}
ssize_t rv;
size_t n = 0;
char* str = nullptr;
while ((rv = ::getline(&str, &n, fp.get())) > 0) {
if (str[rv - 1] == '\n') {
rv--;
}
device->WriteInfo(std::string(str, rv));
}
int saved_errno = errno;
::free(str);
if (rv < 0 && saved_errno) {
LOG(ERROR) << "dmesg getline: " << strerror(saved_errno);
device->WriteFail("Unable to read dmesg: "s + strerror(saved_errno));
return false;
}
return true;
}

View file

@ -83,6 +83,9 @@ bool GetTrebleEnabled(FastbootDevice* device, const std::vector<std::string>& ar
bool GetMaxFetchSize(FastbootDevice* /* device */, const std::vector<std::string>& /* args */,
std::string* message);
// Complex cases.
bool GetDmesg(FastbootDevice* device);
// Helpers for getvar all.
std::vector<std::vector<std::string>> GetAllPartitionArgsWithSlot(FastbootDevice* device);
std::vector<std::vector<std::string>> GetAllPartitionArgsNoSlot(FastbootDevice* device);