diff options
-rw-r--r-- | adf/libadf/adf.c | 2 | ||||
-rwxr-xr-x | debuggerd/tombstone.cpp | 36 | ||||
-rw-r--r-- | init/init_parser.c | 2 | ||||
-rw-r--r-- | init/property_service.c | 1 | ||||
-rw-r--r-- | logcat/logcat.cpp | 15 | ||||
-rw-r--r-- | logd/Android.mk | 5 | ||||
-rw-r--r-- | logd/LogAudit.cpp | 46 | ||||
-rw-r--r-- | logd/LogBuffer.cpp | 69 | ||||
-rw-r--r-- | logd/LogCommand.cpp | 2 | ||||
-rw-r--r-- | logd/event.logtags | 36 | ||||
-rw-r--r-- | rootdir/init.zygote32_64.rc | 2 | ||||
-rw-r--r-- | toolbox/start.c | 1 | ||||
-rw-r--r-- | toolbox/stop.c | 1 |
13 files changed, 157 insertions, 61 deletions
diff --git a/adf/libadf/adf.c b/adf/libadf/adf.c index 871629e..1d19152 100644 --- a/adf/libadf/adf.c +++ b/adf/libadf/adf.c @@ -768,7 +768,7 @@ int adf_find_simple_post_configuration(struct adf_device *dev, const __u32 *formats, size_t n_formats, adf_id_t *interface, adf_id_t *overlay_engine) { - adf_id_t *intfs; + adf_id_t *intfs = NULL; ssize_t n_intfs = adf_interfaces(dev, &intfs); if (n_intfs < 0) diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp index d0cefc7..6d51171 100755 --- a/debuggerd/tombstone.cpp +++ b/debuggerd/tombstone.cpp @@ -31,9 +31,10 @@ #include <private/android_filesystem_config.h> +#include <cutils/properties.h> #include <log/log.h> #include <log/logger.h> -#include <cutils/properties.h> +#include <log/logprint.h> #include <backtrace/Backtrace.h> #include <backtrace/BacktraceMap.h> @@ -459,6 +460,8 @@ static bool dump_sibling_thread_report( // that don't match the specified pid, and writes them to the tombstone file. // // If "tail" is set, we only print the last few lines. +static EventTagMap* g_eventTagMap = NULL; + static void dump_log_file(log_t* log, pid_t pid, const char* filename, unsigned int tail) { bool first = true; @@ -521,7 +524,28 @@ static void dump_log_file(log_t* log, pid_t pid, const char* filename, if (!hdr_size) { hdr_size = sizeof(log_entry.entry_v1); } - char* msg = (char *)log_entry.buf + hdr_size; + char* msg = reinterpret_cast<char*>(log_entry.buf) + hdr_size; + + char timeBuf[32]; + time_t sec = static_cast<time_t>(entry->sec); + struct tm tmBuf; + struct tm* ptm; + ptm = localtime_r(&sec, &tmBuf); + strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm); + + if (log_entry.id() == LOG_ID_EVENTS) { + if (!g_eventTagMap) { + g_eventTagMap = android_openEventTagMap(EVENT_TAG_MAP_FILE); + } + AndroidLogEntry e; + char buf[512]; + android_log_processBinaryLogBuffer(entry, &e, g_eventTagMap, buf, sizeof(buf)); + _LOG(log, 0, "%s.%03d %5d %5d %c %-8s: %s\n", + timeBuf, entry->nsec / 1000000, entry->pid, entry->tid, + 'I', e.tag, e.message); + continue; + } + unsigned char prio = msg[0]; char* tag = msg + 1; msg = tag + strlen(tag) + 1; @@ -534,13 +558,6 @@ static void dump_log_file(log_t* log, pid_t pid, const char* filename, char prioChar = (prio < strlen(kPrioChars) ? kPrioChars[prio] : '?'); - char timeBuf[32]; - time_t sec = static_cast<time_t>(entry->sec); - struct tm tmBuf; - struct tm* ptm; - ptm = localtime_r(&sec, &tmBuf); - strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm); - // Look for line breaks ('\n') and display each text line // on a separate line, prefixed with the header, like logcat does. do { @@ -565,6 +582,7 @@ static void dump_log_file(log_t* log, pid_t pid, const char* filename, static void dump_logs(log_t* log, pid_t pid, unsigned tail) { dump_log_file(log, pid, "system", tail); dump_log_file(log, pid, "main", tail); + dump_log_file(log, pid, "events", tail); } static void dump_abort_message(Backtrace* backtrace, log_t* log, uintptr_t address) { diff --git a/init/init_parser.c b/init/init_parser.c index 02e5bdc..7800082 100644 --- a/init/init_parser.c +++ b/init/init_parser.c @@ -760,7 +760,7 @@ static void parse_line_service(struct parse_state *state, int nargs, char **args break; case K_setenv: { /* name value */ struct svcenvinfo *ei; - if (nargs < 2) { + if (nargs < 3) { parse_error(state, "setenv option requires name and value arguments\n"); break; } diff --git a/init/property_service.c b/init/property_service.c index 7e8d79a..4bcf883 100644 --- a/init/property_service.c +++ b/init/property_service.c @@ -90,6 +90,7 @@ struct { { "log.", AID_SHELL, 0 }, { "service.adb.root", AID_SHELL, 0 }, { "service.adb.tcp.port", AID_SHELL, 0 }, + { "persist.logd.size",AID_SYSTEM, 0 }, { "persist.sys.", AID_SYSTEM, 0 }, { "persist.service.", AID_SYSTEM, 0 }, { "persist.security.", AID_SYSTEM, 0 }, diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp index db4fddd..ed2c241 100644 --- a/logcat/logcat.cpp +++ b/logcat/logcat.cpp @@ -623,19 +623,20 @@ int main(int argc, char **argv) } if (!devices) { - devices = new log_device_t("main", false, 'm'); + dev = devices = new log_device_t("main", false, 'm'); android::g_devCount = 1; if (android_name_to_log_id("system") == LOG_ID_SYSTEM) { - devices->next = new log_device_t("system", false, 's'); + dev = dev->next = new log_device_t("system", false, 's'); android::g_devCount++; } if (android_name_to_log_id("crash") == LOG_ID_CRASH) { - if (devices->next) { - devices->next->next = new log_device_t("crash", false, 'c'); - } else { - devices->next = new log_device_t("crash", false, 'c'); - } + dev = dev->next = new log_device_t("crash", false, 'c'); + android::g_devCount++; + } + if (android_name_to_log_id("events") == LOG_ID_EVENTS) { + dev = dev->next = new log_device_t("events", true, 'e'); android::g_devCount++; + needBinary = true; } } diff --git a/logd/Android.mk b/logd/Android.mk index 9f4c64f..188511f 100644 --- a/logd/Android.mk +++ b/logd/Android.mk @@ -17,7 +17,8 @@ LOCAL_SRC_FILES := \ LogStatistics.cpp \ LogWhiteBlackList.cpp \ libaudit.c \ - LogAudit.cpp + LogAudit.cpp \ + event.logtags LOCAL_SHARED_LIBRARIES := \ libsysutils \ @@ -25,7 +26,7 @@ LOCAL_SHARED_LIBRARIES := \ libcutils \ libutils -LOCAL_CFLAGS := -Werror +LOCAL_CFLAGS := -Werror $(shell sed -n 's/^\([0-9]*\)[ \t]*auditd[ \t].*/-DAUDITD_LOG_TAG=\1/p' $(LOCAL_PATH)/event.logtags) include $(BUILD_EXECUTABLE) diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp index add0f0e..0651a92 100644 --- a/logd/LogAudit.cpp +++ b/logd/LogAudit.cpp @@ -54,9 +54,6 @@ bool LogAudit::onDataAvailable(SocketClient *cli) { return true; } -#define AUDIT_LOG_ID LOG_ID_MAIN -#define AUDIT_LOG_PRIO ANDROID_LOG_WARN - int LogAudit::logPrint(const char *fmt, ...) { if (fmt == NULL) { return -EINVAL; @@ -115,43 +112,30 @@ int LogAudit::logPrint(const char *fmt, ...) { strcpy(pidptr, cp); } - static const char comm_str[] = " comm=\""; - char *comm = strstr(str, comm_str); - if (comm) { - cp = comm; - comm += sizeof(comm_str) - 1; - char *ecomm = strchr(comm, '"'); - if (ecomm) { - *ecomm = '\0'; - } - comm = strdup(comm); - if (ecomm) { - strcpy(cp, ecomm + 1); - } - } else if (pid == getpid()) { - pid = tid; - comm = strdup("auditd"); - } else if (!(comm = logbuf->pidToName(pid))) { - comm = strdup("unknown"); - } - - size_t l = strlen(comm) + 1; - size_t n = l + strlen(str) + 2; + size_t n = strlen(str); + n += sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t); char *newstr = reinterpret_cast<char *>(malloc(n)); if (!newstr) { - free(comm); free(str); return -ENOMEM; } - *newstr = AUDIT_LOG_PRIO; - strcpy(newstr + 1, comm); - free(comm); - strcpy(newstr + 1 + l, str); + char *msg = newstr; + *msg++ = AUDITD_LOG_TAG & 0xFF; + *msg++ = (AUDITD_LOG_TAG >> 8) & 0xFF; + *msg++ = (AUDITD_LOG_TAG >> 16) & 0xFF; + *msg++ = (AUDITD_LOG_TAG >> 24) & 0xFF; + *msg++ = EVENT_TYPE_STRING; + size_t l = n - sizeof(uint32_t) - sizeof(uint8_t) - sizeof(uint32_t); + *msg++ = l & 0xFF; + *msg++ = (l >> 8) & 0xFF; + *msg++ = (l >> 16) & 0xFF; + *msg++ = (l >> 24) & 0xFF; + memcpy(msg, str, l); free(str); - logbuf->log(AUDIT_LOG_ID, now, uid, pid, tid, newstr, + logbuf->log(LOG_ID_EVENTS, now, uid, pid, tid, newstr, (n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX); reader->notifyNewLog(); diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp index dc9d47e..ae167aa 100644 --- a/logd/LogBuffer.cpp +++ b/logd/LogBuffer.cpp @@ -18,6 +18,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/user.h> #include <time.h> #include <unistd.h> @@ -32,6 +33,34 @@ // Default #define LOG_BUFFER_SIZE (256 * 1024) // Tuned on a per-platform basis here? #define log_buffer_size(id) mMaxSize[id] +#define LOG_BUFFER_MIN_SIZE (64 * 1024UL) +#define LOG_BUFFER_MAX_SIZE (256 * 1024 * 1024UL) + +static bool valid_size(unsigned long value) { + if ((value < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < value)) { + return false; + } + + long pages = sysconf(_SC_PHYS_PAGES); + if (pages < 1) { + return true; + } + + long pagesize = sysconf(_SC_PAGESIZE); + if (pagesize <= 1) { + pagesize = PAGE_SIZE; + } + + // maximum memory impact a somewhat arbitrary ~3% + pages = (pages + 31) / 32; + unsigned long maximum = pages * pagesize; + + if ((maximum < LOG_BUFFER_MIN_SIZE) || (LOG_BUFFER_MAX_SIZE < maximum)) { + return true; + } + + return value <= maximum; +} static unsigned long property_get_size(const char *key) { char property[PROPERTY_VALUE_MAX]; @@ -56,6 +85,10 @@ static unsigned long property_get_size(const char *key) { value = 0; } + if (!valid_size(value)) { + value = 0; + } + return value; } @@ -64,18 +97,38 @@ LogBuffer::LogBuffer(LastLogTimes *times) pthread_mutex_init(&mLogElementsLock, NULL); dgram_qlen_statistics = false; - static const char global_default[] = "persist.logd.size"; - unsigned long default_size = property_get_size(global_default); + static const char global_tuneable[] = "persist.logd.size"; // Settings App + static const char global_default[] = "ro.logd.size"; // BoardConfig.mk - log_id_for_each(i) { - setSize(i, LOG_BUFFER_SIZE); - setSize(i, default_size); + unsigned long default_size = property_get_size(global_tuneable); + if (!default_size) { + default_size = property_get_size(global_default); + } + log_id_for_each(i) { char key[PROP_NAME_MAX]; + snprintf(key, sizeof(key), "%s.%s", - global_default, android_log_id_to_name(i)); + global_tuneable, android_log_id_to_name(i)); + unsigned long property_size = property_get_size(key); + + if (!property_size) { + snprintf(key, sizeof(key), "%s.%s", + global_default, android_log_id_to_name(i)); + property_size = property_get_size(key); + } + + if (!property_size) { + property_size = default_size; + } - setSize(i, property_get_size(key)); + if (!property_size) { + property_size = LOG_BUFFER_SIZE; + } + + if (setSize(i, property_size)) { + setSize(i, LOG_BUFFER_MIN_SIZE); + } } } @@ -339,7 +392,7 @@ unsigned long LogBuffer::getSizeUsed(log_id_t id) { // set the total space allocated to "id" int LogBuffer::setSize(log_id_t id, unsigned long size) { // Reasonable limits ... - if ((size < (64 * 1024)) || ((256 * 1024 * 1024) < size)) { + if (!valid_size(size)) { return -1; } pthread_mutex_lock(&mLogElementsLock); diff --git a/logd/LogCommand.cpp b/logd/LogCommand.cpp index 0873e63..e4c138e 100644 --- a/logd/LogCommand.cpp +++ b/logd/LogCommand.cpp @@ -64,7 +64,7 @@ bool clientHasLogCredentials(SocketClient * cli) { } gid_t gid = cli->getGid(); - if ((gid == AID_ROOT) || (gid == AID_LOG)) { + if ((gid == AID_ROOT) || (gid == AID_SYSTEM) || (gid == AID_LOG)) { return true; } diff --git a/logd/event.logtags b/logd/event.logtags new file mode 100644 index 0000000..a63f034 --- /dev/null +++ b/logd/event.logtags @@ -0,0 +1,36 @@ +# The entries in this file map a sparse set of log tag numbers to tag names. +# This is installed on the device, in /system/etc, and parsed by logcat. +# +# Tag numbers are decimal integers, from 0 to 2^31. (Let's leave the +# negative values alone for now.) +# +# Tag names are one or more ASCII letters and numbers or underscores, i.e. +# "[A-Z][a-z][0-9]_". Do not include spaces or punctuation (the former +# impacts log readability, the latter makes regex searches more annoying). +# +# Tag numbers and names are separated by whitespace. Blank lines and lines +# starting with '#' are ignored. +# +# Optionally, after the tag names can be put a description for the value(s) +# of the tag. Description are in the format +# (<name>|data type[|data unit]) +# Multiple values are separated by commas. +# +# The data type is a number from the following values: +# 1: int +# 2: long +# 3: string +# 4: list +# +# The data unit is a number taken from the following list: +# 1: Number of objects +# 2: Number of bytes +# 3: Number of milliseconds +# 4: Number of allocations +# 5: Id +# 6: Percent +# Default value for data of type int/long is 2 (bytes). +# +# TODO: generate ".java" and ".h" files with integer constants from this file. + +1003 auditd (avc|3) diff --git a/rootdir/init.zygote32_64.rc b/rootdir/init.zygote32_64.rc index 3d60a31..68c0668 100644 --- a/rootdir/init.zygote32_64.rc +++ b/rootdir/init.zygote32_64.rc @@ -1,4 +1,4 @@ -service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote +service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote class main socket zygote stream 660 root system onrestart write /sys/android_power/request_state wake diff --git a/toolbox/start.c b/toolbox/start.c index 665a941..26344da 100644 --- a/toolbox/start.c +++ b/toolbox/start.c @@ -15,6 +15,7 @@ int start_main(int argc, char *argv[]) /* defaults to starting the common services stopped by stop.c */ property_set("ctl.start", "surfaceflinger"); property_set("ctl.start", "zygote"); + property_set("ctl.start", "zygote_secondary"); } return 0; diff --git a/toolbox/stop.c b/toolbox/stop.c index 460f377..6552c7c 100644 --- a/toolbox/stop.c +++ b/toolbox/stop.c @@ -11,6 +11,7 @@ int stop_main(int argc, char *argv[]) property_set("ctl.stop", argv[1]); } else{ /* defaults to stopping the common services */ + property_set("ctl.stop", "zygote_secondary"); property_set("ctl.stop", "zygote"); property_set("ctl.stop", "surfaceflinger"); } |