Loading init/init_first_stage.cpp +47 −73 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ #include <stdlib.h> #include <unistd.h> #include <chrono> #include <memory> #include <set> #include <string> Loading @@ -36,8 +35,6 @@ #include "uevent_listener.h" #include "util.h" using namespace std::chrono_literals; // Class Declarations // ------------------ class FirstStageMount { Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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) { uevent_listener_.RegenerateUeventsForPath("/sys" + dm_path, [this, &dm_path](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; 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()) { Loading @@ -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) { 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); found = true; return ListenerAction::kStop; return RegenerationAction::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; return RegenerationAction::kContinue; }); } bool FirstStageMount::MountPartitions() { Loading Loading @@ -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; } Loading Loading @@ -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 Loading init/uevent_listener.cpp +16 −34 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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; } } Loading @@ -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<DIR, decltype(&closedir)> 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<std::chrono::milliseconds> 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<milliseconds>(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); } } } Loading init/uevent_listener.h +8 −10 Original line number Diff line number Diff line Loading @@ -19,9 +19,7 @@ #include <dirent.h> #include <chrono> #include <functional> #include <optional> #include <android-base/unique_fd.h> Loading @@ -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<ListenerAction(const Uevent&)>; using RegenerateCallback = std::function<RegenerationAction(const Uevent&)>; using PollCallback = std::function<void(const Uevent&)>; 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<std::chrono::milliseconds> 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_; }; Loading init/ueventd.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -138,7 +138,7 @@ void ColdBoot::RegenerateUevents() { HandleFirmwareEvent(uevent); uevent_queue_.emplace_back(std::move(uevent)); return ListenerAction::kContinue; return RegenerationAction::kContinue; }); } Loading Loading @@ -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; Loading Loading
init/init_first_stage.cpp +47 −73 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ #include <stdlib.h> #include <unistd.h> #include <chrono> #include <memory> #include <set> #include <string> Loading @@ -36,8 +35,6 @@ #include "uevent_listener.h" #include "util.h" using namespace std::chrono_literals; // Class Declarations // ------------------ class FirstStageMount { Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -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) { uevent_listener_.RegenerateUeventsForPath("/sys" + dm_path, [this, &dm_path](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; 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()) { Loading @@ -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) { 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); found = true; return ListenerAction::kStop; return RegenerationAction::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; return RegenerationAction::kContinue; }); } bool FirstStageMount::MountPartitions() { Loading Loading @@ -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; } Loading Loading @@ -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 Loading
init/uevent_listener.cpp +16 −34 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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; } } Loading @@ -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<DIR, decltype(&closedir)> 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<std::chrono::milliseconds> 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<milliseconds>(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); } } } Loading
init/uevent_listener.h +8 −10 Original line number Diff line number Diff line Loading @@ -19,9 +19,7 @@ #include <dirent.h> #include <chrono> #include <functional> #include <optional> #include <android-base/unique_fd.h> Loading @@ -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<ListenerAction(const Uevent&)>; using RegenerateCallback = std::function<RegenerationAction(const Uevent&)>; using PollCallback = std::function<void(const Uevent&)>; 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<std::chrono::milliseconds> 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_; }; Loading
init/ueventd.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -138,7 +138,7 @@ void ColdBoot::RegenerateUevents() { HandleFirmwareEvent(uevent); uevent_queue_.emplace_back(std::move(uevent)); return ListenerAction::kContinue; return RegenerationAction::kContinue; }); } Loading Loading @@ -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; Loading