diff options
author | Mark Salyzyn | 2016-10-10 09:27:42 -0500 |
---|---|---|
committer | Mark Salyzyn | 2016-10-13 16:43:42 -0500 |
commit | db8a266aea6c12b0fb8ee3587d72333662b05266 (patch) | |
tree | c10491cebcf0b69c99aa0e8ed56611a50d0080b4 /liblog/pmsg_writer.c | |
parent | bf0cf4e22d594db03c1dcef57fd18d3ae038eefb (diff) | |
download | platform-system-core-db8a266aea6c12b0fb8ee3587d72333662b05266.tar.gz platform-system-core-db8a266aea6c12b0fb8ee3587d72333662b05266.tar.xz platform-system-core-db8a266aea6c12b0fb8ee3587d72333662b05266.zip |
liblog: __android_log_pmsg_file_write() cleanup
__android_log_pmsg_file_write() will open /dev/pmsg0 if not
already, and will close it if we opened it.
Added atomic access to the android_log_context as insurance.
Fortify and correct pmsg tests.
Test: gTest liblog-unit-tests --gtest_filter=liblog.__android_log_pmsg_file_*
Bug: 31958686
Change-Id: I2cf6f971b6968938f471fda67367efe20dae3004
Diffstat (limited to 'liblog/pmsg_writer.c')
-rw-r--r-- | liblog/pmsg_writer.c | 63 |
1 files changed, 42 insertions, 21 deletions
diff --git a/liblog/pmsg_writer.c b/liblog/pmsg_writer.c index 06652f3c1..b3c4a1a04 100644 --- a/liblog/pmsg_writer.c +++ b/liblog/pmsg_writer.c | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | #include <errno.h> | 21 | #include <errno.h> |
22 | #include <fcntl.h> | 22 | #include <fcntl.h> |
23 | #include <stdbool.h> | ||
23 | #include <stdlib.h> | 24 | #include <stdlib.h> |
24 | #include <string.h> | 25 | #include <string.h> |
25 | #include <sys/types.h> | 26 | #include <sys/types.h> |
@@ -53,18 +54,25 @@ LIBLOG_HIDDEN struct android_log_transport_write pmsgLoggerWrite = { | |||
53 | 54 | ||
54 | static int pmsgOpen() | 55 | static int pmsgOpen() |
55 | { | 56 | { |
56 | if (pmsgLoggerWrite.context.fd < 0) { | 57 | int fd = atomic_load(&pmsgLoggerWrite.context.fd); |
57 | pmsgLoggerWrite.context.fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC)); | 58 | if (fd < 0) { |
59 | int i; | ||
60 | |||
61 | fd = TEMP_FAILURE_RETRY(open("/dev/pmsg0", O_WRONLY | O_CLOEXEC)); | ||
62 | i = atomic_exchange(&pmsgLoggerWrite.context.fd, fd); | ||
63 | if ((i >= 0) && (i != fd)) { | ||
64 | close(i); | ||
65 | } | ||
58 | } | 66 | } |
59 | 67 | ||
60 | return pmsgLoggerWrite.context.fd; | 68 | return fd; |
61 | } | 69 | } |
62 | 70 | ||
63 | static void pmsgClose() | 71 | static void pmsgClose() |
64 | { | 72 | { |
65 | if (pmsgLoggerWrite.context.fd >= 0) { | 73 | int fd = atomic_exchange(&pmsgLoggerWrite.context.fd, -1); |
66 | close(pmsgLoggerWrite.context.fd); | 74 | if (fd >= 0) { |
67 | pmsgLoggerWrite.context.fd = -1; | 75 | close(fd); |
68 | } | 76 | } |
69 | } | 77 | } |
70 | 78 | ||
@@ -78,7 +86,7 @@ static int pmsgAvailable(log_id_t logId) | |||
78 | !__android_log_is_debuggable()) { | 86 | !__android_log_is_debuggable()) { |
79 | return -EINVAL; | 87 | return -EINVAL; |
80 | } | 88 | } |
81 | if (pmsgLoggerWrite.context.fd < 0) { | 89 | if (atomic_load(&pmsgLoggerWrite.context.fd) < 0) { |
82 | if (access("/dev/pmsg0", W_OK) == 0) { | 90 | if (access("/dev/pmsg0", W_OK) == 0) { |
83 | return 0; | 91 | return 0; |
84 | } | 92 | } |
@@ -115,7 +123,7 @@ static int pmsgWrite(log_id_t logId, struct timespec *ts, | |||
115 | } | 123 | } |
116 | } | 124 | } |
117 | 125 | ||
118 | if (pmsgLoggerWrite.context.fd < 0) { | 126 | if (atomic_load(&pmsgLoggerWrite.context.fd) < 0) { |
119 | return -EBADF; | 127 | return -EBADF; |
120 | } | 128 | } |
121 | 129 | ||
@@ -169,7 +177,8 @@ static int pmsgWrite(log_id_t logId, struct timespec *ts, | |||
169 | } | 177 | } |
170 | pmsgHeader.len += payloadSize; | 178 | pmsgHeader.len += payloadSize; |
171 | 179 | ||
172 | ret = TEMP_FAILURE_RETRY(writev(pmsgLoggerWrite.context.fd, newVec, i)); | 180 | ret = TEMP_FAILURE_RETRY(writev(atomic_load(&pmsgLoggerWrite.context.fd), |
181 | newVec, i)); | ||
173 | if (ret < 0) { | 182 | if (ret < 0) { |
174 | ret = errno ? -errno : -ENOTCONN; | 183 | ret = errno ? -errno : -ENOTCONN; |
175 | } | 184 | } |
@@ -206,7 +215,7 @@ LIBLOG_ABI_PRIVATE ssize_t __android_log_pmsg_file_write( | |||
206 | char prio, | 215 | char prio, |
207 | const char *filename, | 216 | const char *filename, |
208 | const char *buf, size_t len) { | 217 | const char *buf, size_t len) { |
209 | int fd; | 218 | bool weOpened; |
210 | size_t length, packet_len; | 219 | size_t length, packet_len; |
211 | const char *tag; | 220 | const char *tag; |
212 | char *cp, *slash; | 221 | char *cp, *slash; |
@@ -228,16 +237,6 @@ LIBLOG_ABI_PRIVATE ssize_t __android_log_pmsg_file_write( | |||
228 | return -ENOMEM; | 237 | return -ENOMEM; |
229 | } | 238 | } |
230 | 239 | ||
231 | fd = pmsgLoggerWrite.context.fd; | ||
232 | if (fd < 0) { | ||
233 | __android_log_lock(); | ||
234 | fd = pmsgOpen(); | ||
235 | __android_log_unlock(); | ||
236 | if (fd < 0) { | ||
237 | return -EBADF; | ||
238 | } | ||
239 | } | ||
240 | |||
241 | tag = cp; | 240 | tag = cp; |
242 | slash = strrchr(cp, '/'); | 241 | slash = strrchr(cp, '/'); |
243 | if (slash) { | 242 | if (slash) { |
@@ -256,6 +255,7 @@ LIBLOG_ABI_PRIVATE ssize_t __android_log_pmsg_file_write( | |||
256 | vec[1].iov_base = (unsigned char *)tag; | 255 | vec[1].iov_base = (unsigned char *)tag; |
257 | vec[1].iov_len = length; | 256 | vec[1].iov_len = length; |
258 | 257 | ||
258 | weOpened = false; | ||
259 | for (ts.tv_nsec = 0, length = len; | 259 | for (ts.tv_nsec = 0, length = len; |
260 | length; | 260 | length; |
261 | ts.tv_nsec += ANDROID_LOG_PMSG_FILE_SEQUENCE) { | 261 | ts.tv_nsec += ANDROID_LOG_PMSG_FILE_SEQUENCE) { |
@@ -279,15 +279,36 @@ LIBLOG_ABI_PRIVATE ssize_t __android_log_pmsg_file_write( | |||
279 | vec[2].iov_base = (unsigned char *)buf; | 279 | vec[2].iov_base = (unsigned char *)buf; |
280 | vec[2].iov_len = transfer; | 280 | vec[2].iov_len = transfer; |
281 | 281 | ||
282 | if (atomic_load(&pmsgLoggerWrite.context.fd) < 0) { | ||
283 | if (!weOpened) { /* Impossible for weOpened = true here */ | ||
284 | __android_log_lock(); | ||
285 | } | ||
286 | weOpened = atomic_load(&pmsgLoggerWrite.context.fd) < 0; | ||
287 | if (!weOpened) { | ||
288 | __android_log_unlock(); | ||
289 | } else if (pmsgOpen() < 0) { | ||
290 | __android_log_unlock(); | ||
291 | return -EBADF; | ||
292 | } | ||
293 | } | ||
294 | |||
282 | ret = pmsgWrite(logId, &ts, vec, sizeof(vec) / sizeof(vec[0])); | 295 | ret = pmsgWrite(logId, &ts, vec, sizeof(vec) / sizeof(vec[0])); |
283 | 296 | ||
284 | if (ret <= 0) { | 297 | if (ret <= 0) { |
298 | if (weOpened) { | ||
299 | pmsgClose(); | ||
300 | __android_log_unlock(); | ||
301 | } | ||
285 | free(cp); | 302 | free(cp); |
286 | return ret; | 303 | return ret ? ret : (len - length); |
287 | } | 304 | } |
288 | length -= transfer; | 305 | length -= transfer; |
289 | buf += transfer; | 306 | buf += transfer; |
290 | } | 307 | } |
308 | if (weOpened) { | ||
309 | pmsgClose(); | ||
310 | __android_log_unlock(); | ||
311 | } | ||
291 | free(cp); | 312 | free(cp); |
292 | return len; | 313 | return len; |
293 | } | 314 | } |