summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManish Varma <varmam@google.com>2021-08-10 15:07:55 -0700
committerManish Varma <varmam@google.com>2021-08-13 14:57:57 -0700
commit5e3700ea441ff21328b0cd1f417974feaf30153c (patch)
tree538073ef06289b37e6463f16240a47df4a28c3d4
parente2f08410be0dc611b674db50c68f8a15c78cbffa (diff)
downloadinterfaces-5e3700ea441ff21328b0cd1f417974feaf30153c.tar.gz
system_suspend: allow SystemSuspend to re-open the fd if found stale
Based on the BR it is evedent that when kernel fails to write any wakeup reasons in /sys/kernel/wakeup_reasons/last_resume_reason, i.e. if the file is read empty by system_suspend then the file descriptor associated with that file becomes stale and cannot read the file contents anymore, and all the subsequent attempts to read the wakeup_reason returns empty which causes flurry of "unknown" wakeup reasons. Also, kernel only writes the wakeup reason in the sysfs node upon read() call to the sysfs node, and hence it is not possible to know ahead of time if the kernel is going to return empty file. While we cannot prevent this error condition, we can certainly receover re-opening the fd associated with "last_resume_reason" file. Since it's main that opens all the files and pass their file descriptors to SystemSuspend.cpp to do further file handling. This change will re-open file for that stale fd using "/proc/self/fd/<fd>" when it detects the failure condition, i.e. when an attempt to read last_resume_reason file returns empty. Bug: 192813633 Test: SystemSuspendV1_0UnitTest Signed-off-by: Manish Varma <varmam@google.com> Change-Id: I9e142f6526a1c0f836202725b593c624536c0f64
-rw-r--r--suspend/1.0/default/SystemSuspend.cpp22
-rw-r--r--suspend/1.0/default/SystemSuspend.h1
2 files changed, 21 insertions, 2 deletions
diff --git a/suspend/1.0/default/SystemSuspend.cpp b/suspend/1.0/default/SystemSuspend.cpp
index 81f3d45..2262c58 100644
--- a/suspend/1.0/default/SystemSuspend.cpp
+++ b/suspend/1.0/default/SystemSuspend.cpp
@@ -18,6 +18,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <fcntl.h>
#include <hidl/Status.h>
@@ -70,8 +71,8 @@ static std::vector<std::string> readWakeupReasons(int fd) {
std::string reasonlines;
lseek(fd, 0, SEEK_SET);
- if (!ReadFdToString(fd, &reasonlines)) {
- LOG(ERROR) << "failed to read wakeup reasons";
+ if (!ReadFdToString(fd, &reasonlines) || reasonlines.empty()) {
+ PLOG(ERROR) << "failed to read wakeup reasons";
// Return unknown wakeup reason if we fail to read
return {kUnknownWakeup};
}
@@ -236,6 +237,17 @@ void SystemSuspend::decSuspendCounter(const string& name) {
}
}
+unique_fd SystemSuspend::reopenFileUsingFd(const int pid, const int fd, const int permission) {
+ string filePath = android::base::StringPrintf("/proc/%d/fd/%d", pid, fd);
+
+ unique_fd tempFd{TEMP_FAILURE_RETRY(open(filePath.c_str(), permission))};
+ if (tempFd < 0) {
+ PLOG(ERROR) << "SystemSuspend: Error opening file, using path: " << filePath;
+ return unique_fd(-1);
+ }
+ return tempFd;
+}
+
void SystemSuspend::initAutosuspend() {
std::thread autosuspendThread([this] {
while (true) {
@@ -268,6 +280,12 @@ void SystemSuspend::initAutosuspend() {
updateSleepTime(success, suspendTime);
std::vector<std::string> wakeupReasons = readWakeupReasons(mWakeupReasonsFd);
+ if (wakeupReasons == std::vector<std::string>({kUnknownWakeup})) {
+ LOG(INFO) << "Unknown/empty wakeup reason. Re-opening wakeup_reason file.";
+
+ mWakeupReasonsFd = std::move(reopenFileUsingFd(
+ getCallingPid(), mWakeupReasonsFd.get(), O_CLOEXEC | O_RDONLY));
+ }
mWakeupList.update(wakeupReasons);
mControlService->notifyWakeup(success, wakeupReasons);
diff --git a/suspend/1.0/default/SystemSuspend.h b/suspend/1.0/default/SystemSuspend.h
index 5632325..e5a0e84 100644
--- a/suspend/1.0/default/SystemSuspend.h
+++ b/suspend/1.0/default/SystemSuspend.h
@@ -114,6 +114,7 @@ class SystemSuspend : public ISystemSuspend {
Result<SuspendStats> getSuspendStats();
void getSuspendInfo(SuspendInfo* info);
std::chrono::milliseconds getSleepTime() const;
+ unique_fd reopenFileUsingFd(const int pid, const int fd, int permission);
private:
void initAutosuspend();