Skip to content

Commit 1ab3dfc

Browse files
author
Tom Cherry
committed
Reland^2: "init: run property service in a thread"
It's been a long standing issue that init cannot respond to property set messages when it is running a builtin command. This is particularly problematic when the commands involve IPC to vold or other daemons, as it prevents them from being able to set properties. This change has init run property service in a thread, which eliminates the above issue. This change may also serve as a starting block to running property service in an entirely different process to better isolate init from handling property requests. Reland: during reboot, init stops processing property_changed messages from property service, since it will not act on these anyway. This had an unexpected effect of causing future property_set calls to block indefinitely, since the buffer between init and property_service was filling up and the send() call from property_service would then block. This change has init tell property_service to stop sending it property_changed messages once reboot begins. Test: CF boots, walleye boots, properties are set appropriately Change-Id: I26902708e8be788caa6dbcf4b6d2968d90962785
1 parent 50e408d commit 1ab3dfc

11 files changed

+371
-147
lines changed

init/Android.bp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ cc_library_static {
130130
"persistent_properties.cpp",
131131
"persistent_properties.proto",
132132
"property_service.cpp",
133+
"property_service.proto",
133134
"property_type.cpp",
134135
"reboot.cpp",
135136
"reboot_utils.cpp",

init/builtins.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
using namespace std::literals::string_literals;
8181

8282
using android::base::Basename;
83+
using android::base::StartsWith;
8384
using android::base::StringPrintf;
8485
using android::base::unique_fd;
8586
using android::fs_mgr::Fstab;
@@ -701,6 +702,15 @@ static Result<void> do_swapon_all(const BuiltinArguments& args) {
701702
}
702703

703704
static Result<void> do_setprop(const BuiltinArguments& args) {
705+
if (StartsWith(args[1], "ctl.")) {
706+
return Error()
707+
<< "Cannot set ctl. properties from init; call the Service functions directly";
708+
}
709+
if (args[1] == kRestoreconProperty) {
710+
return Error() << "Cannot set '" << kRestoreconProperty
711+
<< "' from init; use the restorecon builtin directly";
712+
}
713+
704714
property_set(args[1], args[2]);
705715
return {};
706716
}
@@ -1016,7 +1026,20 @@ static Result<void> do_loglevel(const BuiltinArguments& args) {
10161026
}
10171027

10181028
static Result<void> do_load_persist_props(const BuiltinArguments& args) {
1019-
load_persist_props();
1029+
// Devices with FDE have load_persist_props called twice; the first time when the temporary
1030+
// /data partition is mounted and then again once /data is truly mounted. We do not want to
1031+
// read persistent properties from the temporary /data partition or mark persistent properties
1032+
// as having been loaded during the first call, so we return in that case.
1033+
std::string crypto_state = android::base::GetProperty("ro.crypto.state", "");
1034+
std::string crypto_type = android::base::GetProperty("ro.crypto.type", "");
1035+
if (crypto_state == "encrypted" && crypto_type == "block") {
1036+
static size_t num_calls = 0;
1037+
if (++num_calls == 1) return {};
1038+
}
1039+
1040+
SendLoadPersistentPropertiesMessage();
1041+
1042+
start_waiting_for_property("ro.persistent_properties.ready", "true");
10201043
return {};
10211044
}
10221045

init/init.cpp

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
#include <sys/types.h>
2929
#include <unistd.h>
3030

31+
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
32+
#include <sys/_system_properties.h>
33+
3134
#include <functional>
3235
#include <map>
3336
#include <memory>
@@ -61,6 +64,7 @@
6164
#include "mount_handler.h"
6265
#include "mount_namespace.h"
6366
#include "property_service.h"
67+
#include "proto_utils.h"
6468
#include "reboot.h"
6569
#include "reboot_utils.h"
6670
#include "security.h"
@@ -69,6 +73,7 @@
6973
#include "service.h"
7074
#include "service_parser.h"
7175
#include "sigchld_handler.h"
76+
#include "system/core/init/property_service.pb.h"
7277
#include "util.h"
7378

7479
using namespace std::chrono_literals;
@@ -90,6 +95,7 @@ static int property_triggers_enabled = 0;
9095
static char qemu[32];
9196

9297
static int signal_fd = -1;
98+
static int property_fd = -1;
9399

94100
static std::unique_ptr<Timer> waiting_for_prop(nullptr);
95101
static std::string wait_prop_name;
@@ -615,6 +621,60 @@ static void RecordStageBoottimes(const boot_clock::time_point& second_stage_star
615621
selinux_start_time_ns));
616622
}
617623

624+
void SendLoadPersistentPropertiesMessage() {
625+
auto init_message = InitMessage{};
626+
init_message.set_load_persistent_properties(true);
627+
if (auto result = SendMessage(property_fd, init_message); !result) {
628+
LOG(ERROR) << "Failed to send load persistent properties message: " << result.error();
629+
}
630+
}
631+
632+
void SendStopSendingMessagesMessage() {
633+
auto init_message = InitMessage{};
634+
init_message.set_stop_sending_messages(true);
635+
if (auto result = SendMessage(property_fd, init_message); !result) {
636+
LOG(ERROR) << "Failed to send load persistent properties message: " << result.error();
637+
}
638+
}
639+
640+
static void HandlePropertyFd() {
641+
auto message = ReadMessage(property_fd);
642+
if (!message) {
643+
LOG(ERROR) << "Could not read message from property service: " << message.error();
644+
return;
645+
}
646+
647+
auto property_message = PropertyMessage{};
648+
if (!property_message.ParseFromString(*message)) {
649+
LOG(ERROR) << "Could not parse message from property service";
650+
return;
651+
}
652+
653+
switch (property_message.msg_case()) {
654+
case PropertyMessage::kControlMessage: {
655+
auto& control_message = property_message.control_message();
656+
bool success = HandleControlMessage(control_message.msg(), control_message.name(),
657+
control_message.pid());
658+
659+
uint32_t response = success ? PROP_SUCCESS : PROP_ERROR_HANDLE_CONTROL_MESSAGE;
660+
if (control_message.has_fd()) {
661+
int fd = control_message.fd();
662+
TEMP_FAILURE_RETRY(send(fd, &response, sizeof(response), 0));
663+
close(fd);
664+
}
665+
break;
666+
}
667+
case PropertyMessage::kChangedMessage: {
668+
auto& changed_message = property_message.changed_message();
669+
property_changed(changed_message.name(), changed_message.value());
670+
break;
671+
}
672+
default:
673+
LOG(ERROR) << "Unknown message type from property service: "
674+
<< property_message.msg_case();
675+
}
676+
}
677+
618678
int SecondStageMain(int argc, char** argv) {
619679
if (REBOOT_BOOTLOADER_ON_PANIC) {
620680
InstallRebootSignalHandlers();
@@ -686,7 +746,12 @@ int SecondStageMain(int argc, char** argv) {
686746
UmountDebugRamdisk();
687747
fs_mgr_vendor_overlay_mount_all();
688748
export_oem_lock_status();
689-
StartPropertyService(&epoll);
749+
750+
StartPropertyService(&property_fd);
751+
if (auto result = epoll.RegisterHandler(property_fd, HandlePropertyFd); !result) {
752+
LOG(FATAL) << "Could not register epoll handler for property fd: " << result.error();
753+
}
754+
690755
MountHandler mount_handler(&epoll);
691756
set_usb_controller();
692757

init/init.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,15 @@ namespace init {
3131
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list);
3232
Parser CreateServiceOnlyParser(ServiceList& service_list);
3333

34-
bool HandleControlMessage(const std::string& msg, const std::string& arg, pid_t pid);
35-
36-
void property_changed(const std::string& name, const std::string& value);
37-
3834
bool start_waiting_for_property(const char *name, const char *value);
3935

4036
void DumpState();
4137

4238
void ResetWaitForProp();
4339

40+
void SendLoadPersistentPropertiesMessage();
41+
void SendStopSendingMessagesMessage();
42+
4443
int SecondStageMain(int argc, char** argv);
4544

4645
} // namespace init

0 commit comments

Comments
 (0)