From 39fafedc5a0f8c7e53e9f441a3ff6a7a0fc54bd3 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Mon, 10 Jun 2019 17:49:59 -0700 Subject: [PATCH] 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 --- init/init.cpp | 25 ++++++++++--------------- init/ueventd.cpp | 4 ++-- init/util.h | 4 ++-- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/init/init.cpp b/init/init.cpp index 1412e4a5e..0d3b99f8d 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -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 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 {}; } diff --git a/init/ueventd.cpp b/init/ueventd.cpp index d700c461c..3e33f2f77 100644 --- a/init/ueventd.cpp +++ b/init/ueventd.cpp @@ -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(); } diff --git a/init/util.h b/init/util.h index 770084b87..1929cb5b1 100644 --- a/init/util.h +++ b/init/util.h @@ -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);