Add sysprops for start & end of userspace reboot

There will be useful in debugging/logging events to statsd.

Also as part of this CL, sys.init.userspace_reboot.in_progress property
is now used as a mean of synchronization. It is set directly in
DoUserspaceReboot, to make sure that all the setprop actions triggered
by userspace-reboot-requested were processed.

Test: adb reboot userspace
Test: adb shell getprop sys.init.userspace_reboot.last_started
Test: adb shell getprop sys.init.userspace_reboot.last_finished
Bug: 135984674
Change-Id: I9debcd4f058e790855200d5295344dafb30e496a
This commit is contained in:
Nikita Ioffe 2019-11-13 21:47:06 +00:00
parent 8e2f75e319
commit c0df1874ad
4 changed files with 28 additions and 5 deletions

View File

@ -65,6 +65,7 @@
#include "action_manager.h" #include "action_manager.h"
#include "bootchart.h" #include "bootchart.h"
#include "builtin_arguments.h"
#include "fscrypt_init_extensions.h" #include "fscrypt_init_extensions.h"
#include "init.h" #include "init.h"
#include "mount_namespace.h" #include "mount_namespace.h"
@ -1216,6 +1217,15 @@ static Result<void> do_enter_default_mount_ns(const BuiltinArguments& args) {
} }
} }
static Result<void> do_finish_userspace_reboot(const BuiltinArguments&) {
LOG(INFO) << "Userspace reboot successfully finished";
boot_clock::time_point now = boot_clock::now();
property_set("sys.init.userspace_reboot.last_finished",
std::to_string(now.time_since_epoch().count()));
property_set(kUserspaceRebootInProgress, "0");
return {};
}
// Builtin-function-map start // Builtin-function-map start
const BuiltinFunctionMap& GetBuiltinFunctionMap() { const BuiltinFunctionMap& GetBuiltinFunctionMap() {
constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max(); constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max();
@ -1237,6 +1247,7 @@ const BuiltinFunctionMap& GetBuiltinFunctionMap() {
{"exec_background", {1, kMax, {false, do_exec_background}}}, {"exec_background", {1, kMax, {false, do_exec_background}}},
{"exec_start", {1, 1, {false, do_exec_start}}}, {"exec_start", {1, 1, {false, do_exec_start}}},
{"export", {2, 2, {false, do_export}}}, {"export", {2, 2, {false, do_export}}},
{"finish_userspace_reboot", {0, 0, {false, do_finish_userspace_reboot}}},
{"hostname", {1, 1, {true, do_hostname}}}, {"hostname", {1, 1, {true, do_hostname}}},
{"ifup", {1, 1, {true, do_ifup}}}, {"ifup", {1, 1, {true, do_ifup}}},
{"init_user0", {0, 0, {false, do_init_user0}}}, {"init_user0", {0, 0, {false, do_init_user0}}},

View File

@ -69,10 +69,13 @@
using namespace std::literals; using namespace std::literals;
using android::base::boot_clock;
using android::base::GetBoolProperty; using android::base::GetBoolProperty;
using android::base::SetProperty;
using android::base::Split; using android::base::Split;
using android::base::Timer; using android::base::Timer;
using android::base::unique_fd; using android::base::unique_fd;
using android::base::WaitForProperty;
using android::base::WriteStringToFile; using android::base::WriteStringToFile;
namespace android { namespace android {
@ -728,16 +731,21 @@ static Result<void> UnmountAllApexes() {
static Result<void> DoUserspaceReboot() { static Result<void> DoUserspaceReboot() {
LOG(INFO) << "Userspace reboot initiated"; LOG(INFO) << "Userspace reboot initiated";
boot_clock::time_point now = boot_clock::now();
property_set("sys.init.userspace_reboot.last_started",
std::to_string(now.time_since_epoch().count()));
auto guard = android::base::make_scope_guard([] { auto guard = android::base::make_scope_guard([] {
// Leave shutdown so that we can handle a full reboot. // Leave shutdown so that we can handle a full reboot.
LeaveShutdown(); LeaveShutdown();
trigger_shutdown("reboot,abort-userspace-reboot"); trigger_shutdown("reboot,abort-userspace-reboot");
}); });
// Triggering userspace-reboot-requested will result in a bunch of set_prop // Triggering userspace-reboot-requested will result in a bunch of setprop
// actions. We should make sure, that all of them are propagated before // actions. We should make sure, that all of them are propagated before
// proceeding with userspace reboot. // proceeding with userspace reboot. Synchronously setting kUserspaceRebootInProgress property
// TODO(b/135984674): implement proper synchronization logic. // is not perfect, but it should do the trick.
std::this_thread::sleep_for(500ms); if (property_set(kUserspaceRebootInProgress, "1") != 0) {
return Error() << "Failed to set property " << kUserspaceRebootInProgress;
}
EnterShutdown(); EnterShutdown();
std::vector<Service*> stop_first; std::vector<Service*> stop_first;
// Remember the services that were enabled. We will need to manually enable them again otherwise // Remember the services that were enabled. We will need to manually enable them again otherwise

View File

@ -22,6 +22,8 @@
namespace android { namespace android {
namespace init { namespace init {
static const constexpr char* kUserspaceRebootInProgress = "sys.init.userspace_reboot.in_progress";
// Parses and handles a setprop sys.powerctl message. // Parses and handles a setprop sys.powerctl message.
void HandlePowerctlMessage(const std::string& command); void HandlePowerctlMessage(const std::string& command);

View File

@ -925,7 +925,6 @@ on init && property:ro.debuggable=1
on userspace-reboot-requested on userspace-reboot-requested
# TODO(b/135984674): reset all necessary properties here. # TODO(b/135984674): reset all necessary properties here.
setprop sys.init.userspace_reboot_in_progress 1
setprop sys.boot_completed 0 setprop sys.boot_completed 0
setprop sys.init.updatable_crashing 0 setprop sys.init.updatable_crashing 0
setprop apexd.status "" setprop apexd.status ""
@ -945,3 +944,6 @@ on userspace-reboot-resume
trigger zygote-start trigger zygote-start
trigger early-boot trigger early-boot
trigger boot trigger boot
on property:sys.boot_completed=1 && property:sys.init.userspace_reboot.in_progress=1
finish_userspace_reboot