summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Salyzyn2015-02-12 17:14:26 -0600
committerMark Salyzyn2015-03-04 15:21:41 -0600
commitd45d36e011bf2a42bffac07424d3990022287f3c (patch)
tree45ca563150afa1e1d44b6fed19d164ab67db9a9f /liblog/logd_write.c
parent29eb57066c37bf667a56bb4a7143b50664d5eb44 (diff)
downloadplatform-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.c28
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