init: use a property instead of file to communicate cold boot done

Ueventd can't set properties currently, but this is an artificial
limitation, since ueventd communicates to init that it has finished
cold boot via a file, and init polls this file instead of returning to
the epoll loop, where properties are handled.

This change replaces that file with a property and thus frees ueventd
to be able to set properties.

Bug: 62301678
Test: boot, check that properties are set
Change-Id: I985688e9299456efcb2dfeef9b92668991aa9c05
This commit is contained in:
Tom Cherry 2019-06-10 17:49:59 -07:00
parent bc1ccde87c
commit 39fafedc5a
3 changed files with 14 additions and 19 deletions

View File

@ -198,6 +198,14 @@ void property_changed(const std::string& name, const std::string& value) {
if (property_triggers_enabled) ActionManager::GetInstance().QueuePropertyChange(name, value);
// We always record how long init waited for ueventd to tell us cold boot finished.
// If we aren't waiting on this property, it means that ueventd finished before we even started
// to wait.
if (name == kColdBootDoneProp) {
auto time_waited = waiting_for_prop ? waiting_for_prop->duration().count() : 0;
property_set("ro.boottime.init.cold_boot_wait", std::to_string(time_waited));
}
if (waiting_for_prop) {
if (wait_prop_name == name && wait_prop_value == value) {
LOG(INFO) << "Wait for property '" << wait_prop_name << "=" << wait_prop_value
@ -331,23 +339,10 @@ bool HandleControlMessage(const std::string& msg, const std::string& name, pid_t
}
static Result<void> wait_for_coldboot_done_action(const BuiltinArguments& args) {
Timer t;
LOG(VERBOSE) << "Waiting for " COLDBOOT_DONE "...";
// Historically we had a 1s timeout here because we weren't otherwise
// tracking boot time, and many OEMs made their sepolicy regular
// expressions too expensive (http://b/19899875).
// Now we're tracking boot time, just log the time taken to a system
// property. We still panic if it takes more than a minute though,
// because any build that slow isn't likely to boot at all, and we'd
// rather any test lab devices fail back to the bootloader.
if (wait_for_file(COLDBOOT_DONE, 60s) < 0) {
LOG(FATAL) << "Timed out waiting for " COLDBOOT_DONE;
if (!start_waiting_for_property(kColdBootDoneProp, "true")) {
LOG(FATAL) << "Could not wait for '" << kColdBootDoneProp << "'";
}
property_set("ro.boottime.init.cold_boot_wait", std::to_string(t.duration().count()));
return {};
}

View File

@ -214,7 +214,7 @@ void ColdBoot::Run() {
WaitForSubProcesses();
close(open(COLDBOOT_DONE, O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
android::base::SetProperty(kColdBootDoneProp, "true");
LOG(INFO) << "Coldboot took " << cold_boot_timer.duration().count() / 1000.0f << " seconds";
}
@ -255,7 +255,7 @@ int ueventd_main(int argc, char** argv) {
}
UeventListener uevent_listener(ueventd_configuration.uevent_socket_rcvbuf_size);
if (access(COLDBOOT_DONE, F_OK) != 0) {
if (!android::base::GetBoolProperty(kColdBootDoneProp, false)) {
ColdBoot cold_boot(uevent_listener, uevent_handlers);
cold_boot.Run();
}

View File

@ -30,14 +30,14 @@
#include "result.h"
#define COLDBOOT_DONE "/dev/.coldboot_done"
using android::base::boot_clock;
using namespace std::chrono_literals;
namespace android {
namespace init {
static const char kColdBootDoneProp[] = "ro.cold_boot_done";
int CreateSocket(const char* name, int type, bool passcred, mode_t perm, uid_t uid, gid_t gid,
const char* socketcon);