From d6fccea093ebe5a5d929549d721185b0f1b52ac0 Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Wed, 21 Jun 2017 18:40:58 +0000 Subject: [PATCH] Revert "init: poll in first stage mount if required devices are not found" Bug: 62864413 This reverts commit ccf0d39316dcf6cfd7c50d131fd681a1f6c8fd74. Change-Id: I343e304db4c0e7af2402397ef468cc743a3f08a9 --- init/init_first_stage.cpp | 120 +++++++++++++++----------------------- init/uevent_listener.cpp | 50 +++++----------- init/uevent_listener.h | 18 +++--- init/ueventd.cpp | 5 +- 4 files changed, 73 insertions(+), 120 deletions(-) diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp index 8433056ad..ebbe1cd18 100644 --- a/init/init_first_stage.cpp +++ b/init/init_first_stage.cpp @@ -19,7 +19,6 @@ #include #include -#include #include #include #include @@ -36,8 +35,6 @@ #include "uevent_listener.h" #include "util.h" -using namespace std::chrono_literals; - // Class Declarations // ------------------ class FirstStageMount { @@ -52,11 +49,11 @@ class FirstStageMount { bool InitDevices(); protected: - bool InitRequiredDevices(); - bool InitVerityDevice(const std::string& verity_device); + void InitRequiredDevices(); + void InitVerityDevice(const std::string& verity_device); bool MountPartitions(); - virtual ListenerAction UeventCallback(const Uevent& uevent); + virtual RegenerationAction UeventCallback(const Uevent& uevent); // Pure virtual functions. virtual bool GetRequiredDevices() = 0; @@ -89,7 +86,7 @@ class FirstStageMountVBootV2 : public FirstStageMount { ~FirstStageMountVBootV2() override = default; protected: - ListenerAction UeventCallback(const Uevent& uevent) override; + RegenerationAction UeventCallback(const Uevent& uevent) override; bool GetRequiredDevices() override; bool SetUpDmVerity(fstab_rec* fstab_rec) override; bool InitAvbHandle(); @@ -144,60 +141,49 @@ bool FirstStageMount::DoFirstStageMount() { } bool FirstStageMount::InitDevices() { - return GetRequiredDevices() && InitRequiredDevices(); + if (!GetRequiredDevices()) return false; + + InitRequiredDevices(); + + // InitRequiredDevices() will remove found partitions from required_devices_partition_names_. + // So if it isn't empty here, it means some partitions are not found. + if (!required_devices_partition_names_.empty()) { + LOG(ERROR) << __FUNCTION__ << "(): partition(s) not found: " + << android::base::Join(required_devices_partition_names_, ", "); + return false; + } else { + return true; + } } // Creates devices with uevent->partition_name matching one in the member variable // required_devices_partition_names_. Found partitions will then be removed from it // for the subsequent member function to check which devices are NOT created. -bool FirstStageMount::InitRequiredDevices() { +void FirstStageMount::InitRequiredDevices() { if (required_devices_partition_names_.empty()) { - return true; + return; } if (need_dm_verity_) { const std::string dm_path = "/devices/virtual/misc/device-mapper"; - bool found = false; - auto dm_callback = [this, &dm_path, &found](const Uevent& uevent) { - if (uevent.path == dm_path) { - device_handler_.HandleDeviceEvent(uevent); - found = true; - return ListenerAction::kStop; - } - return ListenerAction::kContinue; - }; - uevent_listener_.RegenerateUeventsForPath("/sys" + dm_path, dm_callback); - if (!found) { - uevent_listener_.Poll(dm_callback, 10s); - } - if (!found) { - LOG(ERROR) << "device-mapper device not found"; - return false; - } + uevent_listener_.RegenerateUeventsForPath("/sys" + dm_path, + [this, &dm_path](const Uevent& uevent) { + if (uevent.path == dm_path) { + device_handler_.HandleDeviceEvent(uevent); + return RegenerationAction::kStop; + } + return RegenerationAction::kContinue; + }); } - auto uevent_callback = [this](const Uevent& uevent) { return UeventCallback(uevent); }; - uevent_listener_.RegenerateUevents(uevent_callback); - - // UeventCallback() will remove found partitions from required_devices_partition_names_. - // So if it isn't empty here, it means some partitions are not found. - if (!required_devices_partition_names_.empty()) { - uevent_listener_.Poll(uevent_callback, 10s); - } - - if (!required_devices_partition_names_.empty()) { - LOG(ERROR) << __PRETTY_FUNCTION__ << ": partition(s) not found: " - << android::base::Join(required_devices_partition_names_, ", "); - return false; - } - - return true; + uevent_listener_.RegenerateUevents( + [this](const Uevent& uevent) { return UeventCallback(uevent); }); } -ListenerAction FirstStageMount::UeventCallback(const Uevent& uevent) { +RegenerationAction FirstStageMount::UeventCallback(const Uevent& uevent) { // Ignores everything that is not a block device. if (uevent.subsystem != "block") { - return ListenerAction::kContinue; + return RegenerationAction::kContinue; } if (!uevent.partition_name.empty()) { @@ -206,46 +192,34 @@ ListenerAction FirstStageMount::UeventCallback(const Uevent& uevent) { // suffix when A/B is used. auto iter = required_devices_partition_names_.find(uevent.partition_name); if (iter != required_devices_partition_names_.end()) { - LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << *iter; + LOG(VERBOSE) << __FUNCTION__ << "(): found partition: " << *iter; required_devices_partition_names_.erase(iter); device_handler_.HandleDeviceEvent(uevent); if (required_devices_partition_names_.empty()) { - return ListenerAction::kStop; + return RegenerationAction::kStop; } else { - return ListenerAction::kContinue; + return RegenerationAction::kContinue; } } } // Not found a partition or find an unneeded partition, continue to find others. - return ListenerAction::kContinue; + return RegenerationAction::kContinue; } // Creates "/dev/block/dm-XX" for dm-verity by running coldboot on /sys/block/dm-XX. -bool FirstStageMount::InitVerityDevice(const std::string& verity_device) { +void FirstStageMount::InitVerityDevice(const std::string& verity_device) { const std::string device_name(basename(verity_device.c_str())); const std::string syspath = "/sys/block/" + device_name; - bool found = false; - auto verity_callback = [&device_name, &verity_device, this, &found](const Uevent& uevent) { - if (uevent.device_name == device_name) { - LOG(VERBOSE) << "Creating dm-verity device : " << verity_device; - device_handler_.HandleDeviceEvent(uevent); - found = true; - return ListenerAction::kStop; - } - return ListenerAction::kContinue; - }; - - uevent_listener_.RegenerateUeventsForPath(syspath, verity_callback); - if (!found) { - uevent_listener_.Poll(verity_callback, 10s); - } - if (!found) { - LOG(ERROR) << "dm-verity device not found"; - return false; - } - - return true; + uevent_listener_.RegenerateUeventsForPath( + syspath, [&device_name, &verity_device, this](const Uevent& uevent) { + if (uevent.device_name == device_name) { + LOG(VERBOSE) << "Creating dm-verity device : " << verity_device; + device_handler_.HandleDeviceEvent(uevent); + return RegenerationAction::kStop; + } + return RegenerationAction::kContinue; + }); } bool FirstStageMount::MountPartitions() { @@ -311,7 +285,7 @@ bool FirstStageMountVBootV1::SetUpDmVerity(fstab_rec* fstab_rec) { } else if (ret == FS_MGR_SETUP_VERITY_SUCCESS) { // The exact block device name (fstab_rec->blk_device) is changed to "/dev/block/dm-XX". // Needs to create it because ueventd isn't started in init first stage. - return InitVerityDevice(fstab_rec->blk_device); + InitVerityDevice(fstab_rec->blk_device); } else { return false; } @@ -371,7 +345,7 @@ bool FirstStageMountVBootV2::GetRequiredDevices() { return true; } -ListenerAction FirstStageMountVBootV2::UeventCallback(const Uevent& uevent) { +RegenerationAction FirstStageMountVBootV2::UeventCallback(const Uevent& uevent) { // Check if this uevent corresponds to one of the required partitions and store its symlinks if // so, in order to create FsManagerAvbHandle later. // Note that the parent callback removes partitions from the list of required partitions diff --git a/init/uevent_listener.cpp b/init/uevent_listener.cpp index c7489843e..27c5d2374 100644 --- a/init/uevent_listener.cpp +++ b/init/uevent_listener.cpp @@ -121,8 +121,8 @@ bool UeventListener::ReadUevent(Uevent* uevent) const { // make sure we don't overrun the socket's buffer. // -ListenerAction UeventListener::RegenerateUeventsForDir(DIR* d, - const ListenerCallback& callback) const { +RegenerationAction UeventListener::RegenerateUeventsForDir(DIR* d, + RegenerateCallback callback) const { int dfd = dirfd(d); int fd = openat(dfd, "uevent", O_WRONLY); @@ -132,7 +132,7 @@ ListenerAction UeventListener::RegenerateUeventsForDir(DIR* d, Uevent uevent; while (ReadUevent(&uevent)) { - if (callback(uevent) == ListenerAction::kStop) return ListenerAction::kStop; + if (callback(uevent) == RegenerationAction::kStop) return RegenerationAction::kStop; } } @@ -147,67 +147,49 @@ ListenerAction UeventListener::RegenerateUeventsForDir(DIR* d, if (d2 == 0) { close(fd); } else { - if (RegenerateUeventsForDir(d2.get(), callback) == ListenerAction::kStop) { - return ListenerAction::kStop; + if (RegenerateUeventsForDir(d2.get(), callback) == RegenerationAction::kStop) { + return RegenerationAction::kStop; } } } // default is always to continue looking for uevents - return ListenerAction::kContinue; + return RegenerationAction::kContinue; } -ListenerAction UeventListener::RegenerateUeventsForPath(const std::string& path, - const ListenerCallback& callback) const { +RegenerationAction UeventListener::RegenerateUeventsForPath(const std::string& path, + RegenerateCallback callback) const { std::unique_ptr d(opendir(path.c_str()), closedir); - if (!d) return ListenerAction::kContinue; + if (!d) return RegenerationAction::kContinue; return RegenerateUeventsForDir(d.get(), callback); } static const char* kRegenerationPaths[] = {"/sys/class", "/sys/block", "/sys/devices"}; -void UeventListener::RegenerateUevents(const ListenerCallback& callback) const { +void UeventListener::RegenerateUevents(RegenerateCallback callback) const { for (const auto path : kRegenerationPaths) { - if (RegenerateUeventsForPath(path, callback) == ListenerAction::kStop) return; + if (RegenerateUeventsForPath(path, callback) == RegenerationAction::kStop) return; } } -void UeventListener::Poll(const ListenerCallback& callback, - const std::optional relative_timeout) const { - using namespace std::chrono; - +void UeventListener::DoPolling(PollCallback callback) const { pollfd ufd; ufd.events = POLLIN; ufd.fd = device_fd_; - auto start_time = steady_clock::now(); - while (true) { ufd.revents = 0; - - int timeout_ms = -1; - if (relative_timeout) { - auto now = steady_clock::now(); - auto time_elapsed = duration_cast(now - start_time); - if (time_elapsed > *relative_timeout) return; - - auto remaining_timeout = *relative_timeout - time_elapsed; - timeout_ms = remaining_timeout.count(); - } - - int nr = poll(&ufd, 1, timeout_ms); - if (nr == 0) return; - if (nr < 0) { - PLOG(ERROR) << "poll() of uevent socket failed, continuing"; + int nr = poll(&ufd, 1, -1); + if (nr <= 0) { continue; } if (ufd.revents & POLLIN) { - // We're non-blocking, so if we receive a poll event keep processing until + // We're non-blocking, so if we receive a poll event keep processing until there // we have exhausted all uevent messages. Uevent uevent; while (ReadUevent(&uevent)) { - if (callback(uevent) == ListenerAction::kStop) return; + callback(uevent); } } } diff --git a/init/uevent_listener.h b/init/uevent_listener.h index 0dae102ed..ba31aaa71 100644 --- a/init/uevent_listener.h +++ b/init/uevent_listener.h @@ -19,9 +19,7 @@ #include -#include #include -#include #include @@ -29,26 +27,26 @@ #define UEVENT_MSG_LEN 2048 -enum class ListenerAction { +enum class RegenerationAction { kStop = 0, // Stop regenerating uevents as we've handled the one(s) we're interested in. kContinue, // Continue regenerating uevents as we haven't seen the one(s) we're interested in. }; -using ListenerCallback = std::function; +using RegenerateCallback = std::function; +using PollCallback = std::function; class UeventListener { public: UeventListener(); - void RegenerateUevents(const ListenerCallback& callback) const; - ListenerAction RegenerateUeventsForPath(const std::string& path, - const ListenerCallback& callback) const; - void Poll(const ListenerCallback& callback, - const std::optional relative_timeout = {}) const; + void RegenerateUevents(RegenerateCallback callback) const; + RegenerationAction RegenerateUeventsForPath(const std::string& path, + RegenerateCallback callback) const; + void DoPolling(PollCallback callback) const; private: bool ReadUevent(Uevent* uevent) const; - ListenerAction RegenerateUeventsForDir(DIR* d, const ListenerCallback& callback) const; + RegenerationAction RegenerateUeventsForDir(DIR* d, RegenerateCallback callback) const; android::base::unique_fd device_fd_; }; diff --git a/init/ueventd.cpp b/init/ueventd.cpp index 4982b7774..28c1c076a 100644 --- a/init/ueventd.cpp +++ b/init/ueventd.cpp @@ -138,7 +138,7 @@ void ColdBoot::RegenerateUevents() { HandleFirmwareEvent(uevent); uevent_queue_.emplace_back(std::move(uevent)); - return ListenerAction::kContinue; + return RegenerationAction::kContinue; }); } @@ -266,10 +266,9 @@ int ueventd_main(int argc, char** argv) { cold_boot.Run(); } - uevent_listener.Poll([&device_handler](const Uevent& uevent) { + uevent_listener.DoPolling([&device_handler](const Uevent& uevent) { HandleFirmwareEvent(uevent); device_handler.HandleDeviceEvent(uevent); - return ListenerAction::kContinue; }); return 0;