logd: Allow flags "eng" and "svelte" in boolean

- enhance property_get_bool, drop property_get_bool_svelte
- enhance base properties with ro and persist variants
- update and fortify README.property
- primarily move auditd and kernel logger into a realm where
  they can be controlled by build properties.
- Move logd.klogd to logd.kernel, and add ro.logd.kernel
  and persist.logd.kernel.
- Add ro.logd.auditd and persist.logd.auditd.
- Document persist.logd.security
- Document log.tag and persist.logd.tag properties.
- Document ro.logd.size, persist.logd.size and logd.size
  properties.

Bug: 26178938
Bug: 26029733
Bug: 17760225
Change-Id: Ibc1a497e45d69db5cf52133937f7ba6fb1d6cd21
This commit is contained in:
Mark Salyzyn 2015-12-14 16:40:12 -08:00
parent 8a1b764db9
commit 9c66a58f21
4 changed files with 135 additions and 55 deletions

View File

@ -101,9 +101,10 @@ void LogBuffer::init() {
if (!default_size) {
default_size = property_get_size(global_default);
if (!default_size) {
default_size = property_get_bool("ro.config.low_ram", false) ?
LOG_BUFFER_MIN_SIZE : // 64K
LOG_BUFFER_SIZE; // 256K
default_size = property_get_bool("ro.config.low_ram",
BOOL_DEFAULT_FALSE)
? LOG_BUFFER_MIN_SIZE // 64K
: LOG_BUFFER_SIZE; // 256K
}
}

View File

@ -44,7 +44,14 @@ bool clientHasLogCredentials(uid_t uid, gid_t gid, pid_t pid);
bool clientHasLogCredentials(SocketClient *cli);
// Furnished in main.cpp
bool property_get_bool(const char *key, bool def);
#define BOOL_DEFAULT_FLAG_TRUE_FALSE 0x1
#define BOOL_DEFAULT_FALSE 0x0 // false if property not present
#define BOOL_DEFAULT_TRUE 0x1 // true if property not present
#define BOOL_DEFAULT_FLAG_PERSIST 0x2 // <key>, persist.<key>, ro.<key>
#define BOOL_DEFAULT_FLAG_ENG 0x4 // off for user
#define BOOL_DEFAULT_FLAG_SVELTE 0x8 // off for low_ram
bool property_get_bool(const char *key, int def);
static inline bool worstUidEnabledForLogid(log_id_t id) {
return (id == LOG_ID_MAIN) || (id == LOG_ID_SYSTEM) || (id == LOG_ID_RADIO);

View File

@ -1,37 +1,53 @@
The properties that logd responds to are:
name type default description
logd.auditd bool true Enable selinux audit daemon
logd.auditd.dmesg bool true selinux audit messages duplicated and
ro.logd.auditd bool true Enable selinux audit daemon
ro.logd.auditd.dmesg bool true selinux audit messages duplicated and
sent on to dmesg log
logd.klogd bool depends Enable klogd daemon
logd.statistics bool depends Enable logcat -S statistics.
ro.config.low_ram bool false if true, logd.statistics & logd.klogd
default false
ro.build.type string if user, logd.statistics & logd.klogd
default false
persist.logd.logpersistd string Enable logpersist daemon, "logcatd"
persist.logd.security bool false Enable security buffer.
ro.device_owner bool false Override persist.logd.security to false
ro.logd.kernel bool+ svelte+ Enable klogd daemon
ro.logd.statistics bool+ svelte+ Enable logcat -S statistics.
ro.build.type string if user, logd.statistics &
ro.logd.kernel default false.
persist.logd.logpersistd string Enable logpersist daemon, "logcatd"
turns on logcat -f in logd context
persist.logd.size number 256K Global default size of the buffer for
persist.logd.size number ro Global default size of the buffer for
all log ids at initial startup, at
runtime use: logcat -b all -G <value>
persist.logd.size.main number 256K Size of the buffer for the main log
persist.logd.size.system number 256K Size of the buffer for the system log
persist.logd.size.radio number 256K Size of the buffer for the radio log
persist.logd.size.event number 256K Size of the buffer for the event log
persist.logd.size.crash number 256K Size of the buffer for the crash log
persist.logd.filter string Pruning filter to optimize content,
default is ro.logd.filter or
"~!" which means to prune the oldest
entries of chattiest UID. At runtime
use: logcat -P "<string>"
persist.logd.timestamp string The recording timestamp source. Default
is ro.logd.timestamp. "m[onotonic]" is
the only supported key character,
otherwise assumes realtime.
ro.logd.size number svelte default for persist.logd.size
persist.logd.size.<buffer> number ro Size of the buffer for <buffer> log
ro.logd.size.<buffer> number svelte default for persist.logd.size.<buffer>
ro.config.low_ram bool false if true, logd.statistics, logd.kernel
default false, logd.size 64K instead
of 256K.
persist.logd.filter string Pruning filter to optimize content.
At runtime use: logcat -P "<string>"
ro.logd.filter string "~!" default for persist.logd.filter.
This default means to prune the
oldest entries of chattiest UID.
persist.logd.timestamp string ro The recording timestamp source.
"m[onotonic]" is the only supported
key character, otherwise realtime.
ro.logd.timestamp string realtime default for persist.logd.timestamp
log.tag string persist The global logging level, VERBOSE,
DEBUG, INFO, WARN, ERROR, ASSERT or
SILENT. Only the first character is
the key character.
persist.log.tag string build default for log.tag
log.tag.<tag> string persist The <tag> specific logging level.
persist.log.tag.<tag> string build default for log.tag.<tag>
NB:
- Number support multipliers (K or M) for convenience. Range is limited
- bool+ - "true", "false" and comma separated list of "eng" (forced false if
ro.build.type is "user") or "svelte" (forced false if ro.config.low_ram is
true).
- svelte - see ro.config.low_ram for details.
- svelte+ - see ro.config.low_ram and ro.build.type for details.
- ro - <base property> temporary override, ro.<base property> platform default.
- persist - <base property> override, persist.<base property> platform default.
- build - VERBOSE for native, DEBUG for jvm isLoggable, or developer option.
- number - support multipliers (K or M) for convenience. Range is limited
to between 64K and 256M for log buffer sizes. Individual log buffer ids
such as main, system, ... override global default.
- Pruning filter is of form of a space-separated list of [~][UID][/PID]

View File

@ -143,18 +143,72 @@ static int drop_privs() {
}
// Property helper
bool property_get_bool(const char *key, bool def) {
char property[PROPERTY_VALUE_MAX];
property_get(key, property, "");
if (!strcasecmp(property, "true")) {
return true;
}
if (!strcasecmp(property, "false")) {
static bool check_flag(const char *prop, const char *flag) {
const char *cp = strcasestr(prop, flag);
if (!cp) {
return false;
}
// We only will document comma (,)
static const char sep[] = ",:;|+ \t\f";
if ((cp != prop) && !strchr(sep, cp[-1])) {
return false;
}
cp += strlen(flag);
return !*cp || !!strchr(sep, *cp);
}
return def;
bool property_get_bool(const char *key, int flag) {
char def[PROPERTY_VALUE_MAX];
char property[PROPERTY_VALUE_MAX];
def[0] = '\0';
if (flag & BOOL_DEFAULT_FLAG_PERSIST) {
char newkey[PROPERTY_KEY_MAX];
snprintf(newkey, sizeof(newkey), "ro.%s", key);
property_get(newkey, property, "");
// persist properties set by /data require innoculation with
// logd-reinit. They may be set in init.rc early and function, but
// otherwise are defunct unless reset. Do not rely on persist
// properties for startup-only keys unless you are willing to restart
// logd daemon (not advised).
snprintf(newkey, sizeof(newkey), "persist.%s", key);
property_get(newkey, def, property);
}
property_get(key, property, def);
if (check_flag(property, "true")) {
return true;
}
if (check_flag(property, "false")) {
return false;
}
if (check_flag(property, "eng")) {
flag |= BOOL_DEFAULT_FLAG_ENG;
}
// this is really a "not" flag
if (check_flag(property, "svelte")) {
flag |= BOOL_DEFAULT_FLAG_SVELTE;
}
// Sanity Check
if (flag & (BOOL_DEFAULT_FLAG_SVELTE | BOOL_DEFAULT_FLAG_ENG)) {
flag &= ~BOOL_DEFAULT_FLAG_TRUE_FALSE;
flag |= BOOL_DEFAULT_TRUE;
}
if ((flag & BOOL_DEFAULT_FLAG_SVELTE)
&& property_get_bool("ro.config.low_ram",
BOOL_DEFAULT_FALSE)) {
return false;
}
if (flag & BOOL_DEFAULT_FLAG_ENG) {
property_get("ro.build.type", property, "");
if (!strcmp(property, "user")) {
return false;
}
}
return (flag & BOOL_DEFAULT_FLAG_TRUE_FALSE) != BOOL_DEFAULT_FALSE;
}
// Remove the static, and use this variable
@ -266,17 +320,6 @@ const char *android::tagToName(uint32_t tag) {
return android_lookupEventTag(map, tag);
}
static bool property_get_bool_svelte(const char *key) {
bool not_user;
{
char property[PROPERTY_VALUE_MAX];
property_get("ro.build.type", property, "");
not_user = !!strcmp(property, "user");
}
return property_get_bool(key, not_user
&& !property_get_bool("ro.config.low_ram", false));
}
static void readDmesg(LogAudit *al, LogKlog *kl) {
if (!al && !kl) {
return;
@ -325,7 +368,11 @@ static void readDmesg(LogAudit *al, LogKlog *kl) {
// transitory per-client threads are created for each reader.
int main(int argc, char *argv[]) {
int fdPmesg = -1;
bool klogd = property_get_bool_svelte("logd.klogd");
bool klogd = property_get_bool("logd.kernel",
BOOL_DEFAULT_TRUE |
BOOL_DEFAULT_FLAG_PERSIST |
BOOL_DEFAULT_FLAG_ENG |
BOOL_DEFAULT_FLAG_SVELTE);
if (klogd) {
fdPmesg = open("/proc/kmsg", O_RDONLY | O_NDELAY);
}
@ -405,7 +452,11 @@ int main(int argc, char *argv[]) {
signal(SIGHUP, reinit_signal_handler);
if (property_get_bool_svelte("logd.statistics")) {
if (property_get_bool("logd.statistics",
BOOL_DEFAULT_TRUE |
BOOL_DEFAULT_FLAG_PERSIST |
BOOL_DEFAULT_FLAG_ENG |
BOOL_DEFAULT_FLAG_SVELTE)) {
logBuf->enableStatistics();
}
@ -439,12 +490,17 @@ int main(int argc, char *argv[]) {
// initiated log messages. New log entries are added to LogBuffer
// and LogReader is notified to send updates to connected clients.
bool auditd = property_get_bool("logd.auditd", true);
bool auditd = property_get_bool("logd.auditd",
BOOL_DEFAULT_TRUE |
BOOL_DEFAULT_FLAG_PERSIST);
LogAudit *al = NULL;
if (auditd) {
bool dmesg = property_get_bool("logd.auditd.dmesg", true);
al = new LogAudit(logBuf, reader, dmesg ? fdDmesg : -1);
al = new LogAudit(logBuf, reader,
property_get_bool("logd.auditd.dmesg",
BOOL_DEFAULT_TRUE |
BOOL_DEFAULT_FLAG_PERSIST)
? fdDmesg
: -1);
}
LogKlog *kl = NULL;