Merge "Restart wificond when zygote died"
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..b44c296
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1 @@
+subdirs = ["*"]
diff --git a/adb/Android.mk b/adb/Android.mk
index 16ed991..fab8c87 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -330,6 +330,7 @@
LOCAL_STATIC_LIBRARIES := \
libadbd \
libbase \
+ libbootloader_message \
libfs_mgr \
libfec \
libfec_rs \
diff --git a/adb/services.cpp b/adb/services.cpp
index 2fbc15a..df1b134 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -39,6 +39,7 @@
#if !ADB_HOST
#include <android-base/properties.h>
+#include <bootloader_message/bootloader_message.h>
#include <cutils/android_reboot.h>
#include <private/android_logger.h>
#endif
@@ -133,17 +134,12 @@
return false;
}
- const char* const recovery_dir = "/cache/recovery";
- const char* const command_file = "/cache/recovery/command";
- // Ensure /cache/recovery exists.
- if (adb_mkdir(recovery_dir, 0770) == -1 && errno != EEXIST) {
- D("Failed to create directory '%s': %s", recovery_dir, strerror(errno));
- return false;
- }
-
- bool write_status = android::base::WriteStringToFile(
- auto_reboot ? "--sideload_auto_reboot" : "--sideload", command_file);
- if (!write_status) {
+ const std::vector<std::string> options = {
+ auto_reboot ? "--sideload_auto_reboot" : "--sideload"
+ };
+ std::string err;
+ if (!write_bootloader_message(options, &err)) {
+ D("Failed to set bootloader message: %s", err.c_str());
return false;
}
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 7c0e85d..483c01d 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -207,6 +207,19 @@
return boot_complete_prefix;
}
+// Records the value of a given ro.boottime.init property in milliseconds.
+void RecordInitBootTimeProp(
+ BootEventRecordStore* boot_event_store, const char* property) {
+ std::string value = GetProperty(property);
+
+ int32_t time_in_ns;
+ if (android::base::ParseInt(value, &time_in_ns)) {
+ static constexpr int32_t kNanosecondsPerMillisecond = 1e6;
+ int32_t time_in_ms = static_cast<int32_t>(time_in_ns / kNanosecondsPerMillisecond);
+ boot_event_store->AddBootEventWithValue(property, time_in_ms);
+ }
+}
+
// Records several metrics related to the time it takes to boot the device,
// including disambiguating boot time on encrypted or non-encrypted devices.
void RecordBootComplete() {
@@ -256,6 +269,10 @@
// Record the total time from device startup to boot complete, regardless of
// encryption state.
boot_event_store.AddBootEventWithValue(boot_complete_prefix, uptime);
+
+ RecordInitBootTimeProp(&boot_event_store, "ro.boottime.init");
+ RecordInitBootTimeProp(&boot_event_store, "ro.boottime.init.selinux");
+ RecordInitBootTimeProp(&boot_event_store, "ro.boottime.init.cold_boot_wait");
}
// Records the boot_reason metric by querying the ro.boot.bootreason system
diff --git a/fastboot/fastboot_protocol.txt b/fastboot/fastboot_protocol.txt
index 2801703..b12e420 100644
--- a/fastboot/fastboot_protocol.txt
+++ b/fastboot/fastboot_protocol.txt
@@ -78,7 +78,7 @@
Host: "getvar:nonexistant" request some undefined variable
-Client: "OKAY" return value ""
+Client: "FAILUnknown variable" getvar failure; see getvar details below
Host: "download:00001234" request to send 0x1234 bytes of data
@@ -113,7 +113,14 @@
"getvar:%s" Read a config/version variable from the bootloader.
The variable contents will be returned after the
- OKAY response.
+ OKAY response. If the variable is unknown, the bootloader
+ should return a FAIL response, optionally with an error
+ message.
+
+ Previous versions of this document indicated that getvar
+ should return an empty OKAY response for unknown
+ variables, so older devices might exhibit this behavior,
+ but new implementations should return FAIL instead.
"download:%08x" Write data to memory which will be later used
by "boot", "ramdisk", "flash", etc. The client
@@ -215,7 +222,7 @@
Host [0x00][0x00][0x00][0x00][0x00][0x00][0x00][0x0E]getvar:version
Device [0x00][0x00][0x00][0x00][0x00][0x00][0x00][0x07]OKAY0.4
Host [0x00][0x00][0x00][0x00][0x00][0x00][0x00][0x0B]getvar:none
-Device [0x00][0x00][0x00][0x00][0x00][0x00][0x00][0x04]OKAY
+Device [0x00][0x00][0x00][0x00][0x00][0x00][0x00][0x14]FAILUnknown variable
Host <disconnect>
@@ -364,10 +371,10 @@
0x03 0x00 0x00 0x01
0x03 0x00 0x00 0x02
0x03 0x00 0x00 0x02 OKAY0.4
-0x03 0x00 0x00 0x03 getvar:foo
+0x03 0x00 0x00 0x03 getvar:none
0x03 0x00 0x00 0x03
0x03 0x00 0x00 0x04
- 0x03 0x00 0x00 0x04 OKAY
+ 0x03 0x00 0x00 0x04 FAILUnknown var
----------------------------------------------------------------------
[fastboot "INFO" responses, S = 0x0000]
diff --git a/fingerprintd/FingerprintDaemonProxy.cpp b/fingerprintd/FingerprintDaemonProxy.cpp
index 0119e55..73748f2 100644
--- a/fingerprintd/FingerprintDaemonProxy.cpp
+++ b/fingerprintd/FingerprintDaemonProxy.cpp
@@ -171,7 +171,7 @@
hardware::hidl_array<uint8_t, hw_auth_token_size> hat(token);
Return<RequestStatus> ret = gBFP->enroll(hat, groupId, timeout);
- if (!ret.getStatus().isOk()) {
+ if (!ret.isOk()) {
ALOGE("Unknown transport error");
return -1;
}
@@ -186,7 +186,7 @@
int32_t FingerprintDaemonProxy::postEnroll() {
Return<RequestStatus> ret = gBFP->postEnroll();
- if (!ret.getStatus().isOk()) {
+ if (!ret.isOk()) {
ALOGE("Unknown transport error");
return -1;
}
@@ -198,7 +198,7 @@
int32_t FingerprintDaemonProxy::stopEnrollment() {
ALOG(LOG_VERBOSE, LOG_TAG, "stopEnrollment()\n");
Return<RequestStatus> ret = gBFP->cancel();
- if (!ret.getStatus().isOk()) {
+ if (!ret.isOk()) {
ALOGE("Unknown transport error");
return -1;
}
@@ -210,7 +210,7 @@
int32_t FingerprintDaemonProxy::authenticate(uint64_t sessionId, uint32_t groupId) {
ALOG(LOG_VERBOSE, LOG_TAG, "authenticate(sid=%" PRId64 ", gid=%d)\n", sessionId, groupId);
Return<RequestStatus> ret = gBFP->authenticate(sessionId, groupId);
- if (!ret.getStatus().isOk()) {
+ if (!ret.isOk()) {
ALOGE("Unknown transport error");
return -1;
}
@@ -222,7 +222,7 @@
int32_t FingerprintDaemonProxy::stopAuthentication() {
ALOG(LOG_VERBOSE, LOG_TAG, "stopAuthentication()\n");
Return<RequestStatus> ret = gBFP->cancel();
- if (!ret.getStatus().isOk()) {
+ if (!ret.isOk()) {
ALOGE("Unknown transport error");
return -1;
}
@@ -234,7 +234,7 @@
int32_t FingerprintDaemonProxy::remove(int32_t fingerId, int32_t groupId) {
ALOG(LOG_VERBOSE, LOG_TAG, "remove(fid=%d, gid=%d)\n", fingerId, groupId);
Return<RequestStatus> ret = gBFP->remove(groupId, fingerId);
- if (!ret.getStatus().isOk()) {
+ if (!ret.isOk()) {
ALOGE("Unknown transport error");
return -1;
}
@@ -246,7 +246,7 @@
int32_t FingerprintDaemonProxy::enumerate() {
ALOG(LOG_VERBOSE, LOG_TAG, "enumerate()\n");
Return<RequestStatus> ret = gBFP->enumerate();
- if (!ret.getStatus().isOk()) {
+ if (!ret.isOk()) {
ALOGE("Unknown transport error");
return -1;
}
@@ -269,7 +269,7 @@
pathname.setToExternal(reinterpret_cast<const char*>(path), pathlen);
ALOG(LOG_VERBOSE, LOG_TAG, "setActiveGroup(%d, %s, %zu)", groupId, pathname.c_str(), pathlen);
Return<RequestStatus> ret = gBFP->setActiveGroup(groupId, pathname);
- if (!ret.getStatus().isOk()) {
+ if (!ret.isOk()) {
ALOGE("Unknown transport error");
return -1;
}
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index 7389f59..88b5c98 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -464,7 +464,7 @@
if (!end_idx || !attempted_idx || start_idx >= fstab->num_entries) {
errno = EINVAL;
if (end_idx) *end_idx = start_idx;
- if (attempted_idx) *end_idx = start_idx;
+ if (attempted_idx) *attempted_idx = start_idx;
return -1;
}
diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp
index d2c119d..bea7ee7 100644
--- a/gatekeeperd/gatekeeperd.cpp
+++ b/gatekeeperd/gatekeeperd.cpp
@@ -184,7 +184,7 @@
ret = rsp.timeout;
}
});
- if (!hwRes.getStatus().isOk()) {
+ if (!hwRes.isOk()) {
ALOGE("enroll transaction failed\n");
ret = -1;
}
@@ -196,7 +196,14 @@
enrolled_password_handle, enrolled_password_handle_length);
}
- if (ret == 0) {
+ if (ret == GATEKEEPER_RESPONSE_OK && (*enrolled_password_handle == nullptr ||
+ *enrolled_password_handle_length != sizeof(password_handle_t))) {
+ ret = GATEKEEPER_RESPONSE_ERROR;
+ ALOGE("HAL: password_handle=%p size_of_handle=%" PRIu32 "\n",
+ *enrolled_password_handle, *enrolled_password_handle_length);
+ }
+
+ if (ret == GATEKEEPER_RESPONSE_OK) {
gatekeeper::password_handle_t *handle =
reinterpret_cast<gatekeeper::password_handle_t *>(*enrolled_password_handle);
store_sid(uid, handle->user_id);
@@ -267,7 +274,7 @@
ret = rsp.timeout;
}
});
- if (!hwRes.getStatus().isOk()) {
+ if (!hwRes.isOk()) {
ALOGE("verify transaction failed\n");
ret = -1;
}
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 0c90a54..369a022 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -141,6 +141,7 @@
struct sysfsStringEnumMap supplyTypeMap[] = {
{ "Unknown", ANDROID_POWER_SUPPLY_TYPE_UNKNOWN },
{ "Battery", ANDROID_POWER_SUPPLY_TYPE_BATTERY },
+ { "BMS", ANDROID_POWER_SUPPLY_TYPE_BATTERY },
{ "UPS", ANDROID_POWER_SUPPLY_TYPE_AC },
{ "Mains", ANDROID_POWER_SUPPLY_TYPE_AC },
{ "USB", ANDROID_POWER_SUPPLY_TYPE_USB },
diff --git a/include/log/log.h b/include/log/log.h
index d6f0eb5..ece9ea6 100644
--- a/include/log/log.h
+++ b/include/log/log.h
@@ -24,7 +24,7 @@
#include <stdint.h> /* uint16_t, int32_t */
#include <stdio.h>
#include <sys/types.h>
-#include <time.h> /* clock_gettime */
+#include <time.h>
#include <unistd.h>
#include <android/log.h>
@@ -812,6 +812,54 @@
void __android_log_close();
#endif
+#ifndef __ANDROID_USE_LIBLOG_RATELIMIT_INTERFACE
+#ifndef __ANDROID_API__
+#define __ANDROID_USE_LIBLOG_RATELIMIT_INTERFACE 1
+#elif __ANDROID_API__ > 25 /* > OC */
+#define __ANDROID_USE_LIBLOG_RATELIMIT_INTERFACE 1
+#else
+#define __ANDROID_USE_LIBLOG_RATELIMIT_INTERFACE 0
+#endif
+#endif
+
+#if __ANDROID_USE_LIBLOG_RATELIMIT_INTERFACE
+
+/*
+ * if last is NULL, caller _must_ provide a consistent value for seconds.
+ *
+ * Return -1 if we can not acquire a lock, which below will permit the logging,
+ * error on allowing a log message through.
+ */
+int __android_log_ratelimit(time_t seconds, time_t* last);
+
+/*
+ * Usage:
+ *
+ * // Global default and state
+ * IF_ALOG_RATELIMIT() {
+ * ALOG*(...);
+ * }
+ *
+ * // local state, 10 seconds ratelimit
+ * static time_t local_state;
+ * IF_ALOG_RATELIMIT_LOCAL(10, &local_state) {
+ * ALOG*(...);
+ * }
+ */
+
+#define IF_ALOG_RATELIMIT() \
+ if (__android_log_ratelimit(0, NULL) > 0)
+#define IF_ALOG_RATELIMIT_LOCAL(seconds, state) \
+ if (__android_log_ratelimit(seconds, state) > 0)
+
+#else
+
+/* No ratelimiting as API unsupported */
+#define IF_ALOG_RATELIMIT() if (1)
+#define IF_ALOG_RATELIMIT_LOCAL(...) if (1)
+
+#endif
+
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
diff --git a/include/system/radio.h b/include/system/radio.h
index b164fc8..ea77bdd 100644
--- a/include/system/radio.h
+++ b/include/system/radio.h
@@ -170,7 +170,7 @@
bool stereo; /* program is stereo or not */
bool digital; /* digital program or not (e.g HD Radio program) */
uint32_t signal_strength; /* signal strength from 0 to 100 */
- /* non null if meta data are present (e.g PTY, song title ...) */
+ /* meta data (e.g PTY, song title ...), must not be NULL */
__attribute__((aligned(8))) radio_metadata_t *metadata;
} radio_program_info_t;
@@ -214,7 +214,7 @@
bool on;
radio_band_config_t config;
radio_program_info_t info;
- /* non null if meta data are present (e.g PTY, song title ...) */
+ /* meta data (e.g PTY, song title ...), must not be NULL */
__attribute__((aligned(8))) radio_metadata_t *metadata;
};
} radio_event_t;
diff --git a/include/ziparchive/zip_archive.h b/include/ziparchive/zip_archive.h
index 54946fc..31fc2df 100644
--- a/include/ziparchive/zip_archive.h
+++ b/include/ziparchive/zip_archive.h
@@ -26,8 +26,6 @@
#include <sys/types.h>
#include <utils/Compat.h>
-__BEGIN_DECLS
-
/* Zip compression methods we support */
enum {
kCompressStored = 0, // no compression
@@ -228,6 +226,4 @@
ProcessZipEntryFunction func, void* cookie);
#endif
-__END_DECLS
-
#endif // LIBZIPARCHIVE_ZIPARCHIVE_H_
diff --git a/init/Android.mk b/init/Android.mk
index ecdf5db..111fe89 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -54,7 +54,7 @@
service.cpp \
util.cpp \
-LOCAL_STATIC_LIBRARIES := libbase libselinux liblog libprocessgroup
+LOCAL_STATIC_LIBRARIES := libbase libselinux liblog libprocessgroup libnl
LOCAL_WHOLE_STATIC_LIBRARIES := libcap
LOCAL_MODULE := libinit
LOCAL_SANITIZE := integer
@@ -103,7 +103,8 @@
libdl \
libsparse_static \
libz \
- libprocessgroup
+ libprocessgroup \
+ libnl \
# Create symlinks.
LOCAL_POST_INSTALL_CMD := $(hide) mkdir -p $(TARGET_ROOT_OUT)/sbin; \
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 812ac3c..1186e9d 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -38,6 +38,7 @@
#include <linux/loop.h>
#include <linux/module.h>
+#include <string>
#include <thread>
#include <selinux/android.h>
@@ -67,6 +68,8 @@
#include "signal_handler.h"
#include "util.h"
+using namespace std::literals::string_literals;
+
#define chmod DO_NOT_USE_CHMOD_USE_FCHMODAT_SYMLINK_NOFOLLOW
#define UNMOUNT_CHECK_TIMES 10
@@ -139,8 +142,7 @@
}
}
-static int wipe_data_via_recovery(const std::string& reason) {
- const std::vector<std::string> options = {"--wipe_data", std::string() + "--reason=" + reason};
+static int reboot_into_recovery(const std::vector<std::string>& options) {
std::string err;
if (!write_bootloader_message(options, &err)) {
LOG(ERROR) << "failed to set bootloader message: " << err;
@@ -247,7 +249,7 @@
}
static int do_domainname(const std::vector<std::string>& args) {
- return write_file("/proc/sys/kernel/domainname", args[1].c_str());
+ return write_file("/proc/sys/kernel/domainname", args[1].c_str()) ? 0 : 1;
}
static int do_enable(const std::vector<std::string>& args) {
@@ -275,7 +277,7 @@
}
static int do_hostname(const std::vector<std::string>& args) {
- return write_file("/proc/sys/kernel/hostname", args[1].c_str());
+ return write_file("/proc/sys/kernel/hostname", args[1].c_str()) ? 0 : 1;
}
static int do_ifup(const std::vector<std::string>& args) {
@@ -338,7 +340,10 @@
if (e4crypt_is_native()) {
if (e4crypt_set_directory_policy(args[1].c_str())) {
- wipe_data_via_recovery(std::string() + "set_policy_failed:" + args[1]);
+ const std::vector<std::string> options = {
+ "--prompt_and_wipe_data",
+ "--reason=set_policy_failed:"s + args[1]};
+ reboot_into_recovery(options);
return -1;
}
}
@@ -559,7 +564,8 @@
} else if (code == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
/* Setup a wipe via recovery, and reboot into recovery */
PLOG(ERROR) << "fs_mgr_mount_all suggested recovery, so wiping data via recovery.";
- ret = wipe_data_via_recovery("fs_mgr_mount_all");
+ const std::vector<std::string> options = {"--wipe_data", "--reason=fs_mgr_mount_all" };
+ ret = reboot_into_recovery(options);
/* If reboot worked, there is no return. */
} else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
if (e4crypt_install_keyring()) {
@@ -808,7 +814,7 @@
static int do_write(const std::vector<std::string>& args) {
const char* path = args[1].c_str();
const char* value = args[2].c_str();
- return write_file(path, value);
+ return write_file(path, value) ? 0 : 1;
}
static int do_copy(const std::vector<std::string>& args) {
diff --git a/init/init.cpp b/init/init.cpp
index 60eac48..ee5add8 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -542,7 +542,7 @@
}
}
- if (write_file("/sys/fs/selinux/checkreqprot", "0") == -1) {
+ if (!write_file("/sys/fs/selinux/checkreqprot", "0")) {
security_failure();
}
diff --git a/init/log.cpp b/init/log.cpp
index 8618340..6b32526 100644
--- a/init/log.cpp
+++ b/init/log.cpp
@@ -19,6 +19,8 @@
#include <fcntl.h>
#include <string.h>
+#include <linux/audit.h>
+#include <netlink/netlink.h>
#include <selinux/selinux.h>
void InitKernelLogging(char* argv[]) {
@@ -38,6 +40,24 @@
android::base::InitLogging(argv, &android::base::KernelLogger);
}
+static void selinux_avc_log(char* buf, size_t buf_len) {
+ size_t str_len = strnlen(buf, buf_len);
+
+ // trim newline at end of string
+ buf[str_len - 1] = '\0';
+
+ struct nl_sock* sk = nl_socket_alloc();
+ if (sk == NULL) {
+ return;
+ }
+ nl_connect(sk, NETLINK_AUDIT);
+ int result;
+ do {
+ result = nl_send_simple(sk, AUDIT_USER_AVC, 0, buf, str_len);
+ } while (result == -NLE_INTR);
+ nl_socket_free(sk);
+}
+
int selinux_klog_callback(int type, const char *fmt, ...) {
android::base::LogSeverity severity = android::base::ERROR;
if (type == SELINUX_WARNING) {
@@ -48,8 +68,15 @@
char buf[1024];
va_list ap;
va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf), fmt, ap);
+ int res = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
- android::base::KernelLogger(android::base::MAIN, severity, "selinux", nullptr, 0, buf);
+ if (res <= 0) {
+ return 0;
+ }
+ if (type == SELINUX_AVC) {
+ selinux_avc_log(buf, sizeof(buf));
+ } else {
+ android::base::KernelLogger(android::base::MAIN, severity, "selinux", nullptr, 0, buf);
+ }
return 0;
}
diff --git a/init/service.cpp b/init/service.cpp
index 7cff348..0f7f62f 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -582,12 +582,15 @@
console_ = default_console;
}
- bool have_console = (access(console_.c_str(), R_OK | W_OK) != -1);
- if (!have_console) {
- PLOG(ERROR) << "service '" << name_ << "' cannot gain read/write access to console '" << console_ << "'";
+ // Make sure that open call succeeds to ensure a console driver is
+ // properly registered for the device node
+ int console_fd = open(console_.c_str(), O_RDWR | O_CLOEXEC);
+ if (console_fd < 0) {
+ PLOG(ERROR) << "service '" << name_ << "' couldn't open console '" << console_ << "'";
flags_ |= SVC_DISABLED;
return false;
}
+ close(console_fd);
}
struct stat sb;
diff --git a/init/util.cpp b/init/util.cpp
index a79a419..888a366 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -185,18 +185,18 @@
return okay;
}
-int write_file(const char* path, const char* content) {
+bool write_file(const char* path, const char* content) {
int fd = TEMP_FAILURE_RETRY(open(path, O_WRONLY|O_CREAT|O_NOFOLLOW|O_CLOEXEC, 0600));
if (fd == -1) {
PLOG(ERROR) << "write_file: Unable to open '" << path << "'";
- return -1;
+ return false;
}
- int result = android::base::WriteStringToFd(content, fd) ? 0 : -1;
- if (result == -1) {
+ bool success = android::base::WriteStringToFd(content, fd);
+ if (!success) {
PLOG(ERROR) << "write_file: Unable to write to '" << path << "'";
}
close(fd);
- return result;
+ return success;
}
boot_clock::time_point boot_clock::now() {
diff --git a/init/util.h b/init/util.h
index e63c469..009413d 100644
--- a/init/util.h
+++ b/init/util.h
@@ -33,7 +33,7 @@
uid_t uid, gid_t gid, const char *socketcon);
bool read_file(const char* path, std::string* content);
-int write_file(const char* path, const char* content);
+bool write_file(const char* path, const char* content);
// A std::chrono clock based on CLOCK_BOOTTIME.
class boot_clock {
diff --git a/libbacktrace/Android.bp b/libbacktrace/Android.bp
index 684e611..5b31ecb 100644
--- a/libbacktrace/Android.bp
+++ b/libbacktrace/Android.bp
@@ -27,22 +27,8 @@
include_dirs: ["external/libunwind/include/tdep"],
- // TODO: LLVM_DEVICE_BUILD_MK
- // TODO: LLVM_HOST_BUILD_MK
target: {
- host: {
- // -fno-omit-frame-pointer should be set for host build. Because currently
- // libunwind can't recognize .debug_frame using dwarf version 4, and it relies
- // on stack frame pointer to do unwinding on x86.
- // $(LLVM_HOST_BUILD_MK) overwrites -fno-omit-frame-pointer. so the below line
- // must be after the include.
- cflags: [
- "-Wno-extern-c-compat",
- "-fno-omit-frame-pointer",
- ],
- },
-
darwin: {
enabled: false,
},
diff --git a/libcutils/properties.c b/libcutils/properties.c
index 5aa6371..740c7a9 100644
--- a/libcutils/properties.c
+++ b/libcutils/properties.c
@@ -36,7 +36,7 @@
}
int8_t result = default_value;
- char buf[PROPERTY_VALUE_MAX] = {'\0',};
+ char buf[PROPERTY_VALUE_MAX] = {'\0'};
int len = property_get(key, buf, "");
if (len == 1) {
@@ -47,7 +47,7 @@
result = true;
}
} else if (len > 1) {
- if (!strcmp(buf, "no") || !strcmp(buf, "false") || !strcmp(buf, "off")) {
+ if (!strcmp(buf, "no") || !strcmp(buf, "false") || !strcmp(buf, "off")) {
result = false;
} else if (!strcmp(buf, "yes") || !strcmp(buf, "true") || !strcmp(buf, "on")) {
result = true;
@@ -59,13 +59,13 @@
// Convert string property to int (default if fails); return default value if out of bounds
static intmax_t property_get_imax(const char *key, intmax_t lower_bound, intmax_t upper_bound,
- intmax_t default_value) {
+ intmax_t default_value) {
if (!key) {
return default_value;
}
intmax_t result = default_value;
- char buf[PROPERTY_VALUE_MAX] = {'\0',};
+ char buf[PROPERTY_VALUE_MAX] = {'\0'};
char *end = NULL;
int len = property_get(key, buf, "");
@@ -74,7 +74,7 @@
errno = 0;
// Infer base automatically
- result = strtoimax(buf, &end, /*base*/0);
+ result = strtoimax(buf, &end, /*base*/ 0);
if ((result == INTMAX_MIN || result == INTMAX_MAX) && errno == ERANGE) {
// Over or underflow
result = default_value;
@@ -86,8 +86,8 @@
} else if (end == buf) {
// Numeric conversion failed
result = default_value;
- ALOGV("%s(%s,%" PRIdMAX ") - numeric conversion failed",
- __FUNCTION__, key, default_value);
+ ALOGV("%s(%s,%" PRIdMAX ") - numeric conversion failed", __FUNCTION__, key,
+ default_value);
}
errno = tmp;
@@ -107,38 +107,31 @@
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include <sys/_system_properties.h>
-int property_set(const char *key, const char *value)
-{
+int property_set(const char *key, const char *value) {
return __system_property_set(key, value);
}
-int property_get(const char *key, char *value, const char *default_value)
-{
+int property_get(const char *key, char *value, const char *default_value) {
int len;
len = __system_property_get(key, value);
- if(len > 0) {
+ if (len > 0) {
return len;
}
- if(default_value) {
- len = strlen(default_value);
- if (len >= PROPERTY_VALUE_MAX) {
- len = PROPERTY_VALUE_MAX - 1;
- }
+ if (default_value) {
+ len = strnlen(default_value, PROPERTY_VALUE_MAX - 1);
memcpy(value, default_value, len);
value[len] = '\0';
}
return len;
}
-struct property_list_callback_data
-{
+struct property_list_callback_data {
void (*propfn)(const char *key, const char *value, void *cookie);
void *cookie;
};
-static void property_list_callback(const prop_info *pi, void *cookie)
-{
+static void property_list_callback(const prop_info *pi, void *cookie) {
char name[PROP_NAME_MAX];
char value[PROP_VALUE_MAX];
struct property_list_callback_data *data = cookie;
@@ -147,10 +140,7 @@
data->propfn(name, value, data->cookie);
}
-int property_list(
- void (*propfn)(const char *key, const char *value, void *cookie),
- void *cookie)
-{
- struct property_list_callback_data data = { propfn, cookie };
+int property_list(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie) {
+ struct property_list_callback_data data = {propfn, cookie};
return __system_property_foreach(property_list_callback, &data);
}
diff --git a/libcutils/tests/PropertiesTest.cpp b/libcutils/tests/PropertiesTest.cpp
index f0cdffd..7921972 100644
--- a/libcutils/tests/PropertiesTest.cpp
+++ b/libcutils/tests/PropertiesTest.cpp
@@ -159,19 +159,68 @@
TEST_F(PropertiesTest, GetString) {
- // Try to use a default value that's too long => set fails
+ // Try to use a default value that's too long => get truncates the value
{
ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
- std::string maxLengthString = std::string(PROPERTY_VALUE_MAX-1, 'a');
+ std::string maxLengthString = std::string(PROPERTY_VALUE_MAX - 1, 'a');
std::string oneLongerString = std::string(PROPERTY_VALUE_MAX, 'a');
// Expect that the value is truncated since it's too long (by 1)
int len = property_get(PROPERTY_TEST_KEY, mValue, oneLongerString.c_str());
- EXPECT_EQ(PROPERTY_VALUE_MAX-1, len);
+ EXPECT_EQ(PROPERTY_VALUE_MAX - 1, len);
EXPECT_STREQ(maxLengthString.c_str(), mValue);
ResetValue();
}
+
+ // Try to use a default value that's the max length => get succeeds
+ {
+ ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
+
+ std::string maxLengthString = std::string(PROPERTY_VALUE_MAX - 1, 'b');
+
+ // Expect that the value matches maxLengthString
+ int len = property_get(PROPERTY_TEST_KEY, mValue, maxLengthString.c_str());
+ EXPECT_EQ(PROPERTY_VALUE_MAX - 1, len);
+ EXPECT_STREQ(maxLengthString.c_str(), mValue);
+ ResetValue();
+ }
+
+ // Try to use a default value of length one => get succeeds
+ {
+ ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
+
+ std::string oneCharString = std::string(1, 'c');
+
+ // Expect that the value matches oneCharString
+ int len = property_get(PROPERTY_TEST_KEY, mValue, oneCharString.c_str());
+ EXPECT_EQ(1, len);
+ EXPECT_STREQ(oneCharString.c_str(), mValue);
+ ResetValue();
+ }
+
+ // Try to use a default value of length zero => get succeeds
+ {
+ ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
+
+ std::string zeroCharString = std::string(0, 'd');
+
+ // Expect that the value matches oneCharString
+ int len = property_get(PROPERTY_TEST_KEY, mValue, zeroCharString.c_str());
+ EXPECT_EQ(0, len);
+ EXPECT_STREQ(zeroCharString.c_str(), mValue);
+ ResetValue();
+ }
+
+ // Try to use a NULL default value => get returns 0
+ {
+ ASSERT_OK(property_set(PROPERTY_TEST_KEY, ""));
+
+ // Expect a return value of 0
+ int len = property_get(PROPERTY_TEST_KEY, mValue, NULL);
+ EXPECT_EQ(0, len);
+ ResetValue();
+ }
}
TEST_F(PropertiesTest, GetBool) {
diff --git a/liblog/Android.bp b/liblog/Android.bp
index 2424dba..bbe7d79 100644
--- a/liblog/Android.bp
+++ b/liblog/Android.bp
@@ -21,6 +21,7 @@
"config_write.c",
"logger_name.c",
"logger_lock.c",
+ "log_ratelimit.cpp",
]
liblog_host_sources = [
"fake_log_device.c",
@@ -114,4 +115,5 @@
name: "liblog.ndk",
symbol_file: "liblog.map.txt",
first_version: "9",
+ unversioned_until: "current",
}
diff --git a/liblog/legacy-ndk-includes/log.h b/liblog/legacy-ndk-includes/log.h
index 0ea4c29..d40d6fa 100644
--- a/liblog/legacy-ndk-includes/log.h
+++ b/liblog/legacy-ndk-includes/log.h
@@ -98,7 +98,7 @@
*/
int __android_log_print(int prio, const char *tag, const char *fmt, ...)
#if defined(__GNUC__)
- __attribute__ ((format(printf, 3, 4)))
+ __attribute__((__format__(printf, 3, 4)))
#endif
;
@@ -116,8 +116,8 @@
void __android_log_assert(const char *cond, const char *tag,
const char *fmt, ...)
#if defined(__GNUC__)
- __attribute__ ((noreturn))
- __attribute__ ((format(printf, 3, 4)))
+ __attribute__((__noreturn__))
+ __attribute__((__format__(printf, 3, 4)))
#endif
;
diff --git a/liblog/log_ratelimit.cpp b/liblog/log_ratelimit.cpp
new file mode 100644
index 0000000..dfd4b8f
--- /dev/null
+++ b/liblog/log_ratelimit.cpp
@@ -0,0 +1,86 @@
+/*
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <errno.h>
+#include <pthread.h>
+#include <time.h>
+
+#include <log/log.h>
+
+#include "log_portability.h"
+
+// Global default if 'last' argument in __android_log_ratelimit is NULL
+static time_t g_last_clock;
+// Global above can not deal well with callers playing games with the
+// seconds argument, so we will also hold on to the maximum value
+// ever provided and use that to gain consistency. If the caller
+// provides their own 'last' argument, then they can play such games
+// of varying the 'seconds' argument to their pleasure.
+static time_t g_last_seconds;
+static const time_t last_seconds_default = 10;
+static const time_t last_seconds_max = 24 * 60 * 60; // maximum of a day
+static const time_t last_seconds_min = 2; // granularity
+// Lock to protect last_clock and last_seconds, but also 'last'
+// argument (not NULL) as supplied to __android_log_ratelimit.
+static pthread_mutex_t lock_ratelimit = PTHREAD_MUTEX_INITIALIZER;
+
+// if last is NULL, caller _must_ provide a consistent value for
+// seconds, otherwise we will take the maximum ever issued and hold
+// on to that. Preserves value of non-zero errno. Return -1 if we
+// can not acquire a lock, 0 if we are not to log a message, and 1
+// if we are ok to log a message. Caller should check > 0 for true.
+LIBLOG_ABI_PUBLIC int __android_log_ratelimit(time_t seconds, time_t* last) {
+ int save_errno = errno;
+
+ // Two reasons for trylock failure:
+ // 1. In a signal handler. Must prevent deadlock
+ // 2. Too many threads calling __android_log_ratelimit.
+ // Bonus to not print if they race here because that
+ // dovetails the goal of ratelimiting. One may print
+ // and the others will wait their turn ...
+ if (pthread_mutex_trylock(&lock_ratelimit)) {
+ if (save_errno) errno = save_errno;
+ return -1;
+ }
+
+ if (seconds == 0) {
+ seconds = last_seconds_default;
+ } else if (seconds < last_seconds_min) {
+ seconds = last_seconds_min;
+ } else if (seconds > last_seconds_max) {
+ seconds = last_seconds_max;
+ }
+
+ if (!last) {
+ if (g_last_seconds > seconds) {
+ seconds = g_last_seconds;
+ } else if (g_last_seconds < seconds) {
+ g_last_seconds = seconds;
+ }
+ last = &g_last_clock;
+ }
+
+ time_t now = time(NULL);
+ if ((now == (time_t)-1) || ((*last + seconds) > now)) {
+ pthread_mutex_unlock(&lock_ratelimit);
+ if (save_errno) errno = save_errno;
+ return 0;
+ }
+ *last = now;
+ pthread_mutex_unlock(&lock_ratelimit);
+ if (save_errno) errno = save_errno;
+ return 1;
+}
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index d07d774..25c4a63 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -214,6 +214,8 @@
}
return false;
}
+
+bool tested__android_log_close;
#endif
TEST(liblog, __android_log_btwrite__android_logger_list_read) {
@@ -228,22 +230,33 @@
// Check that we can close and reopen the logger
log_time ts(CLOCK_MONOTONIC);
ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
- bool pmsgActiveAfter__android_log_btwrite = isPmsgActive();
- bool logdwActiveAfter__android_log_btwrite = isLogdwActive();
- EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
- EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
+ bool pmsgActiveAfter__android_log_btwrite;
+ bool logdwActiveAfter__android_log_btwrite;
+ if (getuid() == AID_ROOT) {
+ tested__android_log_close = true;
+ pmsgActiveAfter__android_log_btwrite = isPmsgActive();
+ logdwActiveAfter__android_log_btwrite = isLogdwActive();
+ EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
+ EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
+ } else if (!tested__android_log_close) {
+ fprintf(stderr, "WARNING: can not test __android_log_close()\n");
+ }
__android_log_close();
- bool pmsgActiveAfter__android_log_close = isPmsgActive();
- bool logdwActiveAfter__android_log_close = isLogdwActive();
- EXPECT_FALSE(pmsgActiveAfter__android_log_close);
- EXPECT_FALSE(logdwActiveAfter__android_log_close);
+ if (getuid() == AID_ROOT) {
+ bool pmsgActiveAfter__android_log_close = isPmsgActive();
+ bool logdwActiveAfter__android_log_close = isLogdwActive();
+ EXPECT_FALSE(pmsgActiveAfter__android_log_close);
+ EXPECT_FALSE(logdwActiveAfter__android_log_close);
+ }
log_time ts1(CLOCK_MONOTONIC);
ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
- pmsgActiveAfter__android_log_btwrite = isPmsgActive();
- logdwActiveAfter__android_log_btwrite = isLogdwActive();
- EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
- EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
+ if (getuid() == AID_ROOT) {
+ pmsgActiveAfter__android_log_btwrite = isPmsgActive();
+ logdwActiveAfter__android_log_btwrite = isLogdwActive();
+ EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
+ EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
+ }
usleep(1000000);
int count = 0;
@@ -257,18 +270,19 @@
ASSERT_EQ(log_msg.entry.pid, pid);
- if ((log_msg.entry.len != (4 + 1 + 8))
+ if ((log_msg.entry.len != sizeof(android_log_event_long_t))
|| (log_msg.id() != LOG_ID_EVENTS)) {
continue;
}
- char *eventData = log_msg.msg();
+ android_log_event_long_t* eventData;
+ eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg());
- if (!eventData || (eventData[4] != EVENT_TYPE_LONG)) {
+ if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) {
continue;
}
- log_time tx(eventData + 4 + 1);
+ log_time tx(reinterpret_cast<char*>(&eventData->payload.data));
if (ts == tx) {
++count;
} else if (ts1 == tx) {
@@ -339,18 +353,20 @@
if ((log_msg.entry.sec < (ts.tv_sec - 1))
|| ((ts.tv_sec + 1) < log_msg.entry.sec)
- || ((size_t)log_msg.entry.len != (4 + 1 + 4 + length))
+ || ((size_t)log_msg.entry.len != (sizeof(android_log_event_string_t) +
+ length))
|| (log_msg.id() != LOG_ID_EVENTS)) {
continue;
}
- char *eventData = log_msg.msg();
+ android_log_event_string_t* eventData;
+ eventData = reinterpret_cast<android_log_event_string_t*>(log_msg.msg());
- if (!eventData || (eventData[4] != EVENT_TYPE_STRING)) {
+ if (!eventData || (eventData->type != EVENT_TYPE_STRING)) {
continue;
}
- size_t len = get4LE(eventData + 4 + 1);
+ size_t len = get4LE(reinterpret_cast<char*>(&eventData->length));
if (len == total) {
++count;
@@ -539,7 +555,6 @@
bool set_persist = false;
bool allow_security = false;
- setuid(AID_SYSTEM); // only one that can read security buffer
if (__android_log_security()) {
allow_security = true;
} else {
@@ -612,6 +627,8 @@
return;
}
+ setuid(AID_SYSTEM); // only one that can read security buffer
+
pid_t pid = getpid();
ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
@@ -636,18 +653,19 @@
ASSERT_EQ(log_msg.entry.pid, pid);
- if ((log_msg.entry.len != (4 + 1 + 8))
+ if ((log_msg.entry.len != sizeof(android_log_event_long_t))
|| (log_msg.id() != LOG_ID_SECURITY)) {
continue;
}
- char *eventData = log_msg.msg();
+ android_log_event_long_t* eventData;
+ eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg());
- if (!eventData || (eventData[4] != EVENT_TYPE_LONG)) {
+ if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) {
continue;
}
- log_time tx(eventData + 4 + 1);
+ log_time tx(reinterpret_cast<char*>(&eventData->payload.data));
if (ts == tx) {
++count;
}
@@ -772,25 +790,27 @@
ASSERT_EQ(log_msg.entry.pid, pid);
- if ((log_msg.entry.len != (4 + 1 + 8))
+ if ((log_msg.entry.len != sizeof(android_log_event_long_t))
|| (log_msg.id() != LOG_ID_EVENTS)) {
continue;
}
- char *eventData = log_msg.msg();
+ android_log_event_long_t* eventData;
+ eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg());
- if (!eventData || (eventData[4] != EVENT_TYPE_LONG)) {
+ if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) {
continue;
}
- unsigned long long l = eventData[4 + 1 + 0] & 0xFF;
- l |= (unsigned long long) (eventData[4 + 1 + 1] & 0xFF) << 8;
- l |= (unsigned long long) (eventData[4 + 1 + 2] & 0xFF) << 16;
- l |= (unsigned long long) (eventData[4 + 1 + 3] & 0xFF) << 24;
- l |= (unsigned long long) (eventData[4 + 1 + 4] & 0xFF) << 32;
- l |= (unsigned long long) (eventData[4 + 1 + 5] & 0xFF) << 40;
- l |= (unsigned long long) (eventData[4 + 1 + 6] & 0xFF) << 48;
- l |= (unsigned long long) (eventData[4 + 1 + 7] & 0xFF) << 56;
+ char* cp = reinterpret_cast<char*>(&eventData->payload.data);
+ unsigned long long l = cp[0] & 0xFF;
+ l |= (unsigned long long) (cp[1] & 0xFF) << 8;
+ l |= (unsigned long long) (cp[2] & 0xFF) << 16;
+ l |= (unsigned long long) (cp[3] & 0xFF) << 24;
+ l |= (unsigned long long) (cp[4] & 0xFF) << 32;
+ l |= (unsigned long long) (cp[5] & 0xFF) << 40;
+ l |= (unsigned long long) (cp[6] & 0xFF) << 48;
+ l |= (unsigned long long) (cp[7] & 0xFF) << 56;
if (l == v) {
++signals;
@@ -929,25 +949,27 @@
ASSERT_EQ(log_msg.entry.pid, pid);
- if ((log_msg.entry.len != (4 + 1 + 8))
+ if ((log_msg.entry.len != sizeof(android_log_event_long_t))
|| (log_msg.id() != LOG_ID_EVENTS)) {
continue;
}
- char *eventData = log_msg.msg();
+ android_log_event_long_t* eventData;
+ eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg());
- if (!eventData || (eventData[4] != EVENT_TYPE_LONG)) {
+ if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) {
continue;
}
- unsigned long long l = eventData[4 + 1 + 0] & 0xFF;
- l |= (unsigned long long) (eventData[4 + 1 + 1] & 0xFF) << 8;
- l |= (unsigned long long) (eventData[4 + 1 + 2] & 0xFF) << 16;
- l |= (unsigned long long) (eventData[4 + 1 + 3] & 0xFF) << 24;
- l |= (unsigned long long) (eventData[4 + 1 + 4] & 0xFF) << 32;
- l |= (unsigned long long) (eventData[4 + 1 + 5] & 0xFF) << 40;
- l |= (unsigned long long) (eventData[4 + 1 + 6] & 0xFF) << 48;
- l |= (unsigned long long) (eventData[4 + 1 + 7] & 0xFF) << 56;
+ char* cp = reinterpret_cast<char*>(&eventData->payload.data);
+ unsigned long long l = cp[0] & 0xFF;
+ l |= (unsigned long long) (cp[1] & 0xFF) << 8;
+ l |= (unsigned long long) (cp[2] & 0xFF) << 16;
+ l |= (unsigned long long) (cp[3] & 0xFF) << 24;
+ l |= (unsigned long long) (cp[4] & 0xFF) << 32;
+ l |= (unsigned long long) (cp[5] & 0xFF) << 40;
+ l |= (unsigned long long) (cp[6] & 0xFF) << 48;
+ l |= (unsigned long long) (cp[7] & 0xFF) << 56;
if (l == v) {
++signals;
@@ -1828,7 +1850,7 @@
int subtag_len = strlen(SUBTAG);
if (subtag_len > 32) subtag_len = 32;
ASSERT_EQ(subtag_len, get4LE(eventData));
- eventData +=4;
+ eventData += 4;
if (memcmp(SUBTAG, eventData, subtag_len)) {
continue;
@@ -2662,10 +2684,15 @@
TEST(liblog, __android_log_pmsg_file_write) {
#ifdef __ANDROID__
__android_log_close();
- bool pmsgActiveAfter__android_log_close = isPmsgActive();
- bool logdwActiveAfter__android_log_close = isLogdwActive();
- EXPECT_FALSE(pmsgActiveAfter__android_log_close);
- EXPECT_FALSE(logdwActiveAfter__android_log_close);
+ if (getuid() == AID_ROOT) {
+ tested__android_log_close = true;
+ bool pmsgActiveAfter__android_log_close = isPmsgActive();
+ bool logdwActiveAfter__android_log_close = isLogdwActive();
+ EXPECT_FALSE(pmsgActiveAfter__android_log_close);
+ EXPECT_FALSE(logdwActiveAfter__android_log_close);
+ } else if (!tested__android_log_close) {
+ fprintf(stderr, "WARNING: can not test __android_log_close()\n");
+ }
int return__android_log_pmsg_file_write = __android_log_pmsg_file_write(
LOG_ID_CRASH, ANDROID_LOG_VERBOSE,
__pmsg_file, max_payload_buf, sizeof(max_payload_buf));
@@ -2679,24 +2706,32 @@
"with liblog.__android_log_msg_file_read test\n",
__pmsg_file);
}
- bool pmsgActiveAfter__android_pmsg_file_write = isPmsgActive();
- bool logdwActiveAfter__android_pmsg_file_write = isLogdwActive();
- EXPECT_FALSE(pmsgActiveAfter__android_pmsg_file_write);
- EXPECT_FALSE(logdwActiveAfter__android_pmsg_file_write);
+ bool pmsgActiveAfter__android_pmsg_file_write;
+ bool logdwActiveAfter__android_pmsg_file_write;
+ if (getuid() == AID_ROOT) {
+ pmsgActiveAfter__android_pmsg_file_write = isPmsgActive();
+ logdwActiveAfter__android_pmsg_file_write = isLogdwActive();
+ EXPECT_FALSE(pmsgActiveAfter__android_pmsg_file_write);
+ EXPECT_FALSE(logdwActiveAfter__android_pmsg_file_write);
+ }
EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
"TEST__android_log_pmsg_file_write",
"main"));
- bool pmsgActiveAfter__android_log_buf_print = isPmsgActive();
- bool logdwActiveAfter__android_log_buf_print = isLogdwActive();
- EXPECT_TRUE(pmsgActiveAfter__android_log_buf_print);
- EXPECT_TRUE(logdwActiveAfter__android_log_buf_print);
+ if (getuid() == AID_ROOT) {
+ bool pmsgActiveAfter__android_log_buf_print = isPmsgActive();
+ bool logdwActiveAfter__android_log_buf_print = isLogdwActive();
+ EXPECT_TRUE(pmsgActiveAfter__android_log_buf_print);
+ EXPECT_TRUE(logdwActiveAfter__android_log_buf_print);
+ }
EXPECT_LT(0, __android_log_pmsg_file_write(
LOG_ID_CRASH, ANDROID_LOG_VERBOSE,
__pmsg_file, max_payload_buf, sizeof(max_payload_buf)));
- pmsgActiveAfter__android_pmsg_file_write = isPmsgActive();
- logdwActiveAfter__android_pmsg_file_write = isLogdwActive();
- EXPECT_TRUE(pmsgActiveAfter__android_pmsg_file_write);
- EXPECT_TRUE(logdwActiveAfter__android_pmsg_file_write);
+ if (getuid() == AID_ROOT) {
+ pmsgActiveAfter__android_pmsg_file_write = isPmsgActive();
+ logdwActiveAfter__android_pmsg_file_write = isLogdwActive();
+ EXPECT_TRUE(pmsgActiveAfter__android_pmsg_file_write);
+ EXPECT_TRUE(logdwActiveAfter__android_pmsg_file_write);
+ }
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
@@ -2731,19 +2766,26 @@
signaled = 0;
__android_log_close();
- bool pmsgActiveAfter__android_log_close = isPmsgActive();
- bool logdwActiveAfter__android_log_close = isLogdwActive();
- EXPECT_FALSE(pmsgActiveAfter__android_log_close);
- EXPECT_FALSE(logdwActiveAfter__android_log_close);
+ if (getuid() == AID_ROOT) {
+ tested__android_log_close = true;
+ bool pmsgActiveAfter__android_log_close = isPmsgActive();
+ bool logdwActiveAfter__android_log_close = isLogdwActive();
+ EXPECT_FALSE(pmsgActiveAfter__android_log_close);
+ EXPECT_FALSE(logdwActiveAfter__android_log_close);
+ } else if (!tested__android_log_close) {
+ fprintf(stderr, "WARNING: can not test __android_log_close()\n");
+ }
ssize_t ret = __android_log_pmsg_file_read(
LOG_ID_CRASH, ANDROID_LOG_VERBOSE,
__pmsg_file, __pmsg_fn, NULL);
- bool pmsgActiveAfter__android_log_pmsg_file_read = isPmsgActive();
- bool logdwActiveAfter__android_log_pmsg_file_read = isLogdwActive();
- EXPECT_FALSE(pmsgActiveAfter__android_log_pmsg_file_read);
- EXPECT_FALSE(logdwActiveAfter__android_log_pmsg_file_read);
+ if (getuid() == AID_ROOT) {
+ bool pmsgActiveAfter__android_log_pmsg_file_read = isPmsgActive();
+ bool logdwActiveAfter__android_log_pmsg_file_read = isLogdwActive();
+ EXPECT_FALSE(pmsgActiveAfter__android_log_pmsg_file_read);
+ EXPECT_FALSE(logdwActiveAfter__android_log_pmsg_file_read);
+ }
if (ret == -ENOENT) {
fprintf(stderr,
@@ -2870,3 +2912,35 @@
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
}
+
+TEST(liblog, __android_log_ratelimit) {
+ time_t state = 0;
+
+ errno = 42;
+ // Prime
+ __android_log_ratelimit(3, &state);
+ EXPECT_EQ(errno, 42);
+ // Check
+ EXPECT_FALSE(__android_log_ratelimit(3, &state));
+ sleep(1);
+ EXPECT_FALSE(__android_log_ratelimit(3, &state));
+ sleep(4);
+ EXPECT_TRUE(__android_log_ratelimit(3, &state));
+ sleep(5);
+ EXPECT_TRUE(__android_log_ratelimit(3, &state));
+
+ // API checks
+ IF_ALOG_RATELIMIT_LOCAL(3, &state) {
+ EXPECT_FALSE(0 != "IF_ALOG_RATELIMIT_LOCAL(3, &state)");
+ }
+
+ IF_ALOG_RATELIMIT() {
+ ;
+ } else {
+ EXPECT_TRUE(0 == "IF_ALOG_RATELIMIT()");
+ }
+ IF_ALOG_RATELIMIT() {
+ EXPECT_FALSE(0 != "IF_ALOG_RATELIMIT()");
+ }
+ // Do not test default seconds, to allow liblog to tune freely
+}
diff --git a/libnativeloader/Android.bp b/libnativeloader/Android.bp
index 9d33899..c1133fb 100644
--- a/libnativeloader/Android.bp
+++ b/libnativeloader/Android.bp
@@ -9,8 +9,8 @@
"liblog",
"libcutils",
"libnativebridge",
+ "libbase",
],
- static_libs: ["libbase"],
target: {
android: {
shared_libs: ["libdl"],
diff --git a/libziparchive/Android.bp b/libziparchive/Android.bp
index fce1378..44daf36 100644
--- a/libziparchive/Android.bp
+++ b/libziparchive/Android.bp
@@ -20,6 +20,7 @@
"-DZLIB_CONST",
"-Werror",
"-Wall",
+ "-D_FILE_OFFSET_BITS=64",
],
cppflags: [
"-Wold-style-cast",
@@ -56,11 +57,13 @@
name: "libziparchive",
host_supported: true,
defaults: ["libziparchive_defaults", "libziparchive_flags"],
- static_libs: ["libutils"],
shared_libs: ["liblog", "libbase"],
target: {
android: {
- static_libs: ["libz"],
+ shared_libs: ["libz", "libutils"],
+ },
+ host: {
+ static_libs: ["libutils"],
},
linux_bionic: {
static_libs: ["libz"],
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index 11cffe6..725d76e 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -451,11 +451,12 @@
"logcat -v brief -b radio,events,bogo,system,main -g 2>/dev/null"));
}
-static void caught_blocking(int /*signum*/)
+static void caught_blocking(int signum)
{
unsigned long long v = 0xDEADBEEFA55A0000ULL;
v += getpid() & 0xFFFF;
+ if (signum == 0) ++v;
LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
}
@@ -520,11 +521,12 @@
EXPECT_EQ(1, signals);
}
-static void caught_blocking_tail(int /*signum*/)
+static void caught_blocking_tail(int signum)
{
unsigned long long v = 0xA55ADEADBEEF0000ULL;
v += getpid() & 0xFFFF;
+ if (signum == 0) ++v;
LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
}
@@ -955,10 +957,11 @@
" -n 256 -r 1024"));
}
-static void caught_blocking_clear(int /*signum*/) {
+static void caught_blocking_clear(int signum) {
unsigned long long v = 0xDEADBEEFA55C0000ULL;
v += getpid() & 0xFFFF;
+ if (signum == 0) ++v;
LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
}
diff --git a/logd/Android.mk b/logd/Android.mk
index 7fe48d7..2da9782 100644
--- a/logd/Android.mk
+++ b/logd/Android.mk
@@ -40,6 +40,7 @@
# event_flag += $(call event_logtags,logd)
# so make sure we do not regret hard-coding it as follows:
event_flag := -DAUDITD_LOG_TAG=1003 -DCHATTY_LOG_TAG=1004
+event_flag += -DLIBLOG_LOG_TAG=1006
LOCAL_CFLAGS := -Werror $(event_flag)
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index aa05932..92d957f 100644
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -43,23 +43,70 @@
'>'
LogAudit::LogAudit(LogBuffer *buf, LogReader *reader, int fdDmesg) :
- SocketListener(getLogSocket(), false),
+ SocketListener(mSock = getLogSocket(), false),
logbuf(buf),
reader(reader),
fdDmesg(fdDmesg),
- initialized(false) {
+ main(__android_logger_property_get_bool("ro.logd.auditd.main",
+ BOOL_DEFAULT_TRUE)),
+ events(__android_logger_property_get_bool("ro.logd.auditd.events",
+ BOOL_DEFAULT_TRUE)),
+ initialized(false),
+ tooFast(false) {
static const char auditd_message[] = { KMSG_PRIORITY(LOG_INFO),
'l', 'o', 'g', 'd', '.', 'a', 'u', 'd', 'i', 't', 'd', ':',
' ', 's', 't', 'a', 'r', 't', '\n' };
write(fdDmesg, auditd_message, sizeof(auditd_message));
}
+void LogAudit::checkRateLimit() {
+
+ // trim list for AUDIT_RATE_LIMIT_BURST_DURATION of history
+ log_time oldest(AUDIT_RATE_LIMIT_BURST_DURATION, 0);
+ bucket.emplace(android_log_clockid());
+ oldest = bucket.back() - oldest;
+ while (bucket.front() < oldest) bucket.pop();
+
+ static const size_t upperThreshold =
+ ((AUDIT_RATE_LIMIT_BURST_DURATION *
+ (AUDIT_RATE_LIMIT_DEFAULT + AUDIT_RATE_LIMIT_MAX)) + 1) /
+ 2;
+ if (bucket.size() >= upperThreshold) {
+ // Hit peak, slow down source
+ if (!tooFast) {
+ tooFast = true;
+ audit_rate_limit(mSock, AUDIT_RATE_LIMIT_MAX);
+ }
+
+ // We do not need to hold on to the full set of timing data history,
+ // let's ensure it does not grow without bounds. This also ensures
+ // that std::dequeue underneath behaves almost like a ring buffer.
+ do {
+ bucket.pop();
+ } while (bucket.size() >= upperThreshold);
+ return;
+ }
+
+ if (!tooFast) return;
+
+ static const size_t lowerThreshold = AUDIT_RATE_LIMIT_BURST_DURATION *
+ AUDIT_RATE_LIMIT_MAX;
+
+ if (bucket.size() >= lowerThreshold) return;
+
+ tooFast = false;
+ // Went below max sustained rate, allow source to speed up
+ audit_rate_limit(mSock, AUDIT_RATE_LIMIT_DEFAULT);
+}
+
bool LogAudit::onDataAvailable(SocketClient *cli) {
if (!initialized) {
prctl(PR_SET_NAME, "logd.auditd");
initialized = true;
}
+ checkRateLimit();
+
struct audit_message rep;
rep.nlh.nlmsg_type = 0;
@@ -71,8 +118,7 @@
return false;
}
- logPrint("type=%d %.*s",
- rep.nlh.nlmsg_type, rep.nlh.nlmsg_len, rep.data);
+ logPrint("type=%d %.*s", rep.nlh.nlmsg_type, rep.nlh.nlmsg_len, rep.data);
return true;
}
@@ -94,6 +140,13 @@
}
char *cp;
+ // Work around kernels missing
+ // https://github.com/torvalds/linux/commit/b8f89caafeb55fba75b74bea25adc4e4cd91be67
+ // Such kernels improperly add newlines inside audit messages.
+ while ((cp = strchr(str, '\n'))) {
+ *cp = ' ';
+ }
+
while ((cp = strstr(str, " "))) {
memmove(cp, cp + 1, strlen(cp + 1) + 1);
}
@@ -172,6 +225,11 @@
}
}
+ if (!main && !events) {
+ free(str);
+ return 0;
+ }
+
pid_t pid = getpid();
pid_t tid = gettid();
uid_t uid = AID_LOGD;
@@ -222,7 +280,7 @@
bool notify = false;
- { // begin scope for event buffer
+ if (events) { // begin scope for event buffer
uint32_t buffer[(n + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
android_log_event_string_t *event
@@ -277,7 +335,7 @@
size_t e = strnlen(ecomm, LOGGER_ENTRY_MAX_PAYLOAD - b);
n = b + e + l + 2;
- { // begin scope for main buffer
+ if (main) { // begin scope for main buffer
char newstr[n];
*newstr = info ? ANDROID_LOG_INFO : ANDROID_LOG_WARN;
@@ -335,5 +393,6 @@
audit_close(fd);
fd = -1;
}
+ (void)audit_rate_limit(fd, AUDIT_RATE_LIMIT_DEFAULT);
return fd;
}
diff --git a/logd/LogAudit.h b/logd/LogAudit.h
index ab30e28..045d631 100644
--- a/logd/LogAudit.h
+++ b/logd/LogAudit.h
@@ -17,6 +17,8 @@
#ifndef _LOGD_LOG_AUDIT_H__
#define _LOGD_LOG_AUDIT_H__
+#include <queue>
+
#include <sysutils/SocketListener.h>
#include "LogBuffer.h"
@@ -26,9 +28,16 @@
class LogAudit : public SocketListener {
LogBuffer *logbuf;
LogReader *reader;
- int fdDmesg;
+ int fdDmesg; // fdDmesg >= 0 is functionally bool dmesg
+ bool main;
+ bool events;
bool initialized;
+ bool tooFast;
+ int mSock;
+ std::queue<log_time> bucket;
+ void checkRateLimit();
+
public:
LogAudit(LogBuffer *buf, LogReader *reader, int fdDmesg);
int log(char *buf, size_t len);
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index d476596..cc65d47 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -17,6 +17,7 @@
//#define DEBUG_CHECK_FOR_STALE_ENTRIES
#include <ctype.h>
+#include <endian.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
@@ -126,27 +127,41 @@
}
}
-static bool identical(LogBufferElement* elem, LogBufferElement* last) {
+enum match_type {
+ DIFFERENT,
+ SAME,
+ SAME_LIBLOG
+};
+
+static enum match_type identical(LogBufferElement* elem, LogBufferElement* last) {
// is it mostly identical?
-// if (!elem) return false;
+// if (!elem) return DIFFERENT;
unsigned short lenl = elem->getMsgLen();
- if (!lenl) return false;
-// if (!last) return false;
+ if (!lenl) return DIFFERENT;
+// if (!last) return DIFFERENT;
unsigned short lenr = last->getMsgLen();
- if (!lenr) return false;
-// if (elem->getLogId() != last->getLogId()) return false;
- if (elem->getUid() != last->getUid()) return false;
- if (elem->getPid() != last->getPid()) return false;
- if (elem->getTid() != last->getTid()) return false;
+ if (!lenr) return DIFFERENT;
+// if (elem->getLogId() != last->getLogId()) return DIFFERENT;
+ if (elem->getUid() != last->getUid()) return DIFFERENT;
+ if (elem->getPid() != last->getPid()) return DIFFERENT;
+ if (elem->getTid() != last->getTid()) return DIFFERENT;
// last is more than a minute old, stop squashing identical messages
if (elem->getRealTime().nsec() >
- (last->getRealTime().nsec() + 60 * NS_PER_SEC)) return false;
+ (last->getRealTime().nsec() + 60 * NS_PER_SEC)) return DIFFERENT;
// Identical message
const char* msgl = elem->getMsg();
const char* msgr = last->getMsg();
- if ((lenl == lenr) && !fastcmp<memcmp>(msgl, msgr, lenl)) return true;
+ if (lenl == lenr) {
+ if (!fastcmp<memcmp>(msgl, msgr, lenl)) return SAME;
+ // liblog tagged messages (content gets summed)
+ if ((elem->getLogId() == LOG_ID_EVENTS) &&
+ (lenl == sizeof(android_log_event_int_t)) &&
+ !fastcmp<memcmp>(msgl, msgr,
+ sizeof(android_log_event_int_t) - sizeof(int32_t)) &&
+ (elem->getTag() == LIBLOG_LOG_TAG)) return SAME_LIBLOG;
+ }
// audit message (except sequence number) identical?
static const char avc[] = "): avc: ";
@@ -154,20 +169,22 @@
if (last->isBinary()) {
if (fastcmp<memcmp>(msgl, msgr,
sizeof(android_log_event_string_t) -
- sizeof(int32_t))) return false;
+ sizeof(int32_t))) return DIFFERENT;
msgl += sizeof(android_log_event_string_t);
lenl -= sizeof(android_log_event_string_t);
msgr += sizeof(android_log_event_string_t);
lenr -= sizeof(android_log_event_string_t);
}
const char *avcl = android::strnstr(msgl, lenl, avc);
- if (!avcl) return false;
+ if (!avcl) return DIFFERENT;
lenl -= avcl - msgl;
const char *avcr = android::strnstr(msgr, lenr, avc);
- if (!avcr) return false;
+ if (!avcr) return DIFFERENT;
lenr -= avcr - msgr;
- if (lenl != lenr) return false;
- return !fastcmp<memcmp>(avcl + strlen(avc), avcr + strlen(avc), lenl);
+ if (lenl != lenr) return DIFFERENT;
+ if (fastcmp<memcmp>(avcl + strlen(avc),
+ avcr + strlen(avc), lenl)) return DIFFERENT;
+ return SAME;
}
int LogBuffer::log(log_id_t log_id, log_time realtime,
@@ -206,8 +223,113 @@
if (currentLast) {
LogBufferElement *dropped = droppedElements[log_id];
unsigned short count = dropped ? dropped->getDropped() : 0;
- if (identical(elem, currentLast)) {
+ //
+ // State Init
+ // incoming:
+ // dropped = NULL
+ // currentLast = NULL;
+ // elem = incoming message
+ // outgoing:
+ // dropped = NULL -> State 0
+ // currentLast = copy of elem
+ // log elem
+ // State 0
+ // incoming:
+ // count = 0
+ // dropped = NULL
+ // currentLast = copy of last message
+ // elem = incoming message
+ // outgoing: if match != DIFFERENT
+ // dropped = copy of first identical message -> State 1
+ // currentLast = reference to elem
+ // break: if match == DIFFERENT
+ // dropped = NULL -> State 0
+ // delete copy of last message (incoming currentLast)
+ // currentLast = copy of elem
+ // log elem
+ // State 1
+ // incoming:
+ // count = 0
+ // dropped = copy of first identical message
+ // currentLast = reference to last held-back incoming
+ // message
+ // elem = incoming message
+ // outgoing: if match == SAME
+ // delete copy of first identical message (dropped)
+ // dropped = reference to last held-back incoming
+ // message set to chatty count of 1 -> State 2
+ // currentLast = reference to elem
+ // outgoing: if match == SAME_LIBLOG
+ // dropped = copy of first identical message -> State 1
+ // take sum of currentLast and elem
+ // if sum overflows:
+ // log currentLast
+ // currentLast = reference to elem
+ // else
+ // delete currentLast
+ // currentLast = reference to elem, sum liblog.
+ // break: if match == DIFFERENT
+ // delete dropped
+ // dropped = NULL -> State 0
+ // log reference to last held-back (currentLast)
+ // currentLast = copy of elem
+ // log elem
+ // State 2
+ // incoming:
+ // count = chatty count
+ // dropped = chatty message holding count
+ // currentLast = reference to last held-back incoming
+ // message.
+ // dropped = chatty message holding count
+ // elem = incoming message
+ // outgoing: if match != DIFFERENT
+ // delete chatty message holding count
+ // dropped = reference to last held-back incoming
+ // message, set to chatty count + 1
+ // currentLast = reference to elem
+ // break: if match == DIFFERENT
+ // log dropped (chatty message)
+ // dropped = NULL -> State 0
+ // log reference to last held-back (currentLast)
+ // currentLast = copy of elem
+ // log elem
+ //
+ enum match_type match = identical(elem, currentLast);
+ if (match != DIFFERENT) {
if (dropped) {
+ // Sum up liblog tag messages?
+ if ((count == 0) /* at Pass 1 */ && (match == SAME_LIBLOG)) {
+ android_log_event_int_t* event =
+ reinterpret_cast<android_log_event_int_t*>(
+ const_cast<char*>(currentLast->getMsg()));
+ //
+ // To unit test, differentiate with something like:
+ // event->header.tag = htole32(CHATTY_LOG_TAG);
+ // here, then instead of delete currentLast below,
+ // log(currentLast) to see the incremental sums form.
+ //
+ uint32_t swab = event->payload.data;
+ unsigned long long total = htole32(swab);
+ event = reinterpret_cast<android_log_event_int_t*>(
+ const_cast<char*>(elem->getMsg()));
+ swab = event->payload.data;
+
+ lastLoggedElements[LOG_ID_EVENTS] = elem;
+ total += htole32(swab);
+ // check for overflow
+ if (total >= UINT32_MAX) {
+ log(currentLast);
+ pthread_mutex_unlock(&mLogElementsLock);
+ return len;
+ }
+ stats.add(currentLast);
+ stats.subtract(currentLast);
+ delete currentLast;
+ swab = total;
+ event->payload.data = htole32(swab);
+ pthread_mutex_unlock(&mLogElementsLock);
+ return len;
+ }
if (count == USHRT_MAX) {
log(dropped);
count = 1;
@@ -226,13 +348,15 @@
pthread_mutex_unlock(&mLogElementsLock);
return len;
}
- if (dropped) {
- log(dropped);
+ if (dropped) { // State 1 or 2
+ if (count) { // State 2
+ log(dropped); // report chatty
+ } else { // State 1
+ delete dropped;
+ }
droppedElements[log_id] = NULL;
- }
- if (count) {
- log(currentLast);
- } else {
+ log(currentLast); // report last message in the series
+ } else { // State 0
delete currentLast;
}
}
@@ -410,10 +534,9 @@
class LogBufferElementKey {
const union {
struct {
- uint16_t uid;
+ uint32_t uid;
uint16_t pid;
uint16_t tid;
- uint16_t padding;
} __packed;
uint64_t value;
} __packed;
@@ -422,8 +545,8 @@
LogBufferElementKey(uid_t uid, pid_t pid, pid_t tid):
uid(uid),
pid(pid),
- tid(tid),
- padding(0) {
+ tid(tid)
+ {
}
explicit LogBufferElementKey(uint64_t key):value(key) { }
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index ddbb64f..273150e 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -27,6 +27,8 @@
#include "LogStatistics.h"
+size_t LogStatistics::SizesTotal;
+
LogStatistics::LogStatistics() : enable(false) {
log_id_for_each(id) {
mSizes[id] = 0;
@@ -39,6 +41,8 @@
namespace android {
+size_t sizesTotal() { return LogStatistics::sizesTotal(); }
+
// caller must own and free character string
char *pidToName(pid_t pid) {
char *retval = NULL;
@@ -80,6 +84,7 @@
// elements, but we must recognize the manufactured dropped
// entry as not contributing to the lifetime totals.
mSizesTotal[log_id] += size;
+ SizesTotal += size;
++mElementsTotal[log_id];
}
@@ -304,7 +309,7 @@
if ((spaces <= 0) && pruned.length()) {
spaces = 1;
}
- if ((spaces > 0) && (pruned.length() != 0)) {
+ if (spaces > 0) {
change += android::base::StringPrintf("%*s", (int)spaces, "");
}
pruned = change + pruned;
diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h
index 8bf655b..7acef6d 100644
--- a/logd/LogStatistics.h
+++ b/logd/LogStatistics.h
@@ -17,11 +17,12 @@
#ifndef _LOGD_LOG_STATISTICS_H__
#define _LOGD_LOG_STATISTICS_H__
-#include <memory>
+#include <ctype.h>
#include <stdlib.h>
#include <sys/types.h>
#include <algorithm> // std::max
+#include <memory>
#include <string> // std::string
#include <unordered_map>
@@ -211,14 +212,16 @@
EntryBaseConstants::total_len
- name.length() - drop_len - 1);
- if (pruned.length()) {
- return android::base::StringPrintf("%s%*s%*s\n", name.c_str(),
- (int)size_len, size.c_str(),
- (int)drop_len, pruned.c_str());
- } else {
- return android::base::StringPrintf("%s%*s\n", name.c_str(),
- (int)size_len, size.c_str());
- }
+ std::string ret = android::base::StringPrintf("%s%*s%*s",
+ name.c_str(),
+ (int)size_len, size.c_str(),
+ (int)drop_len, pruned.c_str());
+ // remove any trailing spaces
+ size_t pos = ret.size();
+ size_t len = 0;
+ while (pos && isspace(ret[--pos])) ++len;
+ if (len) ret.erase(pos + 1, len);
+ return ret + "\n";
}
};
@@ -472,6 +475,7 @@
size_t mDroppedElements[LOG_ID_MAX];
size_t mSizesTotal[LOG_ID_MAX];
size_t mElementsTotal[LOG_ID_MAX];
+ static size_t SizesTotal;
bool enable;
// uid to size list
@@ -554,6 +558,7 @@
}
size_t sizesTotal(log_id_t id) const { return mSizesTotal[id]; }
size_t elementsTotal(log_id_t id) const { return mElementsTotal[id]; }
+ static size_t sizesTotal() { return SizesTotal; }
std::string format(uid_t uid, pid_t pid, unsigned int logMask) const;
diff --git a/logd/LogUtils.h b/logd/LogUtils.h
index d300a2a..70f24e4 100644
--- a/logd/LogUtils.h
+++ b/logd/LogUtils.h
@@ -33,7 +33,9 @@
char *uidToName(uid_t uid);
void prdebug(const char *fmt, ...) __printflike(1, 2);
-// Furnished in LogStatistics.cpp. Caller must own and free returned value
+// Furnished in LogStatistics.cpp.
+size_t sizesTotal();
+// Caller must own and free returned value
char *pidToName(pid_t pid);
char *tidToName(pid_t tid);
diff --git a/logd/README.property b/logd/README.property
index 791b1d5..de6767a 100644
--- a/logd/README.property
+++ b/logd/README.property
@@ -2,8 +2,9 @@
name type default description
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
+ro.logd.auditd.dmesg bool true selinux audit messages sent to dmesg.
+ro.logd.auditd.main bool true selinux audit messages sent to main.
+ro.logd.auditd.events bool true selinux audit messages sent to events.
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
diff --git a/logd/libaudit.c b/logd/libaudit.c
index d2b212e..216f1a1 100644
--- a/logd/libaudit.c
+++ b/logd/libaudit.c
@@ -149,7 +149,7 @@
return rc;
}
-int audit_setup(int fd, uint32_t pid)
+int audit_setup(int fd, pid_t pid)
{
int rc;
struct audit_message rep;
@@ -163,8 +163,7 @@
* and the the mask set to AUDIT_STATUS_PID
*/
status.pid = pid;
- status.mask = AUDIT_STATUS_PID | AUDIT_STATUS_RATE_LIMIT;
- status.rate_limit = 20; // audit entries per second
+ status.mask = AUDIT_STATUS_PID;
/* Let the kernel know this pid will be registering for audit events */
rc = audit_send(fd, AUDIT_SET, &status, sizeof(status));
@@ -187,6 +186,27 @@
return 0;
}
+int audit_rate_limit(int fd, unsigned rate_limit)
+{
+ int rc;
+ struct audit_message rep;
+ struct audit_status status;
+
+ memset(&status, 0, sizeof(status));
+
+ status.mask = AUDIT_STATUS_RATE_LIMIT;
+ status.rate_limit = rate_limit; /* audit entries per second */
+
+ rc = audit_send(fd, AUDIT_SET, &status, sizeof(status));
+ if (rc < 0) {
+ return rc;
+ }
+
+ audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0);
+
+ return 0;
+}
+
int audit_open()
{
return socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_AUDIT);
diff --git a/logd/libaudit.h b/logd/libaudit.h
index b9e330d..9865d43 100644
--- a/logd/libaudit.h
+++ b/logd/libaudit.h
@@ -33,7 +33,7 @@
#define MAX_AUDIT_MESSAGE_LENGTH 8970
typedef enum {
- GET_REPLY_BLOCKING=0,
+ GET_REPLY_BLOCKING = 0,
GET_REPLY_NONBLOCKING
} reply_t;
@@ -55,7 +55,7 @@
* A valid fd on success or < 0 on error with errno set.
* Returns the same errors as man 2 socket.
*/
-extern int audit_open(void);
+extern int audit_open(void);
/**
* Closes the fd returned from audit_open()
@@ -78,19 +78,36 @@
* @return
* This function returns 0 on success, else -errno.
*/
-extern int audit_get_reply(int fd, struct audit_message *rep, reply_t block,
- int peek);
+extern int audit_get_reply(int fd, struct audit_message *rep, reply_t block,
+ int peek);
/**
- * Sets a pid to recieve audit netlink events from the kernel
+ * Sets a pid to receive audit netlink events from the kernel
* @param fd
* The fd returned by a call to audit_open()
* @param pid
- * The pid whom to set as the reciever of audit messages
+ * The pid whom to set as the receiver of audit messages
* @return
* This function returns 0 on success, -errno on error.
*/
-extern int audit_setup(int fd, uint32_t pid);
+extern int audit_setup(int fd, pid_t pid);
+
+/**
+ * Sets the rate limit to receive audit netlink events from the kernel
+ * @param fd
+ * The fd returned by a call to audit_open()
+ * @param max_rate
+ * The cap of the maximum number of audit messages a second
+ * @return
+ * This function returns 0 on success, -errno on error.
+ */
+
+/* Guidelines to follow for dynamic rate_limit */
+#define AUDIT_RATE_LIMIT_DEFAULT 20 /* acceptable burst rate */
+#define AUDIT_RATE_LIMIT_BURST_DURATION 10 /* number of seconds of burst */
+#define AUDIT_RATE_LIMIT_MAX 5 /* acceptable sustained rate */
+
+extern int audit_rate_limit(int fd, unsigned rate_limit);
__END_DECLS
diff --git a/logd/main.cpp b/logd/main.cpp
index c3343d7..5878f15 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -451,9 +451,8 @@
pthread_attr_destroy(&attr);
}
- bool auditd = __android_logger_property_get_bool("logd.auditd",
- BOOL_DEFAULT_TRUE |
- BOOL_DEFAULT_FLAG_PERSIST);
+ bool auditd = __android_logger_property_get_bool("ro.logd.auditd",
+ BOOL_DEFAULT_TRUE);
if (drop_privs(klogd, auditd) != 0) {
return -1;
}
@@ -513,8 +512,8 @@
if (auditd) {
al = new LogAudit(logBuf, reader,
__android_logger_property_get_bool(
- "logd.auditd.dmesg",
- BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST)
+ "ro.logd.auditd.dmesg",
+ BOOL_DEFAULT_TRUE)
? fdDmesg
: -1);
}
diff --git a/logd/tests/Android.mk b/logd/tests/Android.mk
index 808087a..c053993 100644
--- a/logd/tests/Android.mk
+++ b/logd/tests/Android.mk
@@ -27,12 +27,15 @@
# Unit tests.
# -----------------------------------------------------------------------------
+event_flag := -DAUDITD_LOG_TAG=1003 -DCHATTY_LOG_TAG=1004
+
test_c_flags := \
-fstack-protector-all \
-g \
-Wall -Wextra \
-Werror \
-fno-builtin \
+ $(event_flag)
test_src_files := \
logd_test.cpp
@@ -43,6 +46,6 @@
LOCAL_MODULE := $(test_module_prefix)unit-tests
LOCAL_MODULE_TAGS := $(test_tags)
LOCAL_CFLAGS += $(test_c_flags)
-LOCAL_SHARED_LIBRARIES := libbase libcutils liblog
+LOCAL_SHARED_LIBRARIES := libbase libcutils liblog libselinux
LOCAL_SRC_FILES := $(test_src_files)
include $(BUILD_NATIVE_TEST)
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index 4e621e3..703c0fb 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -20,6 +20,9 @@
#include <signal.h>
#include <stdio.h>
#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include <string>
@@ -28,7 +31,12 @@
#include <cutils/sockets.h>
#include <gtest/gtest.h>
#include <log/log.h>
+#include <private/android_filesystem_config.h>
+#ifdef __ANDROID__
+#include <selinux/selinux.h>
+#endif
+#include "../libaudit.h" // pickup AUDIT_RATE_LIMIT_*
#include "../LogReader.h" // pickup LOGD_SNDTIMEO
/*
@@ -415,7 +423,13 @@
// Introduce some extreme spam for the worst UID filter
ASSERT_TRUE(NULL != (fp = popen(
- "/data/nativetest/liblog-benchmarks/liblog-benchmarks",
+ "/data/nativetest/liblog-benchmarks/liblog-benchmarks"
+ " BM_log_maximum_retry"
+ " BM_log_maximum"
+ " BM_clock_overhead"
+ " BM_log_overhead"
+ " BM_log_latency"
+ " BM_log_delay",
"r")));
char buffer[5120];
@@ -581,10 +595,12 @@
continue;
}
+ // alarm triggers at 50% of the --wrap time out
content_wrap = recv(fd, msg_wrap.buf, sizeof(msg_wrap), 0) > 0;
alarm_wrap = alarm(5);
+ // alarm triggers at 133% of the --wrap time out
content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0;
if (!content_timeout) { // make sure we hit dumpAndClose
content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0;
@@ -629,11 +645,24 @@
// b/26447386 refined behavior
TEST(logd, timeout) {
+ // b/33962045 This test interferes with other log reader tests that
+ // follow because of file descriptor socket persistence in the same
+ // process. So let's fork it to isolate it from giving us pain.
+
+ pid_t pid = fork();
+
+ if (pid) {
+ siginfo_t info = {};
+ ASSERT_EQ(0, TEMP_FAILURE_RETRY(waitid(P_PID, pid, &info, WEXITED)));
+ ASSERT_EQ(0, info.si_status);
+ return;
+ }
+
log_msg msg_wrap, msg_timeout;
bool content_wrap = false, content_timeout = false, written = false;
unsigned int alarm_wrap = 0, alarm_timeout = 0;
// A few tries to get it right just in case wrap kicks in due to
- // content providers being active during the test
+ // content providers being active during the test.
int i = 5;
log_time now(android_log_clockid());
now.tv_sec -= 30; // reach back a moderate period of time
@@ -642,7 +671,8 @@
int fd = socket_local_client("logdr",
ANDROID_SOCKET_NAMESPACE_RESERVED,
SOCK_SEQPACKET);
- ASSERT_LT(0, fd);
+ EXPECT_LT(0, fd);
+ if (fd < 0) _exit(fd);
std::string ask = android::base::StringPrintf(
"dumpAndClose lids=0,1,2,3,4,5 timeout=6 start=%"
@@ -665,10 +695,12 @@
continue;
}
+ // alarm triggers at 50% of the --wrap time out
content_wrap = recv(fd, msg_wrap.buf, sizeof(msg_wrap), 0) > 0;
alarm_wrap = alarm(5);
+ // alarm triggers at 133% of the --wrap time out
content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0;
if (!content_timeout) { // make sure we hit dumpAndClose
content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0;
@@ -692,6 +724,7 @@
if (content_timeout) {
log_time msg(msg_timeout.entry.sec, msg_timeout.entry.nsec);
EXPECT_FALSE(msg < now);
+ if (msg < now) _exit(-1);
if (msg > now) {
now = msg;
now.tv_sec += 30;
@@ -724,6 +757,8 @@
EXPECT_EQ(0U, alarm_wrap);
EXPECT_TRUE(content_timeout);
EXPECT_NE(0U, alarm_timeout);
+
+ _exit(!written + content_wrap + alarm_wrap + !content_timeout + !alarm_timeout);
}
// b/27242723 confirmed fixed
@@ -787,12 +822,11 @@
void __android_log_btwrite_multiple__helper(int count) {
log_time ts(CLOCK_MONOTONIC);
- struct logger_list *logger_list;
- ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
- LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, 0)));
-
log_time ts1(CLOCK_MONOTONIC);
+ // We fork to create a unique pid for the submitted log messages
+ // so that we do not collide with the other _multiple_ tests.
+
pid_t pid = fork();
if (pid == 0) {
@@ -807,8 +841,13 @@
_exit(0);
}
- siginfo_t info{};
+ siginfo_t info = {};
ASSERT_EQ(0, TEMP_FAILURE_RETRY(waitid(P_PID, pid, &info, WEXITED)));
+ ASSERT_EQ(0, info.si_status);
+
+ struct logger_list *logger_list;
+ ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
+ LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, pid)));
int expected_count = (count < 2) ? count : 2;
int expected_chatty_count = (count <= 2) ? 0 : 1;
@@ -842,10 +881,10 @@
++second_count;
}
} else if (eventData[4] == EVENT_TYPE_STRING) {
- // chatty
- if (tag != 1004) continue;
+ if (tag != CHATTY_LOG_TAG) continue;
++chatty_count;
// int len = get4LE(eventData + 4 + 1);
+ log_msg.buf[LOGGER_ENTRY_MAX_LEN] = '\0';
const char *cp = strstr(eventData + 4 + 1 + 4, " expire ");
if (!cp) continue;
unsigned val = 0;
@@ -854,12 +893,12 @@
}
}
+ android_logger_list_close(logger_list);
+
EXPECT_EQ(expected_count, count);
EXPECT_EQ(1, second_count);
EXPECT_EQ(expected_chatty_count, chatty_count);
EXPECT_EQ(expected_expire_count, expire_count);
-
- android_logger_list_close(logger_list);
}
TEST(logd, multiple_test_1) {
@@ -877,3 +916,154 @@
TEST(logd, multiple_test_10) {
__android_log_btwrite_multiple__helper(10);
}
+
+#ifdef __ANDROID__
+// returns violating pid
+static pid_t sepolicy_rate(unsigned rate, unsigned num) {
+ pid_t pid = fork();
+
+ if (pid) {
+ siginfo_t info = {};
+ if (TEMP_FAILURE_RETRY(waitid(P_PID, pid, &info, WEXITED))) return 0;
+ if (info.si_status) return 0;
+ return pid;
+ }
+
+ // We may have DAC, but let's not have MAC
+ if (setcon("u:object_r:shell:s0") < 0) {
+ int save_errno = errno;
+ security_context_t context;
+ getcon(&context);
+ fprintf(stderr, "setcon(\"u:r:shell:s0\") failed @\"%s\" %s\n",
+ context, strerror(save_errno));
+ freecon(context);
+ _exit(-1);
+ // NOTREACHED
+ return 0;
+ }
+
+ // Requests dac_read_search, falls back to request dac_override
+ rate /= 2;
+ useconds_t usec;
+ if (rate == 0) {
+ rate = 1;
+ usec = 2000000;
+ } else {
+ usec = (1000000 + (rate / 2)) / rate;
+ }
+ num = (num + 1) / 2;
+
+ if (usec < 2) usec = 2;
+
+ while (num > 0) {
+ if (access(android::base::StringPrintf(
+ "/data/misc/logd/cannot_access_directory_%u",
+ num).c_str(),
+ F_OK) == 0) {
+ _exit(-1);
+ // NOTREACHED
+ return 0;
+ }
+ usleep(usec);
+ --num;
+ }
+ _exit(0);
+ // NOTREACHED
+ return 0;
+}
+
+static int count_avc(pid_t pid) {
+ int count = 0;
+
+ if (pid == 0) return count;
+
+ struct logger_list *logger_list;
+ if (!(logger_list = android_logger_list_open(LOG_ID_EVENTS,
+ ANDROID_LOG_RDONLY |
+ ANDROID_LOG_NONBLOCK,
+ 0,
+ pid))) return count;
+ for (;;) {
+ log_msg log_msg;
+
+ if (android_logger_list_read(logger_list, &log_msg) <= 0) break;
+
+ if ((log_msg.entry.pid != pid) ||
+ (log_msg.entry.len < (4 + 1 + 8)) ||
+ (log_msg.id() != LOG_ID_EVENTS)) continue;
+
+ char *eventData = log_msg.msg();
+ if (!eventData) continue;
+
+ uint32_t tag = get4LE(eventData);
+ if (tag != AUDITD_LOG_TAG) continue;
+
+ if (eventData[4] != EVENT_TYPE_STRING) continue;
+
+ // int len = get4LE(eventData + 4 + 1);
+ log_msg.buf[LOGGER_ENTRY_MAX_LEN] = '\0';
+ const char *cp = strstr(eventData + 4 + 1 + 4, "): avc: ");
+ if (!cp) continue;
+
+ ++count;
+ }
+
+ android_logger_list_close(logger_list);
+
+ return count;
+}
+#endif
+
+TEST(logd, sepolicy_rate_limiter_maximum) {
+#ifdef __ANDROID__
+ static const int rate = AUDIT_RATE_LIMIT_MAX;
+ static const int duration = 2;
+ // Two seconds of a liveable sustained rate
+ EXPECT_EQ(rate * duration, count_avc(sepolicy_rate(rate, rate * duration)));
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
+}
+
+TEST(logd, sepolicy_rate_limiter_sub_burst) {
+#ifdef __ANDROID__
+ // maximum period below half way between sustainable and burst rate.
+ static const int threshold = ((AUDIT_RATE_LIMIT_BURST_DURATION *
+ (AUDIT_RATE_LIMIT_DEFAULT +
+ AUDIT_RATE_LIMIT_MAX)) +
+ 1) / 2;
+ static const int rate = (threshold / AUDIT_RATE_LIMIT_BURST_DURATION) - 1;
+ static const int duration = AUDIT_RATE_LIMIT_BURST_DURATION;
+ EXPECT_EQ(rate * duration, count_avc(sepolicy_rate(rate, rate * duration)));
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
+}
+
+TEST(logd, sepolicy_rate_limiter_spam) {
+#ifdef __ANDROID__
+ // maximum period of double the maximum burst rate
+ static const int threshold = ((AUDIT_RATE_LIMIT_BURST_DURATION *
+ (AUDIT_RATE_LIMIT_DEFAULT +
+ AUDIT_RATE_LIMIT_MAX)) +
+ 1) / 2;
+ static const int rate = AUDIT_RATE_LIMIT_DEFAULT * 2;
+ static const int duration = threshold / AUDIT_RATE_LIMIT_DEFAULT;
+ EXPECT_GE(((AUDIT_RATE_LIMIT_DEFAULT * duration) * 115) /
+ 100, // +15% margin
+ count_avc(sepolicy_rate(rate, rate * duration)));
+ // give logd another 3 seconds to react to the burst before checking
+ sepolicy_rate(rate, rate * 3);
+ // maximum period at double the maximum burst rate (spam filter kicked in)
+ EXPECT_GE(((AUDIT_RATE_LIMIT_MAX * AUDIT_RATE_LIMIT_BURST_DURATION) * 130) /
+ 100, // +30% margin
+ count_avc(sepolicy_rate(rate,
+ rate * AUDIT_RATE_LIMIT_BURST_DURATION)));
+ // cool down, and check unspammy rate still works
+ sleep(2);
+ EXPECT_LE(AUDIT_RATE_LIMIT_BURST_DURATION - 1, // allow _one_ to be lost
+ count_avc(sepolicy_rate(1, AUDIT_RATE_LIMIT_BURST_DURATION)));
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
+}
diff --git a/rootdir/etc/public.libraries.android.txt b/rootdir/etc/public.libraries.android.txt
index e6c94ff..2fe90d9 100644
--- a/rootdir/etc/public.libraries.android.txt
+++ b/rootdir/etc/public.libraries.android.txt
@@ -12,6 +12,7 @@
liblog.so
libmediandk.so
libm.so
+liboboe.so
libOpenMAXAL.so
libOpenSLES.so
libRS.so
diff --git a/rootdir/etc/public.libraries.wear.txt b/rootdir/etc/public.libraries.wear.txt
index 292730a..b35d463 100644
--- a/rootdir/etc/public.libraries.wear.txt
+++ b/rootdir/etc/public.libraries.wear.txt
@@ -12,6 +12,7 @@
liblog.so
libmediandk.so
libm.so
+liboboe.so
libOpenMAXAL.so
libOpenSLES.so
libRS.so
diff --git a/rootdir/init.zygote64_32.rc b/rootdir/init.zygote64_32.rc
index 66e7750..7084355 100644
--- a/rootdir/init.zygote64_32.rc
+++ b/rootdir/init.zygote64_32.rc
@@ -13,7 +13,7 @@
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
-service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
+service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary --enable-lazy-preload
class main
priority -20
user root
diff --git a/storaged/EventLogTags.logtags b/storaged/EventLogTags.logtags
index 2e25d4a..ee92dd1 100644
--- a/storaged/EventLogTags.logtags
+++ b/storaged/EventLogTags.logtags
@@ -36,4 +36,4 @@
2732 storaged_disk_stats (type|3),(start_time|2|3),(end_time|2|3),(read_ios|2|1),(read_merges|2|1),(read_sectors|2|1),(read_ticks|2|3),(write_ios|2|1),(write_merges|2|1),(write_sectors|2|1),(write_ticks|2|3),(o_in_flight|2|1),(io_ticks|2|3),(io_in_queue|2|1)
-2733 storaged_emmc_info (mmc_ver|3),(eol|1),(lifetime_a|1),(lifetime_b|1)
\ No newline at end of file
+2733 storaged_emmc_info (mmc_ver|3),(eol|1),(lifetime_a|1),(lifetime_b|1)
diff --git a/storaged/main.cpp b/storaged/main.cpp
index bd1166a..31ada68 100644
--- a/storaged/main.cpp
+++ b/storaged/main.cpp
@@ -290,9 +290,8 @@
sort_running_tasks_info(res);
log_console_running_tasks_info(res);
-
return 0;
}
return 0;
-}
\ No newline at end of file
+}
diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp
index 1402208..7b0c3ad 100644
--- a/storaged/storaged.cpp
+++ b/storaged/storaged.cpp
@@ -20,7 +20,6 @@
#include <time.h>
#include <unistd.h>
-
#include <android-base/logging.h>
#include <storaged.h>
@@ -42,12 +41,12 @@
if (parse_disk_stats(DISK_STATS_PATH, &curr)) {
struct disk_stats inc = get_inc_disk_stats(&mPrevious, &curr);
add_disk_stats(&inc, &mAccumulate);
- #ifdef DEBUG
+#ifdef DEBUG
// log_kernel_disk_stats(&mPrevious, "prev stats");
// log_kernel_disk_stats(&curr, "curr stats");
// log_kernel_disk_stats(&inc, "inc stats");
// log_kernel_disk_stats(&mAccumulate, "accumulated stats");
- #endif
+#endif
mPrevious = curr;
}
}
@@ -103,10 +102,10 @@
if (UNLIKELY(detect(&perf))) {
mStall = true;
add_disk_stats(&inc, &mAccumulate);
- #ifdef DEBUG
+#ifdef DEBUG
log_kernel_disk_perf(&mMean, "stalled_mean");
log_kernel_disk_perf(&mStd, "stalled_std");
- #endif
+#endif
} else {
if (mStall) {
log_kernel_disk_stats(&mAccumulate, "stalled");
@@ -208,4 +207,4 @@
}
mTimer += mConfig.periodic_chores_interval_unit;
-}
\ No newline at end of file
+}
diff --git a/storaged/storaged_utils.cpp b/storaged/storaged_utils.cpp
index 9c0b625..5e04888 100644
--- a/storaged/storaged_utils.cpp
+++ b/storaged/storaged_utils.cpp
@@ -16,15 +16,15 @@
#define LOG_TAG "storaged"
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <linux/time.h>
-
#include <dirent.h>
-#include <stdio.h>
+#include <fcntl.h>
+#include <linux/time.h>
#include <stdint.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
#include <unistd.h>
#include <sstream>
@@ -32,18 +32,16 @@
#include <unordered_map>
#include <android-base/file.h>
+#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
-#include <android-base/logging.h>
+#include <cutils/klog.h>
#include <log/log.h>
#include <log/log_event_list.h>
-#include <cutils/klog.h>
#include <storaged.h>
#include <storaged_utils.h>
-#include <time.h>
-
#define SECTOR_SIZE ( 512 )
#define SEC_TO_MSEC ( 1000 )
#define MSEC_TO_USEC ( 1000 )
@@ -416,7 +414,7 @@
}
}
}
- { // update critical area
+ { // update critical area
// this is really fast!
std::unique_ptr<lock_t> lock(new lock_t(&mSem));
mRunning = tasks_latest;
diff --git a/storaged/tests/storaged_test.cpp b/storaged/tests/storaged_test.cpp
index 4ca9839..99b21ac 100644
--- a/storaged/tests/storaged_test.cpp
+++ b/storaged/tests/storaged_test.cpp
@@ -23,7 +23,6 @@
#include <unistd.h>
#include <gtest/gtest.h>
-//#include <private/android_logger.h>
#include <storaged.h> // data structures
#include <storaged_utils.h> // functions to test