Loading init/builtins.cpp +16 −15 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ using namespace std::literals::string_literals; using android::base::Basename; using android::base::SetProperty; using android::base::StartsWith; using android::base::StringPrintf; using android::base::unique_fd; Loading Loading @@ -561,16 +562,16 @@ static Result<void> queue_fs_event(int code, bool userdata_remount) { LOG(ERROR) << "Userdata remount is not supported on FDE devices. How did you get here?"; trigger_shutdown("reboot,requested-userdata-remount-on-fde-device"); } property_set("ro.crypto.state", "encrypted"); property_set("ro.crypto.type", "block"); SetProperty("ro.crypto.state", "encrypted"); SetProperty("ro.crypto.type", "block"); ActionManager::GetInstance().QueueEventTrigger("defaultcrypto"); return {}; } else if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) { property_set("ro.crypto.state", "unencrypted"); SetProperty("ro.crypto.state", "unencrypted"); ActionManager::GetInstance().QueueEventTrigger("nonencrypted"); return {}; } else if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) { property_set("ro.crypto.state", "unsupported"); SetProperty("ro.crypto.state", "unsupported"); ActionManager::GetInstance().QueueEventTrigger("nonencrypted"); return {}; } else if (code == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) { Loading @@ -586,8 +587,8 @@ static Result<void> queue_fs_event(int code, bool userdata_remount) { if (!FscryptInstallKeyring()) { return Error() << "FscryptInstallKeyring() failed"; } property_set("ro.crypto.state", "encrypted"); property_set("ro.crypto.type", "file"); SetProperty("ro.crypto.state", "encrypted"); SetProperty("ro.crypto.type", "file"); // Although encrypted, we have device key, so we do not need to // do anything different from the nonencrypted case. Loading @@ -597,8 +598,8 @@ static Result<void> queue_fs_event(int code, bool userdata_remount) { if (!FscryptInstallKeyring()) { return Error() << "FscryptInstallKeyring() failed"; } property_set("ro.crypto.state", "encrypted"); property_set("ro.crypto.type", "file"); SetProperty("ro.crypto.state", "encrypted"); SetProperty("ro.crypto.type", "file"); // Although encrypted, vold has already set the device up, so we do not need to // do anything different from the nonencrypted case. Loading @@ -608,8 +609,8 @@ static Result<void> queue_fs_event(int code, bool userdata_remount) { if (!FscryptInstallKeyring()) { return Error() << "FscryptInstallKeyring() failed"; } property_set("ro.crypto.state", "encrypted"); property_set("ro.crypto.type", "file"); SetProperty("ro.crypto.state", "encrypted"); SetProperty("ro.crypto.type", "file"); // Although encrypted, vold has already set the device up, so we do not need to // do anything different from the nonencrypted case. Loading Loading @@ -662,7 +663,7 @@ static Result<void> do_mount_all(const BuiltinArguments& args) { } auto mount_fstab_return_code = fs_mgr_mount_all(&fstab, mount_mode); property_set(prop_name, std::to_string(t.duration().count())); SetProperty(prop_name, std::to_string(t.duration().count())); if (import_rc && SelinuxGetVendorAndroidVersion() <= __ANDROID_API_Q__) { /* Paths of .rc files are specified at the 2nd argument and beyond */ Loading Loading @@ -718,7 +719,7 @@ static Result<void> do_setprop(const BuiltinArguments& args) { << "' from init; use the restorecon builtin directly"; } property_set(args[1], args[2]); SetProperty(args[1], args[2]); return {}; } Loading Loading @@ -832,7 +833,7 @@ static Result<void> do_verity_update_state(const BuiltinArguments& args) { // To be consistent in vboot 1.0 and vboot 2.0 (AVB), use "system" for the partition even // for system as root, so it has property [partition.system.verified]. std::string partition = entry.mount_point == "/" ? "system" : Basename(entry.mount_point); property_set("partition." + partition + ".verified", std::to_string(mode)); SetProperty("partition." + partition + ".verified", std::to_string(mode)); } return {}; Loading Loading @@ -1221,7 +1222,7 @@ 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", SetProperty("sys.init.userspace_reboot.last_finished", std::to_string(now.time_since_epoch().count())); if (!android::sysprop::InitProperties::userspace_reboot_in_progress(false)) { return Error() << "Failed to set sys.init.userspace_reboot.in_progress property"; Loading init/host_init_stubs.h +0 −9 Original line number Diff line number Diff line Loading @@ -39,15 +39,6 @@ namespace init { inline bool CanReadProperty(const std::string&, const std::string&) { return true; } inline uint32_t SetProperty(const std::string& key, const std::string& value) { android::base::SetProperty(key, value); return 0; } inline uint32_t (*property_set)(const std::string& name, const std::string& value) = SetProperty; inline uint32_t HandlePropertySet(const std::string&, const std::string&, const std::string&, const ucred&, std::string*) { return 0; } // reboot_utils.h inline void SetFatalRebootTarget() {} Loading init/init.cpp +40 −113 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ using namespace std::string_literals; using android::base::boot_clock; using android::base::GetProperty; using android::base::ReadFileToString; using android::base::SetProperty; using android::base::StringPrintf; using android::base::Timer; using android::base::Trim; Loading @@ -91,8 +92,6 @@ namespace init { static int property_triggers_enabled = 0; static char qemu[32]; static int signal_fd = -1; static int property_fd = -1; Loading @@ -101,7 +100,6 @@ static std::string wait_prop_name; static std::string wait_prop_value; static std::string shutdown_command; static bool do_shutdown = false; static bool load_debug_prop = false; static std::unique_ptr<Subcontext> subcontext; Loading Loading @@ -208,7 +206,7 @@ void property_changed(const std::string& name, const std::string& value) { // 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)); SetProperty("ro.boottime.init.cold_boot_wait", std::to_string(time_waited)); } if (waiting_for_prop) { Loading Loading @@ -364,87 +362,17 @@ static Result<void> SetupCgroupsAction(const BuiltinArguments&) { return {}; } static void import_kernel_nv(const std::string& key, const std::string& value, bool for_emulator) { if (key.empty()) return; if (for_emulator) { // In the emulator, export any kernel option with the "ro.kernel." prefix. property_set("ro.kernel." + key, value); return; } if (key == "qemu") { strlcpy(qemu, value.c_str(), sizeof(qemu)); } else if (android::base::StartsWith(key, "androidboot.")) { property_set("ro.boot." + key.substr(12), value); } } static void export_oem_lock_status() { if (!android::base::GetBoolProperty("ro.oem_unlock_supported", false)) { return; } import_kernel_cmdline( false, [](const std::string& key, const std::string& value, bool in_qemu) { ImportKernelCmdline([](const std::string& key, const std::string& value) { if (key == "androidboot.verifiedbootstate") { property_set("ro.boot.flash.locked", value == "orange" ? "0" : "1"); SetProperty("ro.boot.flash.locked", value == "orange" ? "0" : "1"); } }); } static void export_kernel_boot_props() { constexpr const char* UNSET = ""; struct { const char *src_prop; const char *dst_prop; const char *default_value; } prop_map[] = { { "ro.boot.serialno", "ro.serialno", UNSET, }, { "ro.boot.mode", "ro.bootmode", "unknown", }, { "ro.boot.baseband", "ro.baseband", "unknown", }, { "ro.boot.bootloader", "ro.bootloader", "unknown", }, { "ro.boot.hardware", "ro.hardware", "unknown", }, { "ro.boot.revision", "ro.revision", "0", }, }; for (const auto& prop : prop_map) { std::string value = GetProperty(prop.src_prop, prop.default_value); if (value != UNSET) property_set(prop.dst_prop, value); } } static void process_kernel_dt() { if (!is_android_dt_value_expected("compatible", "android,firmware")) { return; } std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(get_android_dt_dir().c_str()), closedir); if (!dir) return; std::string dt_file; struct dirent *dp; while ((dp = readdir(dir.get())) != NULL) { if (dp->d_type != DT_REG || !strcmp(dp->d_name, "compatible") || !strcmp(dp->d_name, "name")) { continue; } std::string file_name = get_android_dt_dir() + dp->d_name; android::base::ReadFileToString(file_name, &dt_file); std::replace(dt_file.begin(), dt_file.end(), ',', '.'); property_set("ro.boot."s + dp->d_name, dt_file); } } static void process_kernel_cmdline() { // The first pass does the common stuff, and finds if we are in qemu. // The second pass is only necessary for qemu to export all kernel params // as properties. import_kernel_cmdline(false, import_kernel_nv); if (qemu[0]) import_kernel_cmdline(true, import_kernel_nv); } static Result<void> property_enable_triggers_action(const BuiltinArguments& args) { /* Enable property triggers. */ property_triggers_enabled = 1; Loading @@ -468,7 +396,7 @@ static void set_usb_controller() { while ((dp = readdir(dir.get())) != nullptr) { if (dp->d_name[0] == '.') continue; property_set("sys.usb.controller", dp->d_name); SetProperty("sys.usb.controller", dp->d_name); break; } } Loading Loading @@ -591,7 +519,7 @@ static void RecordStageBoottimes(const boot_clock::time_point& second_stage_star int64_t first_stage_start_time_ns = -1; if (auto first_stage_start_time_str = getenv(kEnvFirstStageStartedAt); first_stage_start_time_str) { property_set("ro.boottime.init", first_stage_start_time_str); SetProperty("ro.boottime.init", first_stage_start_time_str); android::base::ParseInt(first_stage_start_time_str, &first_stage_start_time_ns); } unsetenv(kEnvFirstStageStartedAt); Loading @@ -605,9 +533,9 @@ static void RecordStageBoottimes(const boot_clock::time_point& second_stage_star if (selinux_start_time_ns == -1) return; if (first_stage_start_time_ns == -1) return; property_set("ro.boottime.init.first_stage", SetProperty("ro.boottime.init.first_stage", std::to_string(selinux_start_time_ns - first_stage_start_time_ns)); property_set("ro.boottime.init.selinux", SetProperty("ro.boottime.init.selinux", std::to_string(second_stage_start_time.time_since_epoch().count() - selinux_start_time_ns)); } Loading Loading @@ -706,34 +634,27 @@ int SecondStageMain(int argc, char** argv) { // Indicate that booting is in progress to background fw loaders, etc. close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000)); property_init(); // If arguments are passed both on the command line and in DT, // properties set in DT always have priority over the command-line ones. process_kernel_dt(); process_kernel_cmdline(); // Propagate the kernel variables to internal variables // used by init as well as the current required properties. export_kernel_boot_props(); // Make the time that init stages started available for bootstat to log. RecordStageBoottimes(start_time); // Set libavb version for Framework-only OTA match in Treble build. const char* avb_version = getenv("INIT_AVB_VERSION"); if (avb_version) property_set("ro.boot.avb_version", avb_version); // See if need to load debug props to allow adb root, when the device is unlocked. const char* force_debuggable_env = getenv("INIT_FORCE_DEBUGGABLE"); bool load_debug_prop = false; if (force_debuggable_env && AvbHandle::IsDeviceUnlocked()) { load_debug_prop = "true"s == force_debuggable_env; } // Clean up our environment. unsetenv("INIT_AVB_VERSION"); unsetenv("INIT_FORCE_DEBUGGABLE"); // Umount the debug ramdisk so property service doesn't read .prop files from there, when it // is not meant to. if (!load_debug_prop) { UmountDebugRamdisk(); } PropertyInit(); // Umount the debug ramdisk after property service has read the .prop files when it means to. if (load_debug_prop) { UmountDebugRamdisk(); } // Now set up SELinux for second stage. SelinuxSetupKernelLogging(); SelabelInitialize(); Loading @@ -746,16 +667,22 @@ int SecondStageMain(int argc, char** argv) { InstallSignalFdHandler(&epoll); property_load_boot_defaults(load_debug_prop); UmountDebugRamdisk(); fs_mgr_vendor_overlay_mount_all(); export_oem_lock_status(); StartPropertyService(&property_fd); if (auto result = epoll.RegisterHandler(property_fd, HandlePropertyFd); !result) { LOG(FATAL) << "Could not register epoll handler for property fd: " << result.error(); } // Make the time that init stages started available for bootstat to log. RecordStageBoottimes(start_time); // Set libavb version for Framework-only OTA match in Treble build. if (const char* avb_version = getenv("INIT_AVB_VERSION"); avb_version != nullptr) { SetProperty("ro.boot.avb_version", avb_version); } unsetenv("INIT_AVB_VERSION"); fs_mgr_vendor_overlay_mount_all(); export_oem_lock_status(); MountHandler mount_handler(&epoll); set_usb_controller(); Loading @@ -779,9 +706,9 @@ int SecondStageMain(int argc, char** argv) { // Make the GSI status available before scripts start running. if (android::gsi::IsGsiRunning()) { property_set("ro.gsid.image_running", "1"); SetProperty("ro.gsid.image_running", "1"); } else { property_set("ro.gsid.image_running", "0"); SetProperty("ro.gsid.image_running", "0"); } am.QueueBuiltinAction(SetupCgroupsAction, "SetupCgroups"); Loading init/mount_handler.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -38,7 +38,6 @@ #include <libdm/dm.h> #include "epoll.h" #include "property_service.h" namespace android { namespace init { Loading Loading @@ -96,7 +95,7 @@ void SetMountProperty(const MountHandlerEntry& entry, bool add) { // handling, except for clearing non-existent or already clear property. // Goal is reduction of empty properties and associated triggers. if (value.empty() && android::base::GetProperty(mount_prop, "").empty()) return; property_set(mount_prop, value); android::base::SetProperty(mount_prop, value); } } // namespace Loading init/property_service.cpp +108 −41 Original line number Diff line number Diff line Loading @@ -97,8 +97,6 @@ static bool accept_messages = false; static PropertyInfoAreaFile property_info_area; void CreateSerializedPropertyInfo(); struct PropertyAuditData { const ucred* cr; const char* name; Loading @@ -117,21 +115,6 @@ static int PropertyAuditCallback(void* data, security_class_t /*cls*/, char* buf return 0; } void property_init() { selinux_callback cb; cb.func_audit = PropertyAuditCallback; selinux_set_callback(SELINUX_CB_AUDIT, cb); mkdir("/dev/__properties__", S_IRWXU | S_IXGRP | S_IXOTH); CreateSerializedPropertyInfo(); if (__system_property_area_init()) { LOG(FATAL) << "Failed to initialize property area"; } if (!property_info_area.LoadDefaultPath()) { LOG(FATAL) << "Failed to load serialized property info file"; } } bool CanReadProperty(const std::string& source_context, const std::string& name) { const char* target_context = nullptr; property_info_area->GetPropertyInfo(name.c_str(), &target_context, nullptr); Loading Loading @@ -527,20 +510,6 @@ uint32_t HandlePropertySet(const std::string& name, const std::string& value, return PropertySet(name, value, error); } uint32_t InitPropertySet(const std::string& name, const std::string& value) { uint32_t result = 0; ucred cr = {.pid = 1, .uid = 0, .gid = 0}; std::string error; result = HandlePropertySet(name, value, kInitContext, cr, nullptr, &error); if (result != PROP_SUCCESS) { LOG(ERROR) << "Init cannot set '" << name << "' to '" << value << "': " << error; } return result; } uint32_t (*property_set)(const std::string& name, const std::string& value) = InitPropertySet; static void handle_property_set_fd() { static constexpr uint32_t kDefaultSocketTimeout = 2000; /* ms */ Loading Loading @@ -634,6 +603,18 @@ static void handle_property_set_fd() { } } uint32_t InitPropertySet(const std::string& name, const std::string& value) { uint32_t result = 0; ucred cr = {.pid = 1, .uid = 0, .gid = 0}; std::string error; result = HandlePropertySet(name, value, kInitContext, cr, nullptr, &error); if (result != PROP_SUCCESS) { LOG(ERROR) << "Init cannot set '" << name << "' to '" << value << "': " << error; } return result; } static bool load_properties_from_file(const char*, const char*, std::map<std::string, std::string>*); Loading Loading @@ -765,11 +746,11 @@ static void update_sys_usb_config() { bool is_debuggable = android::base::GetBoolProperty("ro.debuggable", false); std::string config = android::base::GetProperty("persist.sys.usb.config", ""); if (config.empty()) { property_set("persist.sys.usb.config", is_debuggable ? "adb" : "none"); InitPropertySet("persist.sys.usb.config", is_debuggable ? "adb" : "none"); } else if (is_debuggable && config.find("adb") == std::string::npos && config.length() + 4 < PROP_VALUE_MAX) { config.append(",adb"); property_set("persist.sys.usb.config", config); InitPropertySet("persist.sys.usb.config", config); } } Loading Loading @@ -890,7 +871,7 @@ static void property_derive_build_fingerprint() { } } void property_load_boot_defaults(bool load_debug_prop) { void PropertyLoadBootDefaults() { // TODO(b/117892318): merge prop.default and build.prop files into one // We read the properties and their values into a map, in order to always allow properties // loaded in the later property files to override the properties in loaded in the earlier Loading @@ -916,7 +897,7 @@ void property_load_boot_defaults(bool load_debug_prop) { load_properties_from_file("/product/build.prop", nullptr, &properties); load_properties_from_file("/factory/factory.prop", "ro.*", &properties); if (load_debug_prop) { if (access(kDebugRamdiskProp, R_OK) == 0) { LOG(INFO) << "Loading " << kDebugRamdiskProp; load_properties_from_file(kDebugRamdiskProp, nullptr, &properties); } Loading Loading @@ -1009,6 +990,97 @@ void CreateSerializedPropertyInfo() { selinux_android_restorecon(kPropertyInfosPath, 0); } static void ExportKernelBootProps() { constexpr const char* UNSET = ""; struct { const char* src_prop; const char* dst_prop; const char* default_value; } prop_map[] = { // clang-format off { "ro.boot.serialno", "ro.serialno", UNSET, }, { "ro.boot.mode", "ro.bootmode", "unknown", }, { "ro.boot.baseband", "ro.baseband", "unknown", }, { "ro.boot.bootloader", "ro.bootloader", "unknown", }, { "ro.boot.hardware", "ro.hardware", "unknown", }, { "ro.boot.revision", "ro.revision", "0", }, // clang-format on }; for (const auto& prop : prop_map) { std::string value = GetProperty(prop.src_prop, prop.default_value); if (value != UNSET) InitPropertySet(prop.dst_prop, value); } } static void ProcessKernelDt() { if (!is_android_dt_value_expected("compatible", "android,firmware")) { return; } std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(get_android_dt_dir().c_str()), closedir); if (!dir) return; std::string dt_file; struct dirent* dp; while ((dp = readdir(dir.get())) != NULL) { if (dp->d_type != DT_REG || !strcmp(dp->d_name, "compatible") || !strcmp(dp->d_name, "name")) { continue; } std::string file_name = get_android_dt_dir() + dp->d_name; android::base::ReadFileToString(file_name, &dt_file); std::replace(dt_file.begin(), dt_file.end(), ',', '.'); InitPropertySet("ro.boot."s + dp->d_name, dt_file); } } static void ProcessKernelCmdline() { bool for_emulator = false; ImportKernelCmdline([&](const std::string& key, const std::string& value) { if (key == "qemu") { for_emulator = true; } else if (StartsWith(key, "androidboot.")) { InitPropertySet("ro.boot." + key.substr(12), value); } }); if (for_emulator) { ImportKernelCmdline([&](const std::string& key, const std::string& value) { // In the emulator, export any kernel option with the "ro.kernel." prefix. InitPropertySet("ro.kernel." + key, value); }); } } void PropertyInit() { selinux_callback cb; cb.func_audit = PropertyAuditCallback; selinux_set_callback(SELINUX_CB_AUDIT, cb); mkdir("/dev/__properties__", S_IRWXU | S_IXGRP | S_IXOTH); CreateSerializedPropertyInfo(); if (__system_property_area_init()) { LOG(FATAL) << "Failed to initialize property area"; } if (!property_info_area.LoadDefaultPath()) { LOG(FATAL) << "Failed to load serialized property info file"; } // If arguments are passed both on the command line and in DT, // properties set in DT always have priority over the command-line ones. ProcessKernelDt(); ProcessKernelCmdline(); // Propagate the kernel variables to internal variables // used by init as well as the current required properties. ExportKernelBootProps(); PropertyLoadBootDefaults(); } static void HandleInitSocket() { auto message = ReadMessage(init_socket); if (!message) { Loading Loading @@ -1075,7 +1147,7 @@ static void PropertyServiceThread() { } void StartPropertyService(int* epoll_socket) { property_set("ro.property_service.version", "2"); InitPropertySet("ro.property_service.version", "2"); int sockets[2]; if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sockets) != 0) { Loading @@ -1095,11 +1167,6 @@ void StartPropertyService(int* epoll_socket) { listen(property_set_fd, 8); std::thread{PropertyServiceThread}.detach(); property_set = [](const std::string& key, const std::string& value) -> uint32_t { android::base::SetProperty(key, value); return 0; }; } } // namespace init Loading Loading
init/builtins.cpp +16 −15 Original line number Diff line number Diff line Loading @@ -84,6 +84,7 @@ using namespace std::literals::string_literals; using android::base::Basename; using android::base::SetProperty; using android::base::StartsWith; using android::base::StringPrintf; using android::base::unique_fd; Loading Loading @@ -561,16 +562,16 @@ static Result<void> queue_fs_event(int code, bool userdata_remount) { LOG(ERROR) << "Userdata remount is not supported on FDE devices. How did you get here?"; trigger_shutdown("reboot,requested-userdata-remount-on-fde-device"); } property_set("ro.crypto.state", "encrypted"); property_set("ro.crypto.type", "block"); SetProperty("ro.crypto.state", "encrypted"); SetProperty("ro.crypto.type", "block"); ActionManager::GetInstance().QueueEventTrigger("defaultcrypto"); return {}; } else if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) { property_set("ro.crypto.state", "unencrypted"); SetProperty("ro.crypto.state", "unencrypted"); ActionManager::GetInstance().QueueEventTrigger("nonencrypted"); return {}; } else if (code == FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) { property_set("ro.crypto.state", "unsupported"); SetProperty("ro.crypto.state", "unsupported"); ActionManager::GetInstance().QueueEventTrigger("nonencrypted"); return {}; } else if (code == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) { Loading @@ -586,8 +587,8 @@ static Result<void> queue_fs_event(int code, bool userdata_remount) { if (!FscryptInstallKeyring()) { return Error() << "FscryptInstallKeyring() failed"; } property_set("ro.crypto.state", "encrypted"); property_set("ro.crypto.type", "file"); SetProperty("ro.crypto.state", "encrypted"); SetProperty("ro.crypto.type", "file"); // Although encrypted, we have device key, so we do not need to // do anything different from the nonencrypted case. Loading @@ -597,8 +598,8 @@ static Result<void> queue_fs_event(int code, bool userdata_remount) { if (!FscryptInstallKeyring()) { return Error() << "FscryptInstallKeyring() failed"; } property_set("ro.crypto.state", "encrypted"); property_set("ro.crypto.type", "file"); SetProperty("ro.crypto.state", "encrypted"); SetProperty("ro.crypto.type", "file"); // Although encrypted, vold has already set the device up, so we do not need to // do anything different from the nonencrypted case. Loading @@ -608,8 +609,8 @@ static Result<void> queue_fs_event(int code, bool userdata_remount) { if (!FscryptInstallKeyring()) { return Error() << "FscryptInstallKeyring() failed"; } property_set("ro.crypto.state", "encrypted"); property_set("ro.crypto.type", "file"); SetProperty("ro.crypto.state", "encrypted"); SetProperty("ro.crypto.type", "file"); // Although encrypted, vold has already set the device up, so we do not need to // do anything different from the nonencrypted case. Loading Loading @@ -662,7 +663,7 @@ static Result<void> do_mount_all(const BuiltinArguments& args) { } auto mount_fstab_return_code = fs_mgr_mount_all(&fstab, mount_mode); property_set(prop_name, std::to_string(t.duration().count())); SetProperty(prop_name, std::to_string(t.duration().count())); if (import_rc && SelinuxGetVendorAndroidVersion() <= __ANDROID_API_Q__) { /* Paths of .rc files are specified at the 2nd argument and beyond */ Loading Loading @@ -718,7 +719,7 @@ static Result<void> do_setprop(const BuiltinArguments& args) { << "' from init; use the restorecon builtin directly"; } property_set(args[1], args[2]); SetProperty(args[1], args[2]); return {}; } Loading Loading @@ -832,7 +833,7 @@ static Result<void> do_verity_update_state(const BuiltinArguments& args) { // To be consistent in vboot 1.0 and vboot 2.0 (AVB), use "system" for the partition even // for system as root, so it has property [partition.system.verified]. std::string partition = entry.mount_point == "/" ? "system" : Basename(entry.mount_point); property_set("partition." + partition + ".verified", std::to_string(mode)); SetProperty("partition." + partition + ".verified", std::to_string(mode)); } return {}; Loading Loading @@ -1221,7 +1222,7 @@ 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", SetProperty("sys.init.userspace_reboot.last_finished", std::to_string(now.time_since_epoch().count())); if (!android::sysprop::InitProperties::userspace_reboot_in_progress(false)) { return Error() << "Failed to set sys.init.userspace_reboot.in_progress property"; Loading
init/host_init_stubs.h +0 −9 Original line number Diff line number Diff line Loading @@ -39,15 +39,6 @@ namespace init { inline bool CanReadProperty(const std::string&, const std::string&) { return true; } inline uint32_t SetProperty(const std::string& key, const std::string& value) { android::base::SetProperty(key, value); return 0; } inline uint32_t (*property_set)(const std::string& name, const std::string& value) = SetProperty; inline uint32_t HandlePropertySet(const std::string&, const std::string&, const std::string&, const ucred&, std::string*) { return 0; } // reboot_utils.h inline void SetFatalRebootTarget() {} Loading
init/init.cpp +40 −113 Original line number Diff line number Diff line Loading @@ -81,6 +81,7 @@ using namespace std::string_literals; using android::base::boot_clock; using android::base::GetProperty; using android::base::ReadFileToString; using android::base::SetProperty; using android::base::StringPrintf; using android::base::Timer; using android::base::Trim; Loading @@ -91,8 +92,6 @@ namespace init { static int property_triggers_enabled = 0; static char qemu[32]; static int signal_fd = -1; static int property_fd = -1; Loading @@ -101,7 +100,6 @@ static std::string wait_prop_name; static std::string wait_prop_value; static std::string shutdown_command; static bool do_shutdown = false; static bool load_debug_prop = false; static std::unique_ptr<Subcontext> subcontext; Loading Loading @@ -208,7 +206,7 @@ void property_changed(const std::string& name, const std::string& value) { // 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)); SetProperty("ro.boottime.init.cold_boot_wait", std::to_string(time_waited)); } if (waiting_for_prop) { Loading Loading @@ -364,87 +362,17 @@ static Result<void> SetupCgroupsAction(const BuiltinArguments&) { return {}; } static void import_kernel_nv(const std::string& key, const std::string& value, bool for_emulator) { if (key.empty()) return; if (for_emulator) { // In the emulator, export any kernel option with the "ro.kernel." prefix. property_set("ro.kernel." + key, value); return; } if (key == "qemu") { strlcpy(qemu, value.c_str(), sizeof(qemu)); } else if (android::base::StartsWith(key, "androidboot.")) { property_set("ro.boot." + key.substr(12), value); } } static void export_oem_lock_status() { if (!android::base::GetBoolProperty("ro.oem_unlock_supported", false)) { return; } import_kernel_cmdline( false, [](const std::string& key, const std::string& value, bool in_qemu) { ImportKernelCmdline([](const std::string& key, const std::string& value) { if (key == "androidboot.verifiedbootstate") { property_set("ro.boot.flash.locked", value == "orange" ? "0" : "1"); SetProperty("ro.boot.flash.locked", value == "orange" ? "0" : "1"); } }); } static void export_kernel_boot_props() { constexpr const char* UNSET = ""; struct { const char *src_prop; const char *dst_prop; const char *default_value; } prop_map[] = { { "ro.boot.serialno", "ro.serialno", UNSET, }, { "ro.boot.mode", "ro.bootmode", "unknown", }, { "ro.boot.baseband", "ro.baseband", "unknown", }, { "ro.boot.bootloader", "ro.bootloader", "unknown", }, { "ro.boot.hardware", "ro.hardware", "unknown", }, { "ro.boot.revision", "ro.revision", "0", }, }; for (const auto& prop : prop_map) { std::string value = GetProperty(prop.src_prop, prop.default_value); if (value != UNSET) property_set(prop.dst_prop, value); } } static void process_kernel_dt() { if (!is_android_dt_value_expected("compatible", "android,firmware")) { return; } std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(get_android_dt_dir().c_str()), closedir); if (!dir) return; std::string dt_file; struct dirent *dp; while ((dp = readdir(dir.get())) != NULL) { if (dp->d_type != DT_REG || !strcmp(dp->d_name, "compatible") || !strcmp(dp->d_name, "name")) { continue; } std::string file_name = get_android_dt_dir() + dp->d_name; android::base::ReadFileToString(file_name, &dt_file); std::replace(dt_file.begin(), dt_file.end(), ',', '.'); property_set("ro.boot."s + dp->d_name, dt_file); } } static void process_kernel_cmdline() { // The first pass does the common stuff, and finds if we are in qemu. // The second pass is only necessary for qemu to export all kernel params // as properties. import_kernel_cmdline(false, import_kernel_nv); if (qemu[0]) import_kernel_cmdline(true, import_kernel_nv); } static Result<void> property_enable_triggers_action(const BuiltinArguments& args) { /* Enable property triggers. */ property_triggers_enabled = 1; Loading @@ -468,7 +396,7 @@ static void set_usb_controller() { while ((dp = readdir(dir.get())) != nullptr) { if (dp->d_name[0] == '.') continue; property_set("sys.usb.controller", dp->d_name); SetProperty("sys.usb.controller", dp->d_name); break; } } Loading Loading @@ -591,7 +519,7 @@ static void RecordStageBoottimes(const boot_clock::time_point& second_stage_star int64_t first_stage_start_time_ns = -1; if (auto first_stage_start_time_str = getenv(kEnvFirstStageStartedAt); first_stage_start_time_str) { property_set("ro.boottime.init", first_stage_start_time_str); SetProperty("ro.boottime.init", first_stage_start_time_str); android::base::ParseInt(first_stage_start_time_str, &first_stage_start_time_ns); } unsetenv(kEnvFirstStageStartedAt); Loading @@ -605,9 +533,9 @@ static void RecordStageBoottimes(const boot_clock::time_point& second_stage_star if (selinux_start_time_ns == -1) return; if (first_stage_start_time_ns == -1) return; property_set("ro.boottime.init.first_stage", SetProperty("ro.boottime.init.first_stage", std::to_string(selinux_start_time_ns - first_stage_start_time_ns)); property_set("ro.boottime.init.selinux", SetProperty("ro.boottime.init.selinux", std::to_string(second_stage_start_time.time_since_epoch().count() - selinux_start_time_ns)); } Loading Loading @@ -706,34 +634,27 @@ int SecondStageMain(int argc, char** argv) { // Indicate that booting is in progress to background fw loaders, etc. close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000)); property_init(); // If arguments are passed both on the command line and in DT, // properties set in DT always have priority over the command-line ones. process_kernel_dt(); process_kernel_cmdline(); // Propagate the kernel variables to internal variables // used by init as well as the current required properties. export_kernel_boot_props(); // Make the time that init stages started available for bootstat to log. RecordStageBoottimes(start_time); // Set libavb version for Framework-only OTA match in Treble build. const char* avb_version = getenv("INIT_AVB_VERSION"); if (avb_version) property_set("ro.boot.avb_version", avb_version); // See if need to load debug props to allow adb root, when the device is unlocked. const char* force_debuggable_env = getenv("INIT_FORCE_DEBUGGABLE"); bool load_debug_prop = false; if (force_debuggable_env && AvbHandle::IsDeviceUnlocked()) { load_debug_prop = "true"s == force_debuggable_env; } // Clean up our environment. unsetenv("INIT_AVB_VERSION"); unsetenv("INIT_FORCE_DEBUGGABLE"); // Umount the debug ramdisk so property service doesn't read .prop files from there, when it // is not meant to. if (!load_debug_prop) { UmountDebugRamdisk(); } PropertyInit(); // Umount the debug ramdisk after property service has read the .prop files when it means to. if (load_debug_prop) { UmountDebugRamdisk(); } // Now set up SELinux for second stage. SelinuxSetupKernelLogging(); SelabelInitialize(); Loading @@ -746,16 +667,22 @@ int SecondStageMain(int argc, char** argv) { InstallSignalFdHandler(&epoll); property_load_boot_defaults(load_debug_prop); UmountDebugRamdisk(); fs_mgr_vendor_overlay_mount_all(); export_oem_lock_status(); StartPropertyService(&property_fd); if (auto result = epoll.RegisterHandler(property_fd, HandlePropertyFd); !result) { LOG(FATAL) << "Could not register epoll handler for property fd: " << result.error(); } // Make the time that init stages started available for bootstat to log. RecordStageBoottimes(start_time); // Set libavb version for Framework-only OTA match in Treble build. if (const char* avb_version = getenv("INIT_AVB_VERSION"); avb_version != nullptr) { SetProperty("ro.boot.avb_version", avb_version); } unsetenv("INIT_AVB_VERSION"); fs_mgr_vendor_overlay_mount_all(); export_oem_lock_status(); MountHandler mount_handler(&epoll); set_usb_controller(); Loading @@ -779,9 +706,9 @@ int SecondStageMain(int argc, char** argv) { // Make the GSI status available before scripts start running. if (android::gsi::IsGsiRunning()) { property_set("ro.gsid.image_running", "1"); SetProperty("ro.gsid.image_running", "1"); } else { property_set("ro.gsid.image_running", "0"); SetProperty("ro.gsid.image_running", "0"); } am.QueueBuiltinAction(SetupCgroupsAction, "SetupCgroups"); Loading
init/mount_handler.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -38,7 +38,6 @@ #include <libdm/dm.h> #include "epoll.h" #include "property_service.h" namespace android { namespace init { Loading Loading @@ -96,7 +95,7 @@ void SetMountProperty(const MountHandlerEntry& entry, bool add) { // handling, except for clearing non-existent or already clear property. // Goal is reduction of empty properties and associated triggers. if (value.empty() && android::base::GetProperty(mount_prop, "").empty()) return; property_set(mount_prop, value); android::base::SetProperty(mount_prop, value); } } // namespace Loading
init/property_service.cpp +108 −41 Original line number Diff line number Diff line Loading @@ -97,8 +97,6 @@ static bool accept_messages = false; static PropertyInfoAreaFile property_info_area; void CreateSerializedPropertyInfo(); struct PropertyAuditData { const ucred* cr; const char* name; Loading @@ -117,21 +115,6 @@ static int PropertyAuditCallback(void* data, security_class_t /*cls*/, char* buf return 0; } void property_init() { selinux_callback cb; cb.func_audit = PropertyAuditCallback; selinux_set_callback(SELINUX_CB_AUDIT, cb); mkdir("/dev/__properties__", S_IRWXU | S_IXGRP | S_IXOTH); CreateSerializedPropertyInfo(); if (__system_property_area_init()) { LOG(FATAL) << "Failed to initialize property area"; } if (!property_info_area.LoadDefaultPath()) { LOG(FATAL) << "Failed to load serialized property info file"; } } bool CanReadProperty(const std::string& source_context, const std::string& name) { const char* target_context = nullptr; property_info_area->GetPropertyInfo(name.c_str(), &target_context, nullptr); Loading Loading @@ -527,20 +510,6 @@ uint32_t HandlePropertySet(const std::string& name, const std::string& value, return PropertySet(name, value, error); } uint32_t InitPropertySet(const std::string& name, const std::string& value) { uint32_t result = 0; ucred cr = {.pid = 1, .uid = 0, .gid = 0}; std::string error; result = HandlePropertySet(name, value, kInitContext, cr, nullptr, &error); if (result != PROP_SUCCESS) { LOG(ERROR) << "Init cannot set '" << name << "' to '" << value << "': " << error; } return result; } uint32_t (*property_set)(const std::string& name, const std::string& value) = InitPropertySet; static void handle_property_set_fd() { static constexpr uint32_t kDefaultSocketTimeout = 2000; /* ms */ Loading Loading @@ -634,6 +603,18 @@ static void handle_property_set_fd() { } } uint32_t InitPropertySet(const std::string& name, const std::string& value) { uint32_t result = 0; ucred cr = {.pid = 1, .uid = 0, .gid = 0}; std::string error; result = HandlePropertySet(name, value, kInitContext, cr, nullptr, &error); if (result != PROP_SUCCESS) { LOG(ERROR) << "Init cannot set '" << name << "' to '" << value << "': " << error; } return result; } static bool load_properties_from_file(const char*, const char*, std::map<std::string, std::string>*); Loading Loading @@ -765,11 +746,11 @@ static void update_sys_usb_config() { bool is_debuggable = android::base::GetBoolProperty("ro.debuggable", false); std::string config = android::base::GetProperty("persist.sys.usb.config", ""); if (config.empty()) { property_set("persist.sys.usb.config", is_debuggable ? "adb" : "none"); InitPropertySet("persist.sys.usb.config", is_debuggable ? "adb" : "none"); } else if (is_debuggable && config.find("adb") == std::string::npos && config.length() + 4 < PROP_VALUE_MAX) { config.append(",adb"); property_set("persist.sys.usb.config", config); InitPropertySet("persist.sys.usb.config", config); } } Loading Loading @@ -890,7 +871,7 @@ static void property_derive_build_fingerprint() { } } void property_load_boot_defaults(bool load_debug_prop) { void PropertyLoadBootDefaults() { // TODO(b/117892318): merge prop.default and build.prop files into one // We read the properties and their values into a map, in order to always allow properties // loaded in the later property files to override the properties in loaded in the earlier Loading @@ -916,7 +897,7 @@ void property_load_boot_defaults(bool load_debug_prop) { load_properties_from_file("/product/build.prop", nullptr, &properties); load_properties_from_file("/factory/factory.prop", "ro.*", &properties); if (load_debug_prop) { if (access(kDebugRamdiskProp, R_OK) == 0) { LOG(INFO) << "Loading " << kDebugRamdiskProp; load_properties_from_file(kDebugRamdiskProp, nullptr, &properties); } Loading Loading @@ -1009,6 +990,97 @@ void CreateSerializedPropertyInfo() { selinux_android_restorecon(kPropertyInfosPath, 0); } static void ExportKernelBootProps() { constexpr const char* UNSET = ""; struct { const char* src_prop; const char* dst_prop; const char* default_value; } prop_map[] = { // clang-format off { "ro.boot.serialno", "ro.serialno", UNSET, }, { "ro.boot.mode", "ro.bootmode", "unknown", }, { "ro.boot.baseband", "ro.baseband", "unknown", }, { "ro.boot.bootloader", "ro.bootloader", "unknown", }, { "ro.boot.hardware", "ro.hardware", "unknown", }, { "ro.boot.revision", "ro.revision", "0", }, // clang-format on }; for (const auto& prop : prop_map) { std::string value = GetProperty(prop.src_prop, prop.default_value); if (value != UNSET) InitPropertySet(prop.dst_prop, value); } } static void ProcessKernelDt() { if (!is_android_dt_value_expected("compatible", "android,firmware")) { return; } std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(get_android_dt_dir().c_str()), closedir); if (!dir) return; std::string dt_file; struct dirent* dp; while ((dp = readdir(dir.get())) != NULL) { if (dp->d_type != DT_REG || !strcmp(dp->d_name, "compatible") || !strcmp(dp->d_name, "name")) { continue; } std::string file_name = get_android_dt_dir() + dp->d_name; android::base::ReadFileToString(file_name, &dt_file); std::replace(dt_file.begin(), dt_file.end(), ',', '.'); InitPropertySet("ro.boot."s + dp->d_name, dt_file); } } static void ProcessKernelCmdline() { bool for_emulator = false; ImportKernelCmdline([&](const std::string& key, const std::string& value) { if (key == "qemu") { for_emulator = true; } else if (StartsWith(key, "androidboot.")) { InitPropertySet("ro.boot." + key.substr(12), value); } }); if (for_emulator) { ImportKernelCmdline([&](const std::string& key, const std::string& value) { // In the emulator, export any kernel option with the "ro.kernel." prefix. InitPropertySet("ro.kernel." + key, value); }); } } void PropertyInit() { selinux_callback cb; cb.func_audit = PropertyAuditCallback; selinux_set_callback(SELINUX_CB_AUDIT, cb); mkdir("/dev/__properties__", S_IRWXU | S_IXGRP | S_IXOTH); CreateSerializedPropertyInfo(); if (__system_property_area_init()) { LOG(FATAL) << "Failed to initialize property area"; } if (!property_info_area.LoadDefaultPath()) { LOG(FATAL) << "Failed to load serialized property info file"; } // If arguments are passed both on the command line and in DT, // properties set in DT always have priority over the command-line ones. ProcessKernelDt(); ProcessKernelCmdline(); // Propagate the kernel variables to internal variables // used by init as well as the current required properties. ExportKernelBootProps(); PropertyLoadBootDefaults(); } static void HandleInitSocket() { auto message = ReadMessage(init_socket); if (!message) { Loading Loading @@ -1075,7 +1147,7 @@ static void PropertyServiceThread() { } void StartPropertyService(int* epoll_socket) { property_set("ro.property_service.version", "2"); InitPropertySet("ro.property_service.version", "2"); int sockets[2]; if (socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sockets) != 0) { Loading @@ -1095,11 +1167,6 @@ void StartPropertyService(int* epoll_socket) { listen(property_set_fd, 8); std::thread{PropertyServiceThread}.detach(); property_set = [](const std::string& key, const std::string& value) -> uint32_t { android::base::SetProperty(key, value); return 0; }; } } // namespace init Loading