1956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn/* 2956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn** Copyright 2014, The Android Open Source Project 3956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn** 4956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn** Licensed under the Apache License, Version 2.0 (the "License"); 5956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn** you may not use this file except in compliance with the License. 6956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn** You may obtain a copy of the License at 7956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn** 8956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn** http://www.apache.org/licenses/LICENSE-2.0 9956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn** 10956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn** Unless required by applicable law or agreed to in writing, software 11956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn** distributed under the License is distributed on an "AS IS" BASIS, 12956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn** See the License for the specific language governing permissions and 14956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn** limitations under the License. 15956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn*/ 16956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn 17956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn#include <ctype.h> 18c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn#include <pthread.h> 19e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn#include <stdbool.h> 20c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn#include <stdlib.h> 21956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn#include <string.h> 22c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ 23c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn#include <sys/_system_properties.h> 24e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn#include <unistd.h> 25956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn 26e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn#include <private/android_logger.h> 27956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn 28018a96d03f0d452bf078084eedcd5693da42308dMark Salyzyn#include "log_portability.h" 29be1d3c21b57d3e67c6a9682f3b2f0838486a3ee8Mark Salyzyn 302d2e0a5c5eb0b0ea2fe1349da50e22228965faf9Mark Salyzynstatic pthread_mutex_t lock_loggable = PTHREAD_MUTEX_INITIALIZER; 312d2e0a5c5eb0b0ea2fe1349da50e22228965faf9Mark Salyzyn 322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic int lock() { 332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* 342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn * If we trigger a signal handler in the middle of locked activity and the 352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn * signal handler logs a message, we could get into a deadlock state. 362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn */ 372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* 382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn * Any contention, and we can turn around and use the non-cached method 392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn * in less time than the system call associated with a mutex to deal with 402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn * the contention. 412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn */ 422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return pthread_mutex_trylock(&lock_loggable); 432d2e0a5c5eb0b0ea2fe1349da50e22228965faf9Mark Salyzyn} 442d2e0a5c5eb0b0ea2fe1349da50e22228965faf9Mark Salyzyn 452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic void unlock() { 462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn pthread_mutex_unlock(&lock_loggable); 472d2e0a5c5eb0b0ea2fe1349da50e22228965faf9Mark Salyzyn} 482d2e0a5c5eb0b0ea2fe1349da50e22228965faf9Mark Salyzyn 49c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzynstruct cache { 502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const prop_info* pinfo; 512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn uint32_t serial; 52e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn}; 53e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 54e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzynstruct cache_char { 552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn struct cache cache; 562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned char c; 57c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn}; 58c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn 592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic int check_cache(struct cache* cache) { 602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return cache->pinfo && __system_property_serial(cache->pinfo) != cache->serial; 61a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn} 62a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn 63ffbd86ff25583e2bdae0b6f958e46e40ad111b3dMark Salyzyn#define BOOLEAN_TRUE 0xFF 64ffbd86ff25583e2bdae0b6f958e46e40ad111b3dMark Salyzyn#define BOOLEAN_FALSE 0xFE 65ffbd86ff25583e2bdae0b6f958e46e40ad111b3dMark Salyzyn 662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic void refresh_cache(struct cache_char* cache, const char* key) { 672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char buf[PROP_VALUE_MAX]; 68956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn 692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!cache->cache.pinfo) { 702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn cache->cache.pinfo = __system_property_find(key); 71e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn if (!cache->cache.pinfo) { 722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return; 732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn cache->cache.serial = __system_property_serial(cache->cache.pinfo); 762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn __system_property_read(cache->cache.pinfo, 0, buf); 772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn switch (buf[0]) { 782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn case 't': 792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn case 'T': 802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn cache->c = strcasecmp(buf + 1, "rue") ? buf[0] : BOOLEAN_TRUE; 812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn break; 822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn case 'f': 832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn case 'F': 842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn cache->c = strcasecmp(buf + 1, "alse") ? buf[0] : BOOLEAN_FALSE; 852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn break; 86ffbd86ff25583e2bdae0b6f958e46e40ad111b3dMark Salyzyn default: 872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn cache->c = buf[0]; 882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 89c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn} 90c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn 912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic int __android_log_level(const char* tag, size_t len, int default_prio) { 922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* sizeof() is used on this array below */ 932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static const char log_namespace[] = "persist.log.tag."; 942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static const size_t base_offset = 8; /* skip "persist." */ 952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* calculate the size of our key temporary buffer */ 962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const size_t taglen = tag ? len : 0; 972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* sizeof(log_namespace) = strlen(log_namespace) + 1 */ 98d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn char key[sizeof(log_namespace) + taglen]; 992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char* kp; 1002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t i; 1012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char c = 0; 1022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* 1032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn * Single layer cache of four properties. Priorities are: 1042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn * log.tag.<tag> 1052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn * persist.log.tag.<tag> 1062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn * log.tag 1072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn * persist.log.tag 1082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn * Where the missing tag matches all tags and becomes the 1092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn * system global default. We do not support ro.log.tag* . 1102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn */ 111d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn static char* last_tag; 112d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn static size_t last_tag_len; 1132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static uint32_t global_serial; 1142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* some compilers erroneously see uninitialized use. !not_locked */ 1152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn uint32_t current_global_serial = 0; 1162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static struct cache_char tag_cache[2]; 1172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static struct cache_char global_cache[2]; 1182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int change_detected; 1192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int global_change_detected; 1202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int not_locked; 1212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 1222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn strcpy(key, log_namespace); 1232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 1242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn global_change_detected = change_detected = not_locked = lock(); 1252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 1262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!not_locked) { 127c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn /* 1282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn * check all known serial numbers to changes. 129c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn */ 1302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) { 1312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (check_cache(&tag_cache[i].cache)) { 1322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn change_detected = 1; 1332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) { 1362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (check_cache(&global_cache[i].cache)) { 1372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn global_change_detected = 1; 1382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 140c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn 1412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn current_global_serial = __system_property_area_serial(); 1422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (current_global_serial != global_serial) { 1432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn change_detected = 1; 1442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn global_change_detected = 1; 1452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 147c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn 1482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (taglen) { 1492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int local_change_detected = change_detected; 150a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn if (!not_locked) { 151d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn if (!last_tag || !last_tag[0] || (last_tag[0] != tag[0]) || 152d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn strncmp(last_tag + 1, tag + 1, last_tag_len - 1)) { 1532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* invalidate log.tag.<tag> cache */ 154a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) { 1552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn tag_cache[i].cache.pinfo = NULL; 1562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn tag_cache[i].c = '\0'; 157a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn } 158d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn if (last_tag) last_tag[0] = '\0'; 1592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn local_change_detected = 1; 1602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 161d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn if (!last_tag || !last_tag[0]) { 162d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn if (!last_tag) { 163d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn last_tag = calloc(1, len + 1); 164d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn last_tag_len = 0; 165d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn if (last_tag) last_tag_len = len + 1; 166d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn } else if (len >= last_tag_len) { 167d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn last_tag = realloc(last_tag, len + 1); 168d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn last_tag_len = 0; 169d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn if (last_tag) last_tag_len = len + 1; 170d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn } 171d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn if (last_tag) { 1722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn strncpy(last_tag, tag, len); 1732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn last_tag[len] = '\0'; 174a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn } 1752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn strncpy(key + sizeof(log_namespace) - 1, tag, len); 1782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn key[sizeof(log_namespace) - 1 + len] = '\0'; 1792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 1802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn kp = key; 1812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn for (i = 0; i < (sizeof(tag_cache) / sizeof(tag_cache[0])); ++i) { 1822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn struct cache_char* cache = &tag_cache[i]; 1832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn struct cache_char temp_cache; 1842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 1852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (not_locked) { 1862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn temp_cache.cache.pinfo = NULL; 1872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn temp_cache.c = '\0'; 1882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn cache = &temp_cache; 1892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (local_change_detected) { 1912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn refresh_cache(cache, kp); 1922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 1942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (cache->c) { 1952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn c = cache->c; 1962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn break; 1972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 198956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn 1992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn kp = key + base_offset; 200c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn } 2012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 202c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn 2032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn switch (toupper(c)) { /* if invalid, resort to global */ 204c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn case 'V': 205c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn case 'D': 206c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn case 'I': 207c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn case 'W': 208c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn case 'E': 209c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn case 'F': /* Not officially supported */ 210c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn case 'A': 211c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn case 'S': 212ffbd86ff25583e2bdae0b6f958e46e40ad111b3dMark Salyzyn case BOOLEAN_FALSE: /* Not officially supported */ 2132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn break; 214c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn default: 2152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* clear '.' after log.tag */ 2162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn key[sizeof(log_namespace) - 2] = '\0'; 2172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 2182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn kp = key; 2192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn for (i = 0; i < (sizeof(global_cache) / sizeof(global_cache[0])); ++i) { 2202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn struct cache_char* cache = &global_cache[i]; 2212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn struct cache_char temp_cache; 2222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 2232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (not_locked) { 2242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn temp_cache = *cache; 2252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (temp_cache.cache.pinfo != cache->cache.pinfo) { /* check atomic */ 2262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn temp_cache.cache.pinfo = NULL; 2272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn temp_cache.c = '\0'; 2282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn cache = &temp_cache; 2302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (global_change_detected) { 2322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn refresh_cache(cache, kp); 2331f028b2fdfd75fb8689e2da78320d178991a4731Mark Salyzyn } 234c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn 2352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (cache->c) { 2362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn c = cache->c; 2372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn break; 2382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 239c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn 2402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn kp = key + base_offset; 2412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn break; 2432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 2452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!not_locked) { 2462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn global_serial = current_global_serial; 2472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unlock(); 2482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 2502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn switch (toupper(c)) { 2512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* clang-format off */ 252c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn case 'V': return ANDROID_LOG_VERBOSE; 253c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn case 'D': return ANDROID_LOG_DEBUG; 254c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn case 'I': return ANDROID_LOG_INFO; 255c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn case 'W': return ANDROID_LOG_WARN; 256c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn case 'E': return ANDROID_LOG_ERROR; 257c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn case 'F': /* FALLTHRU */ /* Not officially supported */ 258c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn case 'A': return ANDROID_LOG_FATAL; 259ffbd86ff25583e2bdae0b6f958e46e40ad111b3dMark Salyzyn case BOOLEAN_FALSE: /* FALLTHRU */ /* Not Officially supported */ 260c158456f50817ac506f4eed780978e63dd222fe4Mark Salyzyn case 'S': return -1; /* ANDROID_LOG_SUPPRESS */ 2612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* clang-format on */ 2622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 2632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return default_prio; 264956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn} 265956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn 2662ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC int __android_log_is_loggable_len(int prio, const char* tag, 2672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn size_t len, 2682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int default_prio) { 2692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int logLevel = __android_log_level(tag, len, default_prio); 2702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return logLevel >= 0 && prio >= logLevel; 271807e40ecc9786755e2f74a7a6a9b20c812588119Mark Salyzyn} 272807e40ecc9786755e2f74a7a6a9b20c812588119Mark Salyzyn 2732ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC int __android_log_is_loggable(int prio, const char* tag, 2742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int default_prio) { 2752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int logLevel = 2762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn __android_log_level(tag, (tag && *tag) ? strlen(tag) : 0, default_prio); 2772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return logLevel >= 0 && prio >= logLevel; 278956870518ee89b5302b8409ac78f287bf091d9edMark Salyzyn} 279500afc75325823c03dbdf6b2d56fd86e29f120f4Mark Salyzyn 280d73be1b96beab812b86f8174e7fc928291f0cb44Steven MorelandLIBLOG_ABI_PUBLIC int __android_log_is_debuggable() { 2812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static uint32_t serial; 2822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static struct cache_char tag_cache; 2832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static const char key[] = "ro.debuggable"; 2842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int ret; 2852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 2862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (tag_cache.c) { /* ro property does not change after set */ 2872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ret = tag_cache.c == '1'; 2882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else if (lock()) { 2892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn struct cache_char temp_cache = { { NULL, -1 }, '\0' }; 2902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn refresh_cache(&temp_cache, key); 2912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ret = temp_cache.c == '1'; 2922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else { 2932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int change_detected = check_cache(&tag_cache.cache); 2942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn uint32_t current_serial = __system_property_area_serial(); 2952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (current_serial != serial) { 2962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn change_detected = 1; 2977ef5249afacffe3901e3a602372c7d34cf655675Mark Salyzyn } 2982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (change_detected) { 2992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn refresh_cache(&tag_cache, key); 3002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn serial = current_serial; 3012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ret = tag_cache.c == '1'; 3032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 3042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unlock(); 3052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3067ef5249afacffe3901e3a602372c7d34cf655675Mark Salyzyn 3072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return ret; 3087ef5249afacffe3901e3a602372c7d34cf655675Mark Salyzyn} 3097ef5249afacffe3901e3a602372c7d34cf655675Mark Salyzyn 3102d2e0a5c5eb0b0ea2fe1349da50e22228965faf9Mark Salyzyn/* 311a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn * For properties that are read often, but generally remain constant. 312a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn * Since a change is rare, we will accept a trylock failure gracefully. 313a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn * Use a separate lock from is_loggable to keep contention down b/25563384. 3142d2e0a5c5eb0b0ea2fe1349da50e22228965faf9Mark Salyzyn */ 315e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzynstruct cache2_char { 3162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn pthread_mutex_t lock; 3172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn uint32_t serial; 3182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* key_persist; 3192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn struct cache_char cache_persist; 3202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* key_ro; 3212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn struct cache_char cache_ro; 3222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned char (*const evaluate)(const struct cache2_char* self); 323a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn}; 3242d2e0a5c5eb0b0ea2fe1349da50e22228965faf9Mark Salyzyn 3252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic inline unsigned char do_cache2_char(struct cache2_char* self) { 3262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn uint32_t current_serial; 3272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int change_detected; 3282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned char c; 3292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 3302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (pthread_mutex_trylock(&self->lock)) { 3312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* We are willing to accept some race in this context */ 3322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return self->evaluate(self); 3332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 3352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn change_detected = check_cache(&self->cache_persist.cache) || 3362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn check_cache(&self->cache_ro.cache); 3372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn current_serial = __system_property_area_serial(); 3382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (current_serial != self->serial) { 3392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn change_detected = 1; 3402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (change_detected) { 3422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn refresh_cache(&self->cache_persist, self->key_persist); 3432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn refresh_cache(&self->cache_ro, self->key_ro); 3442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn self->serial = current_serial; 3452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 3462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn c = self->evaluate(self); 3472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 3482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn pthread_mutex_unlock(&self->lock); 3492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 3502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return c; 351a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn} 352a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn 3532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic unsigned char evaluate_persist_ro(const struct cache2_char* self) { 3542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned char c = self->cache_persist.c; 355a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn 3562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (c) { 3572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return c; 3582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 359a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn 3602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return self->cache_ro.c; 361500afc75325823c03dbdf6b2d56fd86e29f120f4Mark Salyzyn} 362ffbd86ff25583e2bdae0b6f958e46e40ad111b3dMark Salyzyn 363ffbd86ff25583e2bdae0b6f958e46e40ad111b3dMark Salyzyn/* 364a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn * Timestamp state generally remains constant, but can change at any time 365a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn * to handle developer requirements. 366ffbd86ff25583e2bdae0b6f958e46e40ad111b3dMark Salyzyn */ 3672ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC clockid_t android_log_clockid() { 3682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static struct cache2_char clockid = { 3692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn PTHREAD_MUTEX_INITIALIZER, 0, 3702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn "persist.logd.timestamp", { { NULL, -1 }, '\0' }, 3712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn "ro.logd.timestamp", { { NULL, -1 }, '\0' }, 3722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn evaluate_persist_ro 3732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn }; 3742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 3752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return (tolower(do_cache2_char(&clockid)) == 'm') ? CLOCK_MONOTONIC 3762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn : CLOCK_REALTIME; 377a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn} 378a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn 379a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn/* 380a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn * Security state generally remains constant, but the DO must be able 381a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn * to turn off logging should it become spammy after an attack is detected. 382a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn */ 3832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic unsigned char evaluate_security(const struct cache2_char* self) { 3842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned char c = self->cache_ro.c; 385ffbd86ff25583e2bdae0b6f958e46e40ad111b3dMark Salyzyn 3862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return (c != BOOLEAN_FALSE) && c && (self->cache_persist.c == BOOLEAN_TRUE); 387a67d8a53c744b4e873f666541b1854c704994da9Mark Salyzyn} 388ffbd86ff25583e2bdae0b6f958e46e40ad111b3dMark Salyzyn 3892ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PUBLIC int __android_log_security() { 3902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static struct cache2_char security = { 3912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn PTHREAD_MUTEX_INITIALIZER, 0, 3922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn "persist.logd.security", { { NULL, -1 }, BOOLEAN_FALSE }, 3932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn "ro.device_owner", { { NULL, -1 }, BOOLEAN_FALSE }, 3942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn evaluate_security 3952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn }; 3962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 3972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return do_cache2_char(&security); 398e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn} 399e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 400e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn/* 401e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn * Interface that represents the logd buffer size determination so that others 402e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn * need not guess our intentions. 403e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn */ 404e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 405e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn/* Property helper */ 406e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzynstatic bool check_flag(const char* prop, const char* flag) { 4072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* cp = strcasestr(prop, flag); 4082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!cp) { 4092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return false; 4102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* We only will document comma (,) */ 4122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static const char sep[] = ",:;|+ \t\f"; 4132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((cp != prop) && !strchr(sep, cp[-1])) { 4142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return false; 4152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn cp += strlen(flag); 4172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return !*cp || !!strchr(sep, *cp); 418e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn} 419e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 420e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn/* cache structure */ 421e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzynstruct cache_property { 4222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn struct cache cache; 4232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char property[PROP_VALUE_MAX]; 424e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn}; 425e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 4262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic void refresh_cache_property(struct cache_property* cache, 4272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* key) { 4282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!cache->cache.pinfo) { 4292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn cache->cache.pinfo = __system_property_find(key); 430e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn if (!cache->cache.pinfo) { 4312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return; 432e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn } 4332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn cache->cache.serial = __system_property_serial(cache->cache.pinfo); 4352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn __system_property_read(cache->cache.pinfo, 0, cache->property); 436e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn} 437e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 438e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn/* get boolean with the logger twist that supports eng adjustments */ 439e455373b57bc09551eaa2e595bcecbd39acf6a1aMark SalyzynLIBLOG_ABI_PRIVATE bool __android_logger_property_get_bool(const char* key, 4402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int flag) { 4412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn struct cache_property property = { { NULL, -1 }, { 0 } }; 4422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (flag & BOOL_DEFAULT_FLAG_PERSIST) { 443d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn char newkey[strlen("persist.") + strlen(key) + 1]; 4442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn snprintf(newkey, sizeof(newkey), "ro.%s", key); 4452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn refresh_cache_property(&property, newkey); 4462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn property.cache.pinfo = NULL; 4472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn property.cache.serial = -1; 4482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn snprintf(newkey, sizeof(newkey), "persist.%s", key); 4492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn refresh_cache_property(&property, newkey); 4502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn property.cache.pinfo = NULL; 4512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn property.cache.serial = -1; 4522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 4542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn refresh_cache_property(&property, key); 4552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 4562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (check_flag(property.property, "true")) { 4572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return true; 4582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (check_flag(property.property, "false")) { 4602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return false; 4612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4629fcaaba85ddee7ca181901b7409ef3eb2962a7d8Mark Salyzyn if (property.property[0]) { 4639fcaaba85ddee7ca181901b7409ef3eb2962a7d8Mark Salyzyn flag &= ~(BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE); 4649fcaaba85ddee7ca181901b7409ef3eb2962a7d8Mark Salyzyn } 4652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (check_flag(property.property, "eng")) { 4662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn flag |= BOOL_DEFAULT_FLAG_ENG; 4672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* this is really a "not" flag */ 4692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (check_flag(property.property, "svelte")) { 4702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn flag |= BOOL_DEFAULT_FLAG_SVELTE; 4712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 4732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* Sanity Check */ 4742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (flag & (BOOL_DEFAULT_FLAG_SVELTE | BOOL_DEFAULT_FLAG_ENG)) { 4752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn flag &= ~BOOL_DEFAULT_FLAG_TRUE_FALSE; 4762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn flag |= BOOL_DEFAULT_TRUE; 4772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 4792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((flag & BOOL_DEFAULT_FLAG_SVELTE) && 4802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn __android_logger_property_get_bool("ro.config.low_ram", 4812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn BOOL_DEFAULT_FALSE)) { 4822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return false; 4832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((flag & BOOL_DEFAULT_FLAG_ENG) && !__android_log_is_debuggable()) { 4852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return false; 4862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 4872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 4882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return (flag & BOOL_DEFAULT_FLAG_TRUE_FALSE) != BOOL_DEFAULT_FALSE; 489e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn} 490e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 4912ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PRIVATE bool __android_logger_valid_buffer_size(unsigned long value) { 4922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static long pages, pagesize; 4932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned long maximum; 494e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 4952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((value < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < value)) { 4962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return false; 4972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 498e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 4992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!pages) { 5002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn pages = sysconf(_SC_PHYS_PAGES); 5012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (pages < 1) { 5032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return true; 5042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 505e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 5062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!pagesize) { 5072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn pagesize = sysconf(_SC_PAGESIZE); 5082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (pagesize <= 1) { 5092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn pagesize = PAGE_SIZE; 510e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn } 5112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 512e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 5132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* maximum memory impact a somewhat arbitrary ~3% */ 5142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn pages = (pages + 31) / 32; 5152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn maximum = pages * pagesize; 516e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 5172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if ((maximum < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < maximum)) { 5182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return true; 5192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 520e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 5212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return value <= maximum; 522e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn} 523e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 524e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzynstruct cache2_property_size { 5252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn pthread_mutex_t lock; 5262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn uint32_t serial; 5272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* key_persist; 5282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn struct cache_property cache_persist; 5292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const char* key_ro; 5302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn struct cache_property cache_ro; 5312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned long (*const evaluate)(const struct cache2_property_size* self); 532e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn}; 533e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 5342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic inline unsigned long do_cache2_property_size( 5352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn struct cache2_property_size* self) { 5362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn uint32_t current_serial; 5372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn int change_detected; 5382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned long v; 5392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 5402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (pthread_mutex_trylock(&self->lock)) { 5412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* We are willing to accept some race in this context */ 5422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return self->evaluate(self); 5432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 5452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn change_detected = check_cache(&self->cache_persist.cache) || 5462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn check_cache(&self->cache_ro.cache); 5472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn current_serial = __system_property_area_serial(); 5482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (current_serial != self->serial) { 5492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn change_detected = 1; 5502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (change_detected) { 5522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn refresh_cache_property(&self->cache_persist, self->key_persist); 5532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn refresh_cache_property(&self->cache_ro, self->key_ro); 5542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn self->serial = current_serial; 5552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn v = self->evaluate(self); 5572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 5582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn pthread_mutex_unlock(&self->lock); 5592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 5602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return v; 561e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn} 562e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 5632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic unsigned long property_get_size_from_cache( 5642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const struct cache_property* cache) { 5652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char* cp; 5662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned long value = strtoul(cache->property, &cp, 10); 567e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 5682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn switch (*cp) { 569e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn case 'm': 570e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn case 'M': 5712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn value *= 1024; 572e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn /* FALLTHRU */ 573e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn case 'k': 574e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn case 'K': 5752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn value *= 1024; 576e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn /* FALLTHRU */ 577e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn case '\0': 5782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn break; 579e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 580e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn default: 5812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn value = 0; 5822ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 583e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 5842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!__android_logger_valid_buffer_size(value)) { 5852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn value = 0; 5862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 587e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 5882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return value; 589e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn} 590e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 5912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzynstatic unsigned long evaluate_property_get_size( 5922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn const struct cache2_property_size* self) { 5932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned long size = property_get_size_from_cache(&self->cache_persist); 5942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (size) { 5952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return size; 5962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 5972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return property_get_size_from_cache(&self->cache_ro); 598e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn} 599e455373b57bc09551eaa2e595bcecbd39acf6a1aMark Salyzyn 6002ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PRIVATE unsigned long __android_logger_get_buffer_size(log_id_t logId) { 6012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static const char global_tunable[] = "persist.logd.size"; /* Settings App */ 6022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static const char global_default[] = "ro.logd.size"; /* BoardConfig.mk */ 6032ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn static struct cache2_property_size global = { 6042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* clang-format off */ 6052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn PTHREAD_MUTEX_INITIALIZER, 0, 6062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn global_tunable, { { NULL, -1 }, {} }, 6072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn global_default, { { NULL, -1 }, {} }, 6082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn evaluate_property_get_size 6092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* clang-format on */ 6102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn }; 611d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn char key_persist[strlen(global_tunable) + strlen(".security") + 1]; 612d24dc95e871e8d201e894b36f4cd102af226287eMark Salyzyn char key_ro[strlen(global_default) + strlen(".security") + 1]; 6132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn struct cache2_property_size local = { 6142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* clang-format off */ 6152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn PTHREAD_MUTEX_INITIALIZER, 0, 6162ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn key_persist, { { NULL, -1 }, {} }, 6172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn key_ro, { { NULL, -1 }, {} }, 6182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn evaluate_property_get_size 6192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn /* clang-format on */ 6202ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn }; 6212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned long property_size, default_size; 6222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 6232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn default_size = do_cache2_property_size(&global); 6242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!default_size) { 6252ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn default_size = __android_logger_property_get_bool("ro.config.low_ram", 6262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn BOOL_DEFAULT_FALSE) 6272ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ? LOG_BUFFER_MIN_SIZE /* 64K */ 6282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn : LOG_BUFFER_SIZE; /* 256K */ 6292ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 6302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 6312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn snprintf(key_persist, sizeof(key_persist), "%s.%s", global_tunable, 6322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android_log_id_to_name(logId)); 6332ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn snprintf(key_ro, sizeof(key_ro), "%s.%s", global_default, 6342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn android_log_id_to_name(logId)); 6352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn property_size = do_cache2_property_size(&local); 6362ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 6372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!property_size) { 6382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn property_size = default_size; 6392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 6402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 6412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!property_size) { 6422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn property_size = LOG_BUFFER_SIZE; 6432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 6442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 6452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return property_size; 646ffbd86ff25583e2bdae0b6f958e46e40ad111b3dMark Salyzyn} 647