Implement Cpu Freq Section
When poll from sysfs, revents return POLLERR by default, handles
this edge case in this cl.
Bug: 68774444
Test: unit tested + on device tests
Change-Id: I23540299c026d3e7676497f56690e9f8646a47bd
diff --git a/cmds/incidentd/src/FdBuffer.cpp b/cmds/incidentd/src/FdBuffer.cpp
index b7633a4..30dd339 100644
--- a/cmds/incidentd/src/FdBuffer.cpp
+++ b/cmds/incidentd/src/FdBuffer.cpp
@@ -26,6 +26,7 @@
#include <unistd.h>
#include <wait.h>
+const bool DEBUG = false;
const ssize_t BUFFER_SIZE = 16 * 1024; // 16 KB
const ssize_t MAX_BUFFER_COUNT = 256; // 4 MB max
@@ -71,9 +72,11 @@
mTimedOut = true;
break;
} else if (count < 0) {
+ if (DEBUG) ALOGD("poll failed: %s", strerror(errno));
return -errno;
} else {
if ((pfds.revents & POLLERR) != 0) {
+ if (DEBUG) ALOGD("return event has error %s", strerror(errno));
return errno != 0 ? -errno : UNKNOWN_ERROR;
} else {
ssize_t amt = ::read(fd, mBuffer.writeBuffer(), mBuffer.currentToWrite());
@@ -81,6 +84,7 @@
if (errno == EAGAIN || errno == EWOULDBLOCK) {
continue;
} else {
+ if (DEBUG) ALOGD("Fail to read %d: %s", fd, strerror(errno));
return -errno;
}
} else if (amt == 0) {
@@ -95,7 +99,7 @@
}
status_t
-FdBuffer::readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeoutMs)
+FdBuffer::readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeoutMs, const bool isSysfs)
{
struct pollfd pfds[] = {
{ .fd = fd, .events = POLLIN },
@@ -135,12 +139,18 @@
mTimedOut = true;
break;
} else if (count < 0) {
+ if (DEBUG) ALOGD("Fail to poll: %s", strerror(errno));
return -errno;
}
// make sure no errors occur on any fds
for (int i = 0; i < 3; ++i) {
if ((pfds[i].revents & POLLERR) != 0) {
+ if (i == 0 && isSysfs) {
+ if (DEBUG) ALOGD("fd %d is sysfs, ignore its POLLERR return value", fd);
+ continue;
+ }
+ if (DEBUG) ALOGD("fd[%d]=%d returns error events: %s", i, fd, strerror(errno));
return errno != 0 ? -errno : UNKNOWN_ERROR;
}
}
@@ -155,6 +165,7 @@
}
if (amt < 0) {
if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
+ if (DEBUG) ALOGD("Fail to read fd %d: %s", fd, strerror(errno));
return -errno;
} // otherwise just continue
} else if (amt == 0) { // reach EOF so don't have to poll pfds[0].
@@ -176,6 +187,7 @@
}
if (amt < 0) {
if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
+ if (DEBUG) ALOGD("Fail to write toFd %d: %s", toFd, strerror(errno));
return -errno;
} // otherwise just continue
} else {
@@ -202,6 +214,7 @@
ssize_t amt = ::read(fromFd, mBuffer.writeBuffer(), mBuffer.currentToWrite());
if (amt < 0) {
if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
+ if (DEBUG) ALOGD("Fail to read fromFd %d: %s", fromFd, strerror(errno));
return -errno;
} // otherwise just continue
} else if (amt == 0) {
diff --git a/cmds/incidentd/src/FdBuffer.h b/cmds/incidentd/src/FdBuffer.h
index 8857ae7..48dc855 100644
--- a/cmds/incidentd/src/FdBuffer.h
+++ b/cmds/incidentd/src/FdBuffer.h
@@ -47,8 +47,10 @@
* and stores the processed data from 'fromFd' in memory for later usage.
* This function behaves in a streaming fashion in order to save memory usage.
* Returns NO_ERROR if there were no errors or if we timed out.
+ *
+ * Poll will return POLLERR if fd is from sysfs, handle this edge case.
*/
- status_t readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeoutMs);
+ status_t readProcessedDataInStream(int fd, int toFd, int fromFd, int64_t timeoutMs, const bool isSysfs=false);
/**
* Whether we timed out.
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index 892bcca..c08b9ea 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -232,6 +232,7 @@
mFilename(filename)
{
name = filename;
+ mIsSysfs = strncmp(filename, "/sys/", 5) == 0;
}
FileSection::~FileSection() {}
@@ -264,7 +265,7 @@
// parent process
status_t readStatus = buffer.readProcessedDataInStream(fd, p2cPipe.writeFd(), c2pPipe.readFd(),
- this->timeoutMs);
+ this->timeoutMs, mIsSysfs);
if (readStatus != NO_ERROR || buffer.timedOut()) {
ALOGW("FileSection '%s' failed to read data from incident helper: %s, timedout: %s, kill: %s",
this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false",
diff --git a/cmds/incidentd/src/Section.h b/cmds/incidentd/src/Section.h
index 0a1e03e..64558a6 100644
--- a/cmds/incidentd/src/Section.h
+++ b/cmds/incidentd/src/Section.h
@@ -69,6 +69,7 @@
private:
const char* mFilename;
+ bool mIsSysfs; // sysfs files are pollable but return POLLERR by default, handle it separately
};
/**