Loading init/README.ueventd.md +10 −0 Original line number Diff line number Diff line Loading @@ -163,3 +163,13 @@ recommended that devices use genfscon for labeling sysfs nodes. However, some de from enabling the parallelization option: parallel_restorecon enabled Do parallel restorecon to speed up boot process, subdirectories under `/sys` can be sliced by ueventd.rc, and run on multiple process. parallel_restorecon_dir <directory> For example parallel_restorecon_dir /sys parallel_restorecon_dir /sys/devices parallel_restorecon_dir /sys/devices/platform parallel_restorecon_dir /sys/devices/platform/soc init/ueventd.cpp +40 −10 Original line number Diff line number Diff line Loading @@ -115,11 +115,13 @@ class ColdBoot { public: ColdBoot(UeventListener& uevent_listener, std::vector<std::unique_ptr<UeventHandler>>& uevent_handlers, bool enable_parallel_restorecon) bool enable_parallel_restorecon, std::vector<std::string> parallel_restorecon_queue) : uevent_listener_(uevent_listener), uevent_handlers_(uevent_handlers), num_handler_subprocesses_(std::thread::hardware_concurrency() ?: 4), enable_parallel_restorecon_(enable_parallel_restorecon) {} enable_parallel_restorecon_(enable_parallel_restorecon), parallel_restorecon_queue_(parallel_restorecon_queue) {} void Run(); Loading @@ -142,6 +144,8 @@ class ColdBoot { std::set<pid_t> subprocess_pids_; std::vector<std::string> restorecon_queue_; std::vector<std::string> parallel_restorecon_queue_; }; void ColdBoot::UeventHandlerMain(unsigned int process_num, unsigned int total_processes) { Loading @@ -155,17 +159,34 @@ void ColdBoot::UeventHandlerMain(unsigned int process_num, unsigned int total_pr } void ColdBoot::RestoreConHandler(unsigned int process_num, unsigned int total_processes) { android::base::Timer t_process; for (unsigned int i = process_num; i < restorecon_queue_.size(); i += total_processes) { android::base::Timer t; auto& dir = restorecon_queue_[i]; selinux_android_restorecon(dir.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE); //Mark a dir restorecon operation for 50ms, //Maybe you can add this dir to the ueventd.rc script to parallel processing if (t.duration() > 50ms) { LOG(INFO) << "took " << t.duration().count() <<"ms restorecon '" << dir.c_str() << "' on process '" << process_num <<"'"; } } //Calculate process restorecon time LOG(VERBOSE) << "took " << t_process.duration().count() << "ms on process '" << process_num << "'"; } void ColdBoot::GenerateRestoreCon(const std::string& directory) { std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(directory.c_str()), &closedir); if (!dir) return; if (!dir) { PLOG(WARNING) << "opendir " << directory.c_str(); return; } struct dirent* dent; while ((dent = readdir(dir.get())) != NULL) { Loading @@ -176,7 +197,10 @@ void ColdBoot::GenerateRestoreCon(const std::string& directory) { if (S_ISDIR(st.st_mode)) { std::string fullpath = directory + "/" + dent->d_name; if (fullpath != "/sys/devices") { auto parallel_restorecon = std::find(parallel_restorecon_queue_.begin(), parallel_restorecon_queue_.end(), fullpath); if (parallel_restorecon == parallel_restorecon_queue_.end()) { restorecon_queue_.emplace_back(fullpath); } } Loading Loading @@ -248,11 +272,16 @@ void ColdBoot::Run() { RegenerateUevents(); if (enable_parallel_restorecon_) { selinux_android_restorecon("/sys", 0); selinux_android_restorecon("/sys/devices", 0); GenerateRestoreCon("/sys"); if (parallel_restorecon_queue_.empty()) { parallel_restorecon_queue_.emplace_back("/sys"); // takes long time for /sys/devices, parallelize it GenerateRestoreCon("/sys/devices"); parallel_restorecon_queue_.emplace_back("/sys/devices"); LOG(INFO) << "Parallel processing directory is not set, set the default"; } for (const auto& dir : parallel_restorecon_queue_) { selinux_android_restorecon(dir.c_str(), 0); GenerateRestoreCon(dir); } } ForkSubProcesses(); Loading Loading @@ -326,7 +355,8 @@ int ueventd_main(int argc, char** argv) { if (!android::base::GetBoolProperty(kColdBootDoneProp, false)) { ColdBoot cold_boot(uevent_listener, uevent_handlers, ueventd_configuration.enable_parallel_restorecon); ueventd_configuration.enable_parallel_restorecon, ueventd_configuration.parallel_restorecon_dirs); cold_boot.Run(); } Loading init/ueventd_parser.cpp +14 −0 Original line number Diff line number Diff line Loading @@ -151,6 +151,17 @@ Result<void> ParseEnabledDisabledLine(std::vector<std::string>&& args, bool* fea return {}; } Result<void> ParseParallelRestoreconDirsLine(std::vector<std::string>&& args, std::vector<std::string>* parallel_restorecon_dirs) { if (args.size() != 2) { return Error() << "parallel_restorecon_dir lines must have exactly 2 parameters"; } std::move(std::next(args.begin()), args.end(), std::back_inserter(*parallel_restorecon_dirs)); return {}; } Result<void> ParseUeventSocketRcvbufSizeLine(std::vector<std::string>&& args, size_t* uevent_socket_rcvbuf_size) { if (args.size() != 2) { Loading Loading @@ -268,6 +279,9 @@ UeventdConfiguration ParseConfig(const std::vector<std::string>& configs) { parser.AddSingleLineParser("uevent_socket_rcvbuf_size", std::bind(ParseUeventSocketRcvbufSizeLine, _1, &ueventd_configuration.uevent_socket_rcvbuf_size)); parser.AddSingleLineParser("parallel_restorecon_dir", std::bind(ParseParallelRestoreconDirsLine, _1, &ueventd_configuration.parallel_restorecon_dirs)); parser.AddSingleLineParser("parallel_restorecon", std::bind(ParseEnabledDisabledLine, _1, &ueventd_configuration.enable_parallel_restorecon)); Loading init/ueventd_parser.h +1 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ struct UeventdConfiguration { std::vector<Permissions> dev_permissions; std::vector<std::string> firmware_directories; std::vector<ExternalFirmwareHandler> external_firmware_handlers; std::vector<std::string> parallel_restorecon_dirs; bool enable_modalias_handling = false; size_t uevent_socket_rcvbuf_size = 0; bool enable_parallel_restorecon = false; Loading init/ueventd_parser_test.cpp +36 −9 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ void TestUeventdFile(const std::string& content, const UeventdConfiguration& exp EXPECT_EQ(expected.firmware_directories, result.firmware_directories); TestVector(expected.external_firmware_handlers, result.external_firmware_handlers, TestExternalFirmwareHandler); EXPECT_EQ(expected.parallel_restorecon_dirs, result.parallel_restorecon_dirs); } TEST(ueventd_parser, EmptyFile) { Loading Loading @@ -105,7 +106,7 @@ subsystem test_devpath_dirname {"test_devname2", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"}, {"test_devpath_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev/graphics"}}; TestUeventdFile(ueventd_file, {subsystems, {}, {}, {}, {}}); TestUeventdFile(ueventd_file, {subsystems, {}, {}, {}, {}, {}}); } TEST(ueventd_parser, Permissions) { Loading @@ -131,7 +132,7 @@ TEST(ueventd_parser, Permissions) { {"/sys/devices/virtual/*/input", "poll_delay", 0660, AID_ROOT, AID_INPUT, true}, }; TestUeventdFile(ueventd_file, {{}, sysfs_permissions, permissions, {}, {}}); TestUeventdFile(ueventd_file, {{}, sysfs_permissions, permissions, {}, {}, {}}); } TEST(ueventd_parser, FirmwareDirectories) { Loading @@ -147,7 +148,7 @@ firmware_directories /more "/more", }; TestUeventdFile(ueventd_file, {{}, {}, {}, firmware_directories, {}}); TestUeventdFile(ueventd_file, {{}, {}, {}, firmware_directories, {}, {}}); } TEST(ueventd_parser, ExternalFirmwareHandlers) { Loading Loading @@ -213,7 +214,7 @@ external_firmware_handler /devices/path/firmware/something004.bin radio radio "/ }, }; TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers}); TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers, {}}); } TEST(ueventd_parser, ExternalFirmwareHandlersDuplicate) { Loading @@ -231,7 +232,21 @@ external_firmware_handler devpath root handler_path2 }, }; TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers}); TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers, {}}); } TEST(ueventd_parser, ParallelRestoreconDirs) { auto ueventd_file = R"( parallel_restorecon_dir /sys parallel_restorecon_dir /sys/devices )"; auto parallel_restorecon_dirs = std::vector<std::string>{ "/sys", "/sys/devices", }; TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, parallel_restorecon_dirs}); } TEST(ueventd_parser, UeventSocketRcvbufSize) { Loading @@ -240,7 +255,7 @@ uevent_socket_rcvbuf_size 8k uevent_socket_rcvbuf_size 8M )"; TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, false, 8 * 1024 * 1024}); TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, {}, false, 8 * 1024 * 1024}); } TEST(ueventd_parser, EnabledDisabledLines) { Loading @@ -250,7 +265,7 @@ parallel_restorecon enabled modalias_handling disabled )"; TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, false, 0, true}); TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, {}, false, 0, true}); auto ueventd_file2 = R"( parallel_restorecon enabled Loading @@ -258,7 +273,7 @@ modalias_handling enabled parallel_restorecon disabled )"; TestUeventdFile(ueventd_file2, {{}, {}, {}, {}, {}, true, 0, false}); TestUeventdFile(ueventd_file2, {{}, {}, {}, {}, {}, {}, true, 0, false}); } TEST(ueventd_parser, AllTogether) { Loading Loading @@ -298,6 +313,9 @@ uevent_socket_rcvbuf_size 6M modalias_handling enabled parallel_restorecon enabled parallel_restorecon_dir /sys parallel_restorecon_dir /sys/devices #ending comment )"; Loading Loading @@ -330,11 +348,17 @@ parallel_restorecon enabled {"/devices/path/firmware/firmware001.bin", AID_ROOT, AID_ROOT, "/vendor/bin/touch.sh"}, }; auto parallel_restorecon_dirs = std::vector<std::string>{ "/sys", "/sys/devices", }; size_t uevent_socket_rcvbuf_size = 6 * 1024 * 1024; TestUeventdFile(ueventd_file, {subsystems, sysfs_permissions, permissions, firmware_directories, external_firmware_handlers, true, uevent_socket_rcvbuf_size, true}); external_firmware_handlers, parallel_restorecon_dirs, true, uevent_socket_rcvbuf_size, true}); } // All of these lines are ill-formed, so test that there is 0 output. Loading Loading @@ -366,6 +390,9 @@ external_firmware_handler external_firmware_handler blah blah external_firmware_handler blah blah blah blah parallel_restorecon_dir parallel_restorecon_dir /sys /sys/devices )"; TestUeventdFile(ueventd_file, {}); Loading Loading
init/README.ueventd.md +10 −0 Original line number Diff line number Diff line Loading @@ -163,3 +163,13 @@ recommended that devices use genfscon for labeling sysfs nodes. However, some de from enabling the parallelization option: parallel_restorecon enabled Do parallel restorecon to speed up boot process, subdirectories under `/sys` can be sliced by ueventd.rc, and run on multiple process. parallel_restorecon_dir <directory> For example parallel_restorecon_dir /sys parallel_restorecon_dir /sys/devices parallel_restorecon_dir /sys/devices/platform parallel_restorecon_dir /sys/devices/platform/soc
init/ueventd.cpp +40 −10 Original line number Diff line number Diff line Loading @@ -115,11 +115,13 @@ class ColdBoot { public: ColdBoot(UeventListener& uevent_listener, std::vector<std::unique_ptr<UeventHandler>>& uevent_handlers, bool enable_parallel_restorecon) bool enable_parallel_restorecon, std::vector<std::string> parallel_restorecon_queue) : uevent_listener_(uevent_listener), uevent_handlers_(uevent_handlers), num_handler_subprocesses_(std::thread::hardware_concurrency() ?: 4), enable_parallel_restorecon_(enable_parallel_restorecon) {} enable_parallel_restorecon_(enable_parallel_restorecon), parallel_restorecon_queue_(parallel_restorecon_queue) {} void Run(); Loading @@ -142,6 +144,8 @@ class ColdBoot { std::set<pid_t> subprocess_pids_; std::vector<std::string> restorecon_queue_; std::vector<std::string> parallel_restorecon_queue_; }; void ColdBoot::UeventHandlerMain(unsigned int process_num, unsigned int total_processes) { Loading @@ -155,17 +159,34 @@ void ColdBoot::UeventHandlerMain(unsigned int process_num, unsigned int total_pr } void ColdBoot::RestoreConHandler(unsigned int process_num, unsigned int total_processes) { android::base::Timer t_process; for (unsigned int i = process_num; i < restorecon_queue_.size(); i += total_processes) { android::base::Timer t; auto& dir = restorecon_queue_[i]; selinux_android_restorecon(dir.c_str(), SELINUX_ANDROID_RESTORECON_RECURSE); //Mark a dir restorecon operation for 50ms, //Maybe you can add this dir to the ueventd.rc script to parallel processing if (t.duration() > 50ms) { LOG(INFO) << "took " << t.duration().count() <<"ms restorecon '" << dir.c_str() << "' on process '" << process_num <<"'"; } } //Calculate process restorecon time LOG(VERBOSE) << "took " << t_process.duration().count() << "ms on process '" << process_num << "'"; } void ColdBoot::GenerateRestoreCon(const std::string& directory) { std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(directory.c_str()), &closedir); if (!dir) return; if (!dir) { PLOG(WARNING) << "opendir " << directory.c_str(); return; } struct dirent* dent; while ((dent = readdir(dir.get())) != NULL) { Loading @@ -176,7 +197,10 @@ void ColdBoot::GenerateRestoreCon(const std::string& directory) { if (S_ISDIR(st.st_mode)) { std::string fullpath = directory + "/" + dent->d_name; if (fullpath != "/sys/devices") { auto parallel_restorecon = std::find(parallel_restorecon_queue_.begin(), parallel_restorecon_queue_.end(), fullpath); if (parallel_restorecon == parallel_restorecon_queue_.end()) { restorecon_queue_.emplace_back(fullpath); } } Loading Loading @@ -248,11 +272,16 @@ void ColdBoot::Run() { RegenerateUevents(); if (enable_parallel_restorecon_) { selinux_android_restorecon("/sys", 0); selinux_android_restorecon("/sys/devices", 0); GenerateRestoreCon("/sys"); if (parallel_restorecon_queue_.empty()) { parallel_restorecon_queue_.emplace_back("/sys"); // takes long time for /sys/devices, parallelize it GenerateRestoreCon("/sys/devices"); parallel_restorecon_queue_.emplace_back("/sys/devices"); LOG(INFO) << "Parallel processing directory is not set, set the default"; } for (const auto& dir : parallel_restorecon_queue_) { selinux_android_restorecon(dir.c_str(), 0); GenerateRestoreCon(dir); } } ForkSubProcesses(); Loading Loading @@ -326,7 +355,8 @@ int ueventd_main(int argc, char** argv) { if (!android::base::GetBoolProperty(kColdBootDoneProp, false)) { ColdBoot cold_boot(uevent_listener, uevent_handlers, ueventd_configuration.enable_parallel_restorecon); ueventd_configuration.enable_parallel_restorecon, ueventd_configuration.parallel_restorecon_dirs); cold_boot.Run(); } Loading
init/ueventd_parser.cpp +14 −0 Original line number Diff line number Diff line Loading @@ -151,6 +151,17 @@ Result<void> ParseEnabledDisabledLine(std::vector<std::string>&& args, bool* fea return {}; } Result<void> ParseParallelRestoreconDirsLine(std::vector<std::string>&& args, std::vector<std::string>* parallel_restorecon_dirs) { if (args.size() != 2) { return Error() << "parallel_restorecon_dir lines must have exactly 2 parameters"; } std::move(std::next(args.begin()), args.end(), std::back_inserter(*parallel_restorecon_dirs)); return {}; } Result<void> ParseUeventSocketRcvbufSizeLine(std::vector<std::string>&& args, size_t* uevent_socket_rcvbuf_size) { if (args.size() != 2) { Loading Loading @@ -268,6 +279,9 @@ UeventdConfiguration ParseConfig(const std::vector<std::string>& configs) { parser.AddSingleLineParser("uevent_socket_rcvbuf_size", std::bind(ParseUeventSocketRcvbufSizeLine, _1, &ueventd_configuration.uevent_socket_rcvbuf_size)); parser.AddSingleLineParser("parallel_restorecon_dir", std::bind(ParseParallelRestoreconDirsLine, _1, &ueventd_configuration.parallel_restorecon_dirs)); parser.AddSingleLineParser("parallel_restorecon", std::bind(ParseEnabledDisabledLine, _1, &ueventd_configuration.enable_parallel_restorecon)); Loading
init/ueventd_parser.h +1 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ struct UeventdConfiguration { std::vector<Permissions> dev_permissions; std::vector<std::string> firmware_directories; std::vector<ExternalFirmwareHandler> external_firmware_handlers; std::vector<std::string> parallel_restorecon_dirs; bool enable_modalias_handling = false; size_t uevent_socket_rcvbuf_size = 0; bool enable_parallel_restorecon = false; Loading
init/ueventd_parser_test.cpp +36 −9 Original line number Diff line number Diff line Loading @@ -77,6 +77,7 @@ void TestUeventdFile(const std::string& content, const UeventdConfiguration& exp EXPECT_EQ(expected.firmware_directories, result.firmware_directories); TestVector(expected.external_firmware_handlers, result.external_firmware_handlers, TestExternalFirmwareHandler); EXPECT_EQ(expected.parallel_restorecon_dirs, result.parallel_restorecon_dirs); } TEST(ueventd_parser, EmptyFile) { Loading Loading @@ -105,7 +106,7 @@ subsystem test_devpath_dirname {"test_devname2", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"}, {"test_devpath_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev/graphics"}}; TestUeventdFile(ueventd_file, {subsystems, {}, {}, {}, {}}); TestUeventdFile(ueventd_file, {subsystems, {}, {}, {}, {}, {}}); } TEST(ueventd_parser, Permissions) { Loading @@ -131,7 +132,7 @@ TEST(ueventd_parser, Permissions) { {"/sys/devices/virtual/*/input", "poll_delay", 0660, AID_ROOT, AID_INPUT, true}, }; TestUeventdFile(ueventd_file, {{}, sysfs_permissions, permissions, {}, {}}); TestUeventdFile(ueventd_file, {{}, sysfs_permissions, permissions, {}, {}, {}}); } TEST(ueventd_parser, FirmwareDirectories) { Loading @@ -147,7 +148,7 @@ firmware_directories /more "/more", }; TestUeventdFile(ueventd_file, {{}, {}, {}, firmware_directories, {}}); TestUeventdFile(ueventd_file, {{}, {}, {}, firmware_directories, {}, {}}); } TEST(ueventd_parser, ExternalFirmwareHandlers) { Loading Loading @@ -213,7 +214,7 @@ external_firmware_handler /devices/path/firmware/something004.bin radio radio "/ }, }; TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers}); TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers, {}}); } TEST(ueventd_parser, ExternalFirmwareHandlersDuplicate) { Loading @@ -231,7 +232,21 @@ external_firmware_handler devpath root handler_path2 }, }; TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers}); TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers, {}}); } TEST(ueventd_parser, ParallelRestoreconDirs) { auto ueventd_file = R"( parallel_restorecon_dir /sys parallel_restorecon_dir /sys/devices )"; auto parallel_restorecon_dirs = std::vector<std::string>{ "/sys", "/sys/devices", }; TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, parallel_restorecon_dirs}); } TEST(ueventd_parser, UeventSocketRcvbufSize) { Loading @@ -240,7 +255,7 @@ uevent_socket_rcvbuf_size 8k uevent_socket_rcvbuf_size 8M )"; TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, false, 8 * 1024 * 1024}); TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, {}, false, 8 * 1024 * 1024}); } TEST(ueventd_parser, EnabledDisabledLines) { Loading @@ -250,7 +265,7 @@ parallel_restorecon enabled modalias_handling disabled )"; TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, false, 0, true}); TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, {}, false, 0, true}); auto ueventd_file2 = R"( parallel_restorecon enabled Loading @@ -258,7 +273,7 @@ modalias_handling enabled parallel_restorecon disabled )"; TestUeventdFile(ueventd_file2, {{}, {}, {}, {}, {}, true, 0, false}); TestUeventdFile(ueventd_file2, {{}, {}, {}, {}, {}, {}, true, 0, false}); } TEST(ueventd_parser, AllTogether) { Loading Loading @@ -298,6 +313,9 @@ uevent_socket_rcvbuf_size 6M modalias_handling enabled parallel_restorecon enabled parallel_restorecon_dir /sys parallel_restorecon_dir /sys/devices #ending comment )"; Loading Loading @@ -330,11 +348,17 @@ parallel_restorecon enabled {"/devices/path/firmware/firmware001.bin", AID_ROOT, AID_ROOT, "/vendor/bin/touch.sh"}, }; auto parallel_restorecon_dirs = std::vector<std::string>{ "/sys", "/sys/devices", }; size_t uevent_socket_rcvbuf_size = 6 * 1024 * 1024; TestUeventdFile(ueventd_file, {subsystems, sysfs_permissions, permissions, firmware_directories, external_firmware_handlers, true, uevent_socket_rcvbuf_size, true}); external_firmware_handlers, parallel_restorecon_dirs, true, uevent_socket_rcvbuf_size, true}); } // All of these lines are ill-formed, so test that there is 0 output. Loading Loading @@ -366,6 +390,9 @@ external_firmware_handler external_firmware_handler blah blah external_firmware_handler blah blah blah blah parallel_restorecon_dir parallel_restorecon_dir /sys /sys/devices )"; TestUeventdFile(ueventd_file, {}); Loading