blob: 563cb3f9b804fc7ebf60c6bb52b3f317bd28ed25 [file] [log] [blame]
Mark Salyzyn71002882016-03-08 16:18:26 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <errno.h>
18#include <fcntl.h>
19#include <pthread.h>
20#if !defined(__MINGW32__)
21#include <pwd.h>
22#endif
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080023#include <log/uio.h>
Mark Salyzyn71002882016-03-08 16:18:26 -080024#include <sched.h>
25#include <stdlib.h>
26#include <string.h>
27#include <sys/types.h>
Mark Salyzyn71002882016-03-08 16:18:26 -080028
29#include <cutils/list.h> /* template, no library dependency */
Mark Salyzyn81321a72017-03-09 07:28:29 -080030#include <log/log_transport.h>
Mark Salyzyn71002882016-03-08 16:18:26 -080031#include <private/android_filesystem_config.h>
32#include <private/android_logger.h>
33#include <system/thread_defs.h>
34
35#include "config_read.h"
36#include "config_write.h"
37#include "log_portability.h"
38#include "logger.h"
39
40static const char baseServiceName[] = "android.logd";
41
42static int writeToLocalInit();
43static int writeToLocalAvailable(log_id_t logId);
44static void writeToLocalReset();
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080045static int writeToLocalWrite(log_id_t logId, struct timespec* ts,
46 struct iovec* vec, size_t nr);
Mark Salyzyn71002882016-03-08 16:18:26 -080047
48LIBLOG_HIDDEN struct android_log_transport_write localLoggerWrite = {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080049 .node = { &localLoggerWrite.node, &localLoggerWrite.node },
Mark Salyzyn04bbc8e2017-03-08 15:03:20 -080050 .context.priv = NULL,
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080051 .name = "local",
52 .available = writeToLocalAvailable,
53 .open = writeToLocalInit,
54 .close = writeToLocalReset,
55 .write = writeToLocalWrite,
Mark Salyzyn71002882016-03-08 16:18:26 -080056};
57
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080058static int writeToLocalVersion(struct android_log_logger* logger,
59 struct android_log_transport_context* transp);
60static int writeToLocalRead(struct android_log_logger_list* logger_list,
61 struct android_log_transport_context* transp,
62 struct log_msg* log_msg);
63static int writeToLocalPoll(struct android_log_logger_list* logger_list,
64 struct android_log_transport_context* transp);
65static void writeToLocalClose(struct android_log_logger_list* logger_list,
66 struct android_log_transport_context* transp);
67static int writeToLocalClear(struct android_log_logger* logger,
68 struct android_log_transport_context* transp);
69static ssize_t writeToLocalGetSize(struct android_log_logger* logger,
70 struct android_log_transport_context* transp);
Mark Salyzyn71002882016-03-08 16:18:26 -080071static ssize_t writeToLocalSetSize(
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080072 struct android_log_logger* logger,
73 struct android_log_transport_context* transp __unused, size_t size);
Mark Salyzyn71002882016-03-08 16:18:26 -080074static ssize_t writeToLocalGetReadbleSize(
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080075 struct android_log_logger* logger,
76 struct android_log_transport_context* transp);
Mark Salyzyn71002882016-03-08 16:18:26 -080077
78struct android_log_transport_read localLoggerRead = {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -080079 .node = { &localLoggerRead.node, &localLoggerRead.node },
80 .name = "local",
81 .available = writeToLocalAvailable,
82 .version = writeToLocalVersion,
83 .read = writeToLocalRead,
84 .poll = writeToLocalPoll,
85 .close = writeToLocalClose,
86 .clear = writeToLocalClear,
87 .getSize = writeToLocalGetSize,
88 .setSize = writeToLocalSetSize,
89 .getReadableSize = writeToLocalGetReadbleSize,
90 .getPrune = NULL,
91 .setPrune = NULL,
92 .getStats = NULL,
Mark Salyzyn71002882016-03-08 16:18:26 -080093};
94
95struct LogBufferElement {
96 struct listnode node;
97 log_id_t logId;
98 pid_t tid;
99 log_time timestamp;
100 unsigned short len;
101 char msg[];
102};
103
104static const size_t MAX_SIZE_DEFAULT = 32768;
105
106/*
107 * Number of log buffers we support with the following assumption:
108 * . . .
109 * LOG_ID_SECURITY = 5, // security logs go to the system logs only
110 * LOG_ID_KERNEL = 6, // place last, third-parties can not use it
111 * LOG_ID_MAX
112 * } log_id_t;
113 *
114 * Confirm the following should <log/log_id.h> be adjusted in the future.
115 */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800116#define NUMBER_OF_LOG_BUFFERS \
117 ((LOG_ID_SECURITY == (LOG_ID_MAX - 2)) ? LOG_ID_SECURITY : LOG_ID_KERNEL)
118#define BLOCK_LOG_BUFFERS(id) \
119 (((id) == LOG_ID_SECURITY) || ((id) == LOG_ID_KERNEL))
Mark Salyzyn71002882016-03-08 16:18:26 -0800120
121static struct LogBuffer {
122 struct listnode head;
123 pthread_rwlock_t listLock;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800124 char* serviceName; /* Also indicates ready by having a value */
Mark Salyzyn71002882016-03-08 16:18:26 -0800125 /* Order and proximity important for memset */
126 size_t number[NUMBER_OF_LOG_BUFFERS]; /* clear memset */
127 size_t size[NUMBER_OF_LOG_BUFFERS]; /* clear memset */
128 size_t totalSize[NUMBER_OF_LOG_BUFFERS]; /* init memset */
129 size_t maxSize[NUMBER_OF_LOG_BUFFERS]; /* init MAX_SIZE_DEFAULT */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800130 struct listnode* last[NUMBER_OF_LOG_BUFFERS]; /* init &head */
Mark Salyzyn71002882016-03-08 16:18:26 -0800131} logbuf = {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800132 .head = { &logbuf.head, &logbuf.head }, .listLock = PTHREAD_RWLOCK_INITIALIZER,
Mark Salyzyn71002882016-03-08 16:18:26 -0800133};
134
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800135static void LogBufferInit(struct LogBuffer* log) {
Mark Salyzyn71002882016-03-08 16:18:26 -0800136 size_t i;
137
138 pthread_rwlock_wrlock(&log->listLock);
139 list_init(&log->head);
140 memset(log->number, 0,
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800141 sizeof(log->number) + sizeof(log->size) + sizeof(log->totalSize));
Mark Salyzyn71002882016-03-08 16:18:26 -0800142 for (i = 0; i < NUMBER_OF_LOG_BUFFERS; ++i) {
143 log->maxSize[i] = MAX_SIZE_DEFAULT;
144 log->last[i] = &log->head;
145 }
146#ifdef __BIONIC__
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800147 asprintf(&log->serviceName, "%s@%d:%d", baseServiceName, __android_log_uid(),
148 getpid());
Mark Salyzyn71002882016-03-08 16:18:26 -0800149#else
150 char buffer[sizeof(baseServiceName) + 1 + 5 + 1 + 5 + 8];
151 snprintf(buffer, sizeof(buffer), "%s@%d:%d", baseServiceName,
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800152 __android_log_uid(), getpid());
Mark Salyzyn71002882016-03-08 16:18:26 -0800153 log->serviceName = strdup(buffer);
154#endif
155 pthread_rwlock_unlock(&log->listLock);
156}
157
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800158static void LogBufferClear(struct LogBuffer* log) {
Mark Salyzyn71002882016-03-08 16:18:26 -0800159 size_t i;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800160 struct listnode* node;
Mark Salyzyn71002882016-03-08 16:18:26 -0800161
162 pthread_rwlock_wrlock(&log->listLock);
163 memset(log->number, 0, sizeof(log->number) + sizeof(log->size));
164 for (i = 0; i < NUMBER_OF_LOG_BUFFERS; ++i) {
165 log->last[i] = &log->head;
166 }
167 while ((node = list_head(&log->head)) != &log->head) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800168 struct LogBufferElement* element;
Mark Salyzyn71002882016-03-08 16:18:26 -0800169
170 element = node_to_item(node, struct LogBufferElement, node);
171 list_remove(node);
172 free(element);
173 }
174 pthread_rwlock_unlock(&log->listLock);
175}
176
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800177static inline void LogBufferFree(struct LogBuffer* log) {
Mark Salyzyn71002882016-03-08 16:18:26 -0800178 pthread_rwlock_wrlock(&log->listLock);
179 free(log->serviceName);
180 log->serviceName = NULL;
181 pthread_rwlock_unlock(&log->listLock);
182 LogBufferClear(log);
183}
184
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800185static int LogBufferLog(struct LogBuffer* log,
186 struct LogBufferElement* element) {
Mark Salyzyn71002882016-03-08 16:18:26 -0800187 log_id_t logId = element->logId;
188
189 pthread_rwlock_wrlock(&log->listLock);
190 log->number[logId]++;
191 log->size[logId] += element->len;
192 log->totalSize[logId] += element->len;
193 /* prune entry(s) until enough space is available */
194 if (log->last[logId] == &log->head) {
195 log->last[logId] = list_tail(&log->head);
196 }
197 while (log->size[logId] > log->maxSize[logId]) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800198 struct listnode* node = log->last[logId];
199 struct LogBufferElement* e;
200 struct android_log_logger_list* logger_list;
Mark Salyzyn71002882016-03-08 16:18:26 -0800201
202 e = node_to_item(node, struct LogBufferElement, node);
203 log->number[logId]--;
204 log->size[logId] -= e->len;
205 logger_list_rdlock();
206 logger_list_for_each(logger_list) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800207 struct android_log_transport_context* transp;
Mark Salyzyn71002882016-03-08 16:18:26 -0800208
209 transport_context_for_each(transp, logger_list) {
210 if ((transp->transport == &localLoggerRead) &&
211 (transp->context.node == node)) {
212 if (node == &log->head) {
213 transp->context.node = &log->head;
214 } else {
215 transp->context.node = node->next;
216 }
217 }
218 }
219 }
220 logger_list_unlock();
221 if (node != &log->head) {
222 log->last[logId] = node->prev;
223 }
224 list_remove(node);
Ting-Yuan Huang249bd052017-08-15 17:01:33 -0700225 LOG_ALWAYS_FATAL_IF(node == log->last[logId], "corrupted list");
Mark Salyzyn71002882016-03-08 16:18:26 -0800226 free(e);
227 }
228 /* add entry to list */
229 list_add_head(&log->head, &element->node);
230 /* ToDo: wake up all readers */
231 pthread_rwlock_unlock(&log->listLock);
232
233 return element->len;
234}
235
236/*
237 * return zero if permitted to log directly to logd,
238 * return 1 if binder server started and
239 * return negative error number if failed to start binder server.
240 */
241static int writeToLocalInit() {
242 pthread_attr_t attr;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800243 struct LogBuffer* log;
Mark Salyzyn71002882016-03-08 16:18:26 -0800244
245 if (writeToLocalAvailable(LOG_ID_MAIN) < 0) {
246 return -EPERM;
247 }
248
249 log = &logbuf;
250 if (!log->serviceName) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800251 LogBufferInit(log);
Mark Salyzyn71002882016-03-08 16:18:26 -0800252 }
253
254 if (!log->serviceName) {
255 LogBufferFree(log);
256 return -ENOMEM;
257 }
258
259 return EPERM; /* successful local-only logging */
260}
261
262static void writeToLocalReset() {
263 LogBufferFree(&logbuf);
264}
265
266static int writeToLocalAvailable(log_id_t logId) {
267#if !defined(__MINGW32__)
268 uid_t uid;
269#endif
270
271 if ((logId >= NUMBER_OF_LOG_BUFFERS) || BLOCK_LOG_BUFFERS(logId)) {
272 return -EINVAL;
273 }
274
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800275/* Android hard coded permitted, system goes to logd */
Mark Salyzyn71002882016-03-08 16:18:26 -0800276#if !defined(__MINGW32__)
Mark Salyzyn81321a72017-03-09 07:28:29 -0800277 if (__android_log_transport == LOGGER_DEFAULT) {
Mark Salyzyn71002882016-03-08 16:18:26 -0800278 uid = __android_log_uid();
279 if ((uid < AID_APP) && (getpwuid(uid) != NULL)) {
280 return -EPERM;
281 }
282 }
283#endif
284
285 /* ToDo: Ask package manager for LOGD permissions */
286 /* Assume we do _not_ have permissions to go to LOGD, so must go local */
287 return 0;
288}
289
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800290static int writeToLocalWrite(log_id_t logId, struct timespec* ts,
291 struct iovec* vec, size_t nr) {
Mark Salyzyn71002882016-03-08 16:18:26 -0800292 size_t len, i;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800293 struct LogBufferElement* element;
Mark Salyzyn71002882016-03-08 16:18:26 -0800294
295 if ((logId >= NUMBER_OF_LOG_BUFFERS) || BLOCK_LOG_BUFFERS(logId)) {
296 return -EINVAL;
297 }
298
299 len = 0;
300 for (i = 0; i < nr; ++i) {
301 len += vec[i].iov_len;
302 }
303
304 if (len > LOGGER_ENTRY_MAX_PAYLOAD) {
305 len = LOGGER_ENTRY_MAX_PAYLOAD;
306 }
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800307 element = (struct LogBufferElement*)calloc(
308 1, sizeof(struct LogBufferElement) + len + 1);
Mark Salyzyn71002882016-03-08 16:18:26 -0800309 if (!element) {
310 return errno ? -errno : -ENOMEM;
311 }
312 element->timestamp.tv_sec = ts->tv_sec;
313 element->timestamp.tv_nsec = ts->tv_nsec;
314#ifdef __BIONIC__
315 element->tid = gettid();
316#else
317 element->tid = getpid();
318#endif
319 element->logId = logId;
320 element->len = len;
321
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800322 char* cp = element->msg;
Mark Salyzyn71002882016-03-08 16:18:26 -0800323 for (i = 0; i < nr; ++i) {
324 size_t iov_len = vec[i].iov_len;
325 if (iov_len > len) {
326 iov_len = len;
327 }
328 memcpy(cp, vec[i].iov_base, iov_len);
329 len -= iov_len;
330 if (len == 0) {
331 break;
332 }
333 cp += iov_len;
334 }
335
336 return LogBufferLog(&logbuf, element);
337}
338
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800339static int writeToLocalVersion(struct android_log_logger* logger __unused,
340 struct android_log_transport_context* transp
341 __unused) {
Mark Salyzyn71002882016-03-08 16:18:26 -0800342 return 3;
343}
344
345/* within reader lock, serviceName already validated */
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800346static struct listnode* writeToLocalNode(
347 struct android_log_logger_list* logger_list,
348 struct android_log_transport_context* transp) {
349 struct listnode* node;
Mark Salyzyn71002882016-03-08 16:18:26 -0800350 unsigned logMask;
351 unsigned int tail;
352
353 node = transp->context.node;
354 if (node) {
355 return node;
356 }
357
358 if (!logger_list->tail) {
359 return transp->context.node = &logbuf.head;
360 }
361
362 logMask = transp->logMask;
363 tail = logger_list->tail;
364
365 for (node = list_head(&logbuf.head); node != &logbuf.head; node = node->next) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800366 struct LogBufferElement* element;
Mark Salyzyn71002882016-03-08 16:18:26 -0800367 log_id_t logId;
368
369 element = node_to_item(node, struct LogBufferElement, node);
370 logId = element->logId;
371
372 if ((logMask & (1 << logId)) && !--tail) {
373 node = node->next;
374 break;
375 }
376 }
377 return transp->context.node = node;
378}
379
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800380static int writeToLocalRead(struct android_log_logger_list* logger_list,
381 struct android_log_transport_context* transp,
382 struct log_msg* log_msg) {
Mark Salyzyn71002882016-03-08 16:18:26 -0800383 int ret;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800384 struct listnode* node;
Mark Salyzyn71002882016-03-08 16:18:26 -0800385 unsigned logMask;
386
387 pthread_rwlock_rdlock(&logbuf.listLock);
388 if (!logbuf.serviceName) {
389 pthread_rwlock_unlock(&logbuf.listLock);
390 return (logger_list->mode & ANDROID_LOG_NONBLOCK) ? -ENODEV : 0;
391 }
392
393 logMask = transp->logMask;
394
395 node = writeToLocalNode(logger_list, transp);
396
397 ret = 0;
398
399 while (node != list_head(&logbuf.head)) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800400 struct LogBufferElement* element;
Mark Salyzyn71002882016-03-08 16:18:26 -0800401 log_id_t logId;
402
403 node = node->prev;
404 element = node_to_item(node, struct LogBufferElement, node);
405 logId = element->logId;
406
407 if (logMask & (1 << logId)) {
408 ret = log_msg->entry_v3.len = element->len;
409 log_msg->entry_v3.hdr_size = sizeof(log_msg->entry_v3);
410 log_msg->entry_v3.pid = getpid();
411 log_msg->entry_v3.tid = element->tid;
412 log_msg->entry_v3.sec = element->timestamp.tv_sec;
413 log_msg->entry_v3.nsec = element->timestamp.tv_nsec;
414 log_msg->entry_v3.lid = logId;
415 memcpy(log_msg->entry_v3.msg, element->msg, ret);
416 ret += log_msg->entry_v3.hdr_size;
417 break;
418 }
419 }
420
421 transp->context.node = node;
422
423 /* ToDo: if blocking, and no entry, put reader to sleep */
424 pthread_rwlock_unlock(&logbuf.listLock);
425 return ret;
426}
427
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800428static int writeToLocalPoll(struct android_log_logger_list* logger_list,
429 struct android_log_transport_context* transp) {
Mark Salyzyn71002882016-03-08 16:18:26 -0800430 int ret = (logger_list->mode & ANDROID_LOG_NONBLOCK) ? -ENODEV : 0;
431
432 pthread_rwlock_rdlock(&logbuf.listLock);
433
434 if (logbuf.serviceName) {
435 unsigned logMask = transp->logMask;
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800436 struct listnode* node = writeToLocalNode(logger_list, transp);
Mark Salyzyn71002882016-03-08 16:18:26 -0800437
438 ret = (node != list_head(&logbuf.head));
439 if (ret) {
440 do {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800441 ret = !!(logMask &
442 (1 << (node_to_item(node->prev, struct LogBufferElement, node))
443 ->logId));
Mark Salyzyn71002882016-03-08 16:18:26 -0800444 } while (!ret && ((node = node->prev) != list_head(&logbuf.head)));
445 }
446
447 transp->context.node = node;
448 }
449
450 pthread_rwlock_unlock(&logbuf.listLock);
451
452 return ret;
453}
454
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800455static void writeToLocalClose(struct android_log_logger_list* logger_list
456 __unused,
457 struct android_log_transport_context* transp) {
Mark Salyzyn71002882016-03-08 16:18:26 -0800458 pthread_rwlock_wrlock(&logbuf.listLock);
459 transp->context.node = list_head(&logbuf.head);
460 pthread_rwlock_unlock(&logbuf.listLock);
461}
462
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800463static int writeToLocalClear(struct android_log_logger* logger,
464 struct android_log_transport_context* unused
465 __unused) {
Mark Salyzyn71002882016-03-08 16:18:26 -0800466 log_id_t logId = logger->logId;
467 struct listnode *node, *n;
468
469 if ((logId >= NUMBER_OF_LOG_BUFFERS) || BLOCK_LOG_BUFFERS(logId)) {
470 return -EINVAL;
471 }
472
473 pthread_rwlock_wrlock(&logbuf.listLock);
474 logbuf.number[logId] = 0;
475 logbuf.last[logId] = &logbuf.head;
476 list_for_each_safe(node, n, &logbuf.head) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800477 struct LogBufferElement* element;
Mark Salyzyn71002882016-03-08 16:18:26 -0800478 element = node_to_item(node, struct LogBufferElement, node);
479
480 if (logId == element->logId) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800481 struct android_log_logger_list* logger_list;
Mark Salyzyn71002882016-03-08 16:18:26 -0800482
483 logger_list_rdlock();
484 logger_list_for_each(logger_list) {
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800485 struct android_log_transport_context* transp;
Mark Salyzyn71002882016-03-08 16:18:26 -0800486
487 transport_context_for_each(transp, logger_list) {
488 if ((transp->transport == &localLoggerRead) &&
489 (transp->context.node == node)) {
490 transp->context.node = node->next;
491 }
492 }
493 }
494 logger_list_unlock();
495 list_remove(node);
496 free(element);
497 }
498 }
499
500 pthread_rwlock_unlock(&logbuf.listLock);
501
502 return 0;
503}
504
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800505static ssize_t writeToLocalGetSize(struct android_log_logger* logger,
506 struct android_log_transport_context* transp
507 __unused) {
Mark Salyzyn71002882016-03-08 16:18:26 -0800508 ssize_t ret = -EINVAL;
509 log_id_t logId = logger->logId;
510
511 if ((logId < NUMBER_OF_LOG_BUFFERS) && !BLOCK_LOG_BUFFERS(logId)) {
512 pthread_rwlock_rdlock(&logbuf.listLock);
513 ret = logbuf.maxSize[logId];
514 pthread_rwlock_unlock(&logbuf.listLock);
515 }
516
517 return ret;
518}
519
520static ssize_t writeToLocalSetSize(
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800521 struct android_log_logger* logger,
522 struct android_log_transport_context* transp __unused, size_t size) {
Mark Salyzyn71002882016-03-08 16:18:26 -0800523 ssize_t ret = -EINVAL;
524
525 if ((size > LOGGER_ENTRY_MAX_LEN) || (size < (4 * 1024 * 1024))) {
526 log_id_t logId = logger->logId;
527 if ((logId < NUMBER_OF_LOG_BUFFERS) || !BLOCK_LOG_BUFFERS(logId)) {
528 pthread_rwlock_wrlock(&logbuf.listLock);
529 ret = logbuf.maxSize[logId] = size;
530 pthread_rwlock_unlock(&logbuf.listLock);
531 }
532 }
533
534 return ret;
535}
536
537static ssize_t writeToLocalGetReadbleSize(
Mark Salyzyn2ed51d72017-03-09 08:09:43 -0800538 struct android_log_logger* logger,
539 struct android_log_transport_context* transp __unused) {
Mark Salyzyn71002882016-03-08 16:18:26 -0800540 ssize_t ret = -EINVAL;
541 log_id_t logId = logger->logId;
542
543 if ((logId < NUMBER_OF_LOG_BUFFERS) && !BLOCK_LOG_BUFFERS(logId)) {
544 pthread_rwlock_rdlock(&logbuf.listLock);
545 ret = logbuf.serviceName ? (ssize_t)logbuf.size[logId] : -EBADF;
546 pthread_rwlock_unlock(&logbuf.listLock);
547 }
548
549 return ret;
550}