diff options
author | Mark Salyzyn | 2015-02-12 17:14:26 -0600 |
---|---|---|
committer | Mark Salyzyn | 2015-03-04 15:21:41 -0600 |
commit | d45d36e011bf2a42bffac07424d3990022287f3c (patch) | |
tree | 45ca563150afa1e1d44b6fed19d164ab67db9a9f /liblog/logd_write.c | |
parent | 29eb57066c37bf667a56bb4a7143b50664d5eb44 (diff) | |
download | platform-system-core-d45d36e011bf2a42bffac07424d3990022287f3c.tar.gz platform-system-core-d45d36e011bf2a42bffac07424d3990022287f3c.tar.xz platform-system-core-d45d36e011bf2a42bffac07424d3990022287f3c.zip |
liblog: Instrument logging of logd write drops
- If logger system is prostrated, send an event message with the
liblog tag from the associated UID and PID with a count of
dropped messages once logging is resumed.
- Added to the README a description of the error return values.
- Describe in the README the appropriate mitigations for dropped
messages.
- If the caller sees this message, then
/proc/sys/net/unix/max_dgram_qlen is likely too small
Change-Id: Iaf387b9e5e1b6aa93bebc7481f9e8353732e3229
Diffstat (limited to 'liblog/logd_write.c')
-rw-r--r-- | liblog/logd_write.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/liblog/logd_write.c b/liblog/logd_write.c index 0208c7389..c8a6162b7 100644 --- a/liblog/logd_write.c +++ b/liblog/logd_write.c | |||
@@ -13,12 +13,14 @@ | |||
13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | #include <endian.h> | ||
16 | #include <errno.h> | 17 | #include <errno.h> |
17 | #include <fcntl.h> | 18 | #include <fcntl.h> |
18 | #if !defined(_WIN32) | 19 | #if !defined(_WIN32) |
19 | #include <pthread.h> | 20 | #include <pthread.h> |
20 | #endif | 21 | #endif |
21 | #include <stdarg.h> | 22 | #include <stdarg.h> |
23 | #include <stdatomic.h> | ||
22 | #include <stdio.h> | 24 | #include <stdio.h> |
23 | #include <stdlib.h> | 25 | #include <stdlib.h> |
24 | #include <string.h> | 26 | #include <string.h> |
@@ -172,6 +174,7 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr) | |||
172 | size_t i, payload_size; | 174 | size_t i, payload_size; |
173 | static uid_t last_uid = AID_ROOT; /* logd *always* starts up as AID_ROOT */ | 175 | static uid_t last_uid = AID_ROOT; /* logd *always* starts up as AID_ROOT */ |
174 | static pid_t last_pid = (pid_t) -1; | 176 | static pid_t last_pid = (pid_t) -1; |
177 | static atomic_int_fast32_t dropped; | ||
175 | 178 | ||
176 | if (last_uid == AID_ROOT) { /* have we called to get the UID yet? */ | 179 | if (last_uid == AID_ROOT) { /* have we called to get the UID yet? */ |
177 | last_uid = getuid(); | 180 | last_uid = getuid(); |
@@ -206,7 +209,6 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr) | |||
206 | pmsg_header.uid = last_uid; | 209 | pmsg_header.uid = last_uid; |
207 | pmsg_header.pid = last_pid; | 210 | pmsg_header.pid = last_pid; |
208 | 211 | ||
209 | header.id = log_id; | ||
210 | header.tid = gettid(); | 212 | header.tid = gettid(); |
211 | header.realtime.tv_sec = ts.tv_sec; | 213 | header.realtime.tv_sec = ts.tv_sec; |
212 | header.realtime.tv_nsec = ts.tv_nsec; | 214 | header.realtime.tv_nsec = ts.tv_nsec; |
@@ -216,6 +218,28 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr) | |||
216 | newVec[1].iov_base = (unsigned char *) &header; | 218 | newVec[1].iov_base = (unsigned char *) &header; |
217 | newVec[1].iov_len = sizeof(header); | 219 | newVec[1].iov_len = sizeof(header); |
218 | 220 | ||
221 | if (logd_fd > 0) { | ||
222 | int32_t snapshot = atomic_exchange_explicit(&dropped, 0, memory_order_relaxed); | ||
223 | if (snapshot) { | ||
224 | android_log_event_int_t buffer; | ||
225 | |||
226 | header.id = LOG_ID_EVENTS; | ||
227 | buffer.header.tag = htole32(LIBLOG_LOG_TAG); | ||
228 | buffer.payload.type = EVENT_TYPE_INT; | ||
229 | buffer.payload.data = htole32(snapshot); | ||
230 | |||
231 | newVec[2].iov_base = &buffer; | ||
232 | newVec[2].iov_len = sizeof(buffer); | ||
233 | |||
234 | ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, 2)); | ||
235 | if (ret != (ssize_t)(sizeof(header) + sizeof(buffer))) { | ||
236 | atomic_fetch_add_explicit(&dropped, snapshot, memory_order_relaxed); | ||
237 | } | ||
238 | } | ||
239 | } | ||
240 | |||
241 | header.id = log_id; | ||
242 | |||
219 | for (payload_size = 0, i = header_length; i < nr + header_length; i++) { | 243 | for (payload_size = 0, i = header_length; i < nr + header_length; i++) { |
220 | newVec[i].iov_base = vec[i - header_length].iov_base; | 244 | newVec[i].iov_base = vec[i - header_length].iov_base; |
221 | payload_size += newVec[i].iov_len = vec[i - header_length].iov_len; | 245 | payload_size += newVec[i].iov_len = vec[i - header_length].iov_len; |
@@ -281,6 +305,8 @@ static int __write_to_log_daemon(log_id_t log_id, struct iovec *vec, size_t nr) | |||
281 | 305 | ||
282 | if (ret > (ssize_t)sizeof(header)) { | 306 | if (ret > (ssize_t)sizeof(header)) { |
283 | ret -= sizeof(header); | 307 | ret -= sizeof(header); |
308 | } else if (ret == -EAGAIN) { | ||
309 | atomic_fetch_add_explicit(&dropped, 1, memory_order_relaxed); | ||
284 | } | 310 | } |
285 | #endif | 311 | #endif |
286 | 312 | ||