bootstat: clear persist.sys.boot.reason once read

To ensure a surprise reboot does not take the last boot reason on
face value especially if coming from more than one boot sessions ago.
We shift and clear the value from persist.sys.boot.reason to
sys.boot.reason.last and establish a correct last reboot reason in
the canonical sys.boot.reason property.

This effectively deprecates persist.sys.boot.reason as an API.  They
should have been using sys.boot.reason instead for a correctly
determined reasoning.

Test: boot_reason_test.sh
Bug: 86671991
Merged-In: If85750704445088fd62978679ab3a30744c46abb
Change-Id: If85750704445088fd62978679ab3a30744c46abb
This commit is contained in:
Mark Salyzyn 2018-06-05 08:17:35 -07:00
parent 91061985f5
commit adc433d3ea
2 changed files with 54 additions and 40 deletions

View file

@ -480,23 +480,25 @@ properties test
- (wait until screen is up, boot has completed)
- adb shell getprop ro.boot.bootreason (bootloader reason)
- adb shell getprop persist.sys.boot.reason (last reason)
- adb shell getprop sys.boot.reason.last (last last reason)
- adb shell getprop sys.boot.reason (system reason)
- NB: all should have a value that is compliant with our known set." ]
test_properties() {
duration_test 1
wait_for_screen
retval=0
check_set="ro.boot.bootreason persist.sys.boot.reason sys.boot.reason"
check_set="ro.boot.bootreason sys.boot.reason.last sys.boot.reason"
bootloader=""
# NB: this test could fail if performed _after_ optional_factory_reset test
# and will report
# ERROR: expected "reboot" got ""
# for Android property persist.sys.boot.reason
# for Android property sys.boot.reason.last
# following is mitigation for the persist.sys.boot.reason, skip it
if [ "reboot,factory_reset" = "`validate_property ro.boot_bootreason`" ]; then
check_set="ro.boot.bootreason sys.boot.reason"
bootloader="bootloader"
fi
EXPECT_PROPERTY persist.sys.boot.reason ""
for prop in ${check_set}; do
reason=`validate_property ${prop}`
EXPECT_PROPERTY ${prop} ${reason} || retval=${?}
@ -554,7 +556,8 @@ test_ota() {
popd >&2
wait_for_screen
EXPECT_PROPERTY sys.boot.reason "\(reboot,ota\|bootloader\)"
EXPECT_PROPERTY persist.sys.boot.reason bootloader
EXPECT_PROPERTY sys.boot.reason.last bootloader
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs reboot,ota bootloader
}
@ -568,7 +571,8 @@ test_optional_ota() {
adb reboot ota
wait_for_screen
EXPECT_PROPERTY sys.boot.reason reboot,ota
EXPECT_PROPERTY persist.sys.boot.reason reboot,ota
EXPECT_PROPERTY sys.boot.reason.last reboot,ota
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs reboot,ota
}
@ -593,9 +597,15 @@ blind_reboot_test() {
wait_for_screen
bootloader_reason=`validate_property ro.boot.bootreason`
EXPECT_PROPERTY ro.boot.bootreason ${bootloader_reason}
EXPECT_PROPERTY sys.boot.reason ${reason}
EXPECT_PROPERTY persist.sys.boot.reason ${reason}
report_bootstat_logs ${reason}
# to make sys.boot.reason report user friendly
reasons=${reason}
if [ "${bootloader_reason}" != "${reason}" -a -n "${bootloader_reason}" ]; then
reasons="\(${reason}\|${bootloader_reason}\)"
fi
EXPECT_PROPERTY sys.boot.reason ${reasons}
EXPECT_PROPERTY sys.boot.reason.last ${reason}
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs ${reason} ${bootloader_reason}
}
[ "USAGE: test_cold
@ -627,7 +637,8 @@ test_factory_reset() {
adb reboot >&2
wait_for_screen
EXPECT_PROPERTY sys.boot.reason reboot,factory_reset
EXPECT_PROPERTY persist.sys.boot.reason "reboot,.*"
EXPECT_PROPERTY sys.boot.reason.last "reboot,.*"
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs reboot,factory_reset reboot, reboot,adb \
"-bootstat: Failed to read /data/misc/bootstat/build_date: No such file or directory" \
"-bootstat: Failed to parse boot time record: /data/misc/bootstat/build_date"
@ -658,6 +669,7 @@ test_optional_factory_reset() {
wait_for_screen
( exit ${save_ret} ) # because one can not just do ?=${save_ret}
EXPECT_PROPERTY sys.boot.reason reboot,factory_reset
EXPECT_PROPERTY sys.boot.reason.last ""
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs reboot,factory_reset bootloader \
"-bootstat: Failed to read /data/misc/bootstat/last_boot_time_utc: No such file or directory" \
@ -731,7 +743,8 @@ test_battery() {
)
EXPECT_PROPERTY sys.boot.reason shutdown,battery
EXPECT_PROPERTY persist.sys.boot.reason cold
EXPECT_PROPERTY sys.boot.reason.last cold
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs shutdown,battery "-bootstat: Battery level at shutdown 2%"
exitPstore
}
@ -752,7 +765,8 @@ test_optional_battery() {
echo -n "WARNING: Please power device back up, waiting ... " >&2
wait_for_screen -n >&2
EXPECT_PROPERTY sys.boot.reason shutdown,battery
EXPECT_PROPERTY persist.sys.boot.reason shutdown,battery
EXPECT_PROPERTY sys.boot.reason.last shutdown,battery
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs shutdown,battery
}
@ -772,7 +786,8 @@ test_optional_battery_thermal() {
echo -n "WARNING: Please power device back up, waiting ... " >&2
wait_for_screen -n >&2
EXPECT_PROPERTY sys.boot.reason shutdown,thermal,battery
EXPECT_PROPERTY persist.sys.boot.reason shutdown,thermal,battery
EXPECT_PROPERTY sys.boot.reason.last shutdown,thermal,battery
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs shutdown,thermal,battery
}
@ -808,7 +823,8 @@ test_kernel_panic() {
echo c | adb shell su root tee /proc/sysrq-trigger >/dev/null
wait_for_screen
EXPECT_PROPERTY sys.boot.reason ${panic_msg}
EXPECT_PROPERTY persist.sys.boot.reason ${panic_msg}
EXPECT_PROPERTY sys.boot.reason.last ${panic_msg}
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs kernel_panic,sysrq
exitPstore
}
@ -835,7 +851,8 @@ test_kernel_panic_subreason() {
echo c | adb shell su root tee /proc/sysrq-trigger >/dev/null
wait_for_screen
EXPECT_PROPERTY sys.boot.reason ${panic_msg}
EXPECT_PROPERTY persist.sys.boot.reason ${panic_msg}
EXPECT_PROPERTY sys.boot.reason.last ${panic_msg}
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs kernel_panic,sysrq,test \
"-bootstat: Unknown boot reason: kernel_panic,sysrq,test"
exitPstore
@ -865,7 +882,8 @@ test_kernel_panic_hung() {
adb reboot warm
wait_for_screen
EXPECT_PROPERTY sys.boot.reason ${panic_msg}
EXPECT_PROPERTY persist.sys.boot.reason ${panic_msg}
EXPECT_PROPERTY sys.boot.reason.last ${panic_msg}
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs kernel_panic,hung
exitPstore
}
@ -897,7 +915,8 @@ test_thermal_shutdown() {
echo -n "WARNING: Please power device back up, waiting ... " >&2
wait_for_screen -n >&2
EXPECT_PROPERTY sys.boot.reason shutdown,thermal
EXPECT_PROPERTY persist.sys.boot.reason shutdown,thermal
EXPECT_PROPERTY sys.boot.reason.last shutdown,thermal
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs shutdown,thermal
}
@ -917,7 +936,8 @@ test_userrequested_shutdown() {
echo -n "WARNING: Please power device back up, waiting ... " >&2
wait_for_screen -n >&2
EXPECT_PROPERTY sys.boot.reason shutdown,userrequested
EXPECT_PROPERTY persist.sys.boot.reason shutdown,userrequested
EXPECT_PROPERTY sys.boot.reason.last shutdown,userrequested
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs shutdown,userrequested
}
@ -933,7 +953,8 @@ test_shell_reboot() {
adb shell reboot
wait_for_screen
EXPECT_PROPERTY sys.boot.reason reboot,shell
EXPECT_PROPERTY persist.sys.boot.reason reboot,shell
EXPECT_PROPERTY sys.boot.reason.last reboot,shell
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs reboot,shell
}
@ -949,7 +970,8 @@ test_adb_reboot() {
adb reboot
wait_for_screen
EXPECT_PROPERTY sys.boot.reason reboot,adb
EXPECT_PROPERTY persist.sys.boot.reason reboot,adb
EXPECT_PROPERTY sys.boot.reason.last reboot,adb
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs reboot,adb
}
@ -984,23 +1006,8 @@ test_Its_Just_So_Hard_reboot() {
adb shell 'reboot "Its Just So Hard"'
wait_for_screen
EXPECT_PROPERTY sys.boot.reason reboot,its_just_so_hard
EXPECT_PROPERTY persist.sys.boot.reason "reboot,Its Just So Hard"
# Do not leave this test with an illegal value in persist.sys.boot.reason
save_ret=${?} # hold on to error code from above two lines
if isDebuggable; then # can do this easy, or we can do this hard.
adb shell su root setprop persist.sys.boot.reason reboot,its_just_so_hard
( exit ${save_ret} ) # because one can not just do ?=${save_ret}
else
report_bootstat_logs reboot,its_just_so_hard # report what we have so far
# user build mitigation
adb shell reboot its_just_so_hard
wait_for_screen
( exit ${save_ret} ) # because one can not just do ?=${save_ret}
EXPECT_PROPERTY sys.boot.reason reboot,its_just_so_hard
fi
# Ensure persist.sys.boot.reason now valid, failure here acts as a signal
# that we could choke up following tests. For example test_properties.
EXPECT_PROPERTY persist.sys.boot.reason reboot,its_just_so_hard ${flag}
EXPECT_PROPERTY sys.boot.reason.last reboot,its_just_so_hard
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs reboot,its_just_so_hard
}
@ -1049,7 +1056,8 @@ run_bootloader() {
# Check values
EXPECT_PROPERTY ro.boot.bootreason "${bootloader_expected}"
EXPECT_PROPERTY sys.boot.reason "${sys_expected}"
EXPECT_PROPERTY persist.sys.boot.reason "${last_expected}"
EXPECT_PROPERTY sys.boot.reason.last "${last_expected}"
EXPECT_PROPERTY persist.sys.boot.reason ""
report_bootstat_logs "${sys_expected}"
}

View file

@ -735,6 +735,7 @@ bool addKernelPanicSubReason(const std::string& content, std::string& ret) {
const char system_reboot_reason_property[] = "sys.boot.reason";
const char last_reboot_reason_property[] = LAST_REBOOT_REASON_PROPERTY;
const char last_last_reboot_reason_property[] = "sys.boot.reason.last";
const char bootloader_reboot_reason_property[] = "ro.boot.bootreason";
// Scrub, Sanitize, Standardize and Enhance the boot reason string supplied.
@ -985,10 +986,6 @@ std::string BootReasonStrToReason(const std::string& boot_reason) {
}
LOG(INFO) << "Canonical boot reason: " << ret;
if (isKernelRebootReason(ret) && (GetProperty(last_reboot_reason_property) != "")) {
// Rewrite as it must be old news, kernel reasons trump user space.
SetProperty(last_reboot_reason_property, ret);
}
return ret;
}
@ -1118,6 +1115,15 @@ void SetSystemBootReason() {
const std::string system_boot_reason(BootReasonStrToReason(bootloader_boot_reason));
// Record the scrubbed system_boot_reason to the property
SetProperty(system_reboot_reason_property, system_boot_reason);
// Shift last_reboot_reason_property to last_last_reboot_reason_property
std::string last_boot_reason(GetProperty(last_reboot_reason_property));
if (last_boot_reason.empty() || isKernelRebootReason(system_boot_reason)) {
last_boot_reason = system_boot_reason;
} else {
transformReason(last_boot_reason);
}
SetProperty(last_last_reboot_reason_property, last_boot_reason);
SetProperty(last_reboot_reason_property, "");
}
// Records several metrics related to the time it takes to boot the device,