Merge "Enable clang for init, after fix of global .mk files."
diff --git a/adb/commandline.c b/adb/commandline.c
index f345787..44541b7 100644
--- a/adb/commandline.c
+++ b/adb/commandline.c
@@ -1578,7 +1578,7 @@
{
if (argc != 3)
return usage();
- const char* command = no_rebind ? "forward:norebind:" : "forward";
+ const char* command = no_rebind ? "forward:norebind" : "forward";
snprintf(buf, sizeof buf, "%s:%s:%s;%s", host_prefix, command, argv[1], argv[2]);
}
diff --git a/fastbootd/Android.mk b/fastbootd/Android.mk
index 1e69e7a..c74f906 100644
--- a/fastbootd/Android.mk
+++ b/fastbootd/Android.mk
@@ -37,7 +37,6 @@
LOCAL_MODULE := fastbootd
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter -Wno-deprecated-declarations -DFLASH_CERT
-LOCAL_LDFLAGS := -ldl
LOCAL_STATIC_LIBRARIES := \
libc \
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index 40878c1..d6edd29 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -28,6 +28,9 @@
#include <libgen.h>
#include <time.h>
#include <sys/swap.h>
+#include <dirent.h>
+#include <ext4.h>
+#include <ext4_sb.h>
#include <linux/loop.h>
#include <private/android_filesystem_config.h>
@@ -325,6 +328,83 @@
return 0;
}
+static int translate_ext_labels(struct fstab_rec *rec)
+{
+ DIR *blockdir = NULL;
+ struct dirent *ent;
+ char *label;
+ size_t label_len;
+ int ret = -1;
+
+ if (strncmp(rec->blk_device, "LABEL=", 6))
+ return 0;
+
+ label = rec->blk_device + 6;
+ label_len = strlen(label);
+
+ if (label_len > 16) {
+ ERROR("FS label is longer than allowed by filesystem\n");
+ goto out;
+ }
+
+
+ blockdir = opendir("/dev/block");
+ if (!blockdir) {
+ ERROR("couldn't open /dev/block\n");
+ goto out;
+ }
+
+ while ((ent = readdir(blockdir))) {
+ int fd;
+ char super_buf[1024];
+ struct ext4_super_block *sb;
+
+ if (ent->d_type != DT_BLK)
+ continue;
+
+ fd = openat(dirfd(blockdir), ent->d_name, O_RDONLY);
+ if (fd < 0) {
+ ERROR("Cannot open block device /dev/block/%s\n", ent->d_name);
+ goto out;
+ }
+
+ if (TEMP_FAILURE_RETRY(lseek(fd, 1024, SEEK_SET)) < 0 ||
+ TEMP_FAILURE_RETRY(read(fd, super_buf, 1024)) != 1024) {
+ /* Probably a loopback device or something else without a readable
+ * superblock.
+ */
+ close(fd);
+ continue;
+ }
+
+ sb = (struct ext4_super_block *)super_buf;
+ if (sb->s_magic != EXT4_SUPER_MAGIC) {
+ INFO("/dev/block/%s not ext{234}\n", ent->d_name);
+ continue;
+ }
+
+ if (!strncmp(label, sb->s_volume_name, label_len)) {
+ char *new_blk_device;
+
+ if (asprintf(&new_blk_device, "/dev/block/%s", ent->d_name) < 0) {
+ ERROR("Could not allocate block device string\n");
+ goto out;
+ }
+
+ INFO("resolved label %s to %s\n", rec->blk_device, new_blk_device);
+
+ free(rec->blk_device);
+ rec->blk_device = new_blk_device;
+ ret = 0;
+ break;
+ }
+ }
+
+out:
+ closedir(blockdir);
+ return ret;
+}
+
/* When multiple fstab records share the same mount_point, it will
* try to mount each one in turn, and ignore any duplicates after a
* first successful mount.
@@ -356,6 +436,17 @@
continue;
}
+ /* Translate LABEL= file system labels into block devices */
+ if (!strcmp(fstab->recs[i].fs_type, "ext2") ||
+ !strcmp(fstab->recs[i].fs_type, "ext3") ||
+ !strcmp(fstab->recs[i].fs_type, "ext4")) {
+ int tret = translate_ext_labels(&fstab->recs[i]);
+ if (tret < 0) {
+ ERROR("Could not translate label to block device\n");
+ continue;
+ }
+ }
+
if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
}
diff --git a/include/private/android_logger.h b/include/private/android_logger.h
new file mode 100644
index 0000000..cc7ba30
--- /dev/null
+++ b/include/private/android_logger.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+/* This file is used to define the internal protocol for the Android Logger */
+
+#ifndef _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_LOGGER_H_
+#define _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_LOGGER_H_
+
+#include <stdint.h>
+
+#include <log/log.h>
+#include <log/log_read.h>
+
+#define LOGGER_MAGIC 'l'
+
+/* Header Structure to pstore */
+typedef struct __attribute__((__packed__)) {
+ uint8_t magic;
+ uint16_t len;
+ uint16_t uid;
+ uint16_t pid;
+} android_pmsg_log_header_t;
+
+/* Header Structure to logd, and second header for pstore */
+typedef struct __attribute__((__packed__)) {
+ typeof_log_id_t id;
+ uint16_t tid;
+ log_time realtime;
+} android_log_header_t;
+
+#endif
diff --git a/liblog/logd_write.c b/liblog/logd_write.c
index b2668ce..1e9b591 100644
--- a/liblog/logd_write.c
+++ b/liblog/logd_write.c
@@ -39,6 +39,7 @@
#include <log/logger.h>
#include <log/log_read.h>
#include <private/android_filesystem_config.h>
+#include <private/android_logger.h>
#define LOG_BUF_SIZE 1024
@@ -61,6 +62,7 @@
static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1, -1 };
#else
static int logd_fd = -1;
+static int pstore_fd = -1;
#endif
/*
@@ -109,6 +111,12 @@
logd_fd = -1;
close(i);
}
+ if (pstore_fd >= 0) {
+ i = pstore_fd;
+ pstore_fd = -1;
+ close(i);
+ }
+ pstore_fd = open("/dev/pmsg0", O_WRONLY);
i = socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (i < 0) {
@@ -155,37 +163,27 @@
}
} while (ret == -EINTR);
#else
- static const unsigned header_length = 3;
+ static const unsigned header_length = 2;
struct iovec newVec[nr + header_length];
- typeof_log_id_t log_id_buf;
- uint16_t tid;
+ android_log_header_t header;
+ android_pmsg_log_header_t pmsg_header;
struct timespec ts;
- log_time realtime_ts;
size_t i, payload_size;
static uid_t last_uid = AID_ROOT; /* logd *always* starts up as AID_ROOT */
+ static pid_t last_pid = (pid_t) -1;
if (last_uid == AID_ROOT) { /* have we called to get the UID yet? */
last_uid = getuid();
}
- if (last_uid == AID_LOGD) { /* logd, after initialization and priv drop */
- /*
- * ignore log messages we send to ourself (logd).
- * Such log messages are often generated by libraries we depend on
- * which use standard Android logging.
- */
- return 0;
+ if (last_pid == (pid_t) -1) {
+ last_pid = getpid();
}
-
- if (logd_fd < 0) {
- return -EBADF;
- }
-
/*
* struct {
- * // what we provide
- * typeof_log_id_t log_id;
- * u16 tid;
- * log_time realtime;
+ * // whate we provire to pstore
+ * android_pmsg_log_header_t pmsg_header;
+ * // what we provide to socket
+ * android_log_header_t header;
* // caller provides
* union {
* struct {
@@ -201,18 +199,21 @@
*/
clock_gettime(CLOCK_REALTIME, &ts);
- realtime_ts.tv_sec = ts.tv_sec;
- realtime_ts.tv_nsec = ts.tv_nsec;
- log_id_buf = log_id;
- tid = gettid();
+ pmsg_header.magic = LOGGER_MAGIC;
+ pmsg_header.len = sizeof(pmsg_header) + sizeof(header);
+ pmsg_header.uid = last_uid;
+ pmsg_header.pid = last_pid;
- newVec[0].iov_base = (unsigned char *) &log_id_buf;
- newVec[0].iov_len = sizeof_log_id_t;
- newVec[1].iov_base = (unsigned char *) &tid;
- newVec[1].iov_len = sizeof(tid);
- newVec[2].iov_base = (unsigned char *) &realtime_ts;
- newVec[2].iov_len = sizeof(log_time);
+ header.id = log_id;
+ header.tid = gettid();
+ header.realtime.tv_sec = ts.tv_sec;
+ header.realtime.tv_nsec = ts.tv_nsec;
+
+ newVec[0].iov_base = (unsigned char *) &pmsg_header;
+ newVec[0].iov_len = sizeof(pmsg_header);
+ newVec[1].iov_base = (unsigned char *) &header;
+ newVec[1].iov_len = sizeof(header);
for (payload_size = 0, i = header_length; i < nr + header_length; i++) {
newVec[i].iov_base = vec[i - header_length].iov_base;
@@ -223,17 +224,38 @@
if (newVec[i].iov_len) {
++i;
}
+ payload_size = LOGGER_ENTRY_MAX_PAYLOAD;
break;
}
}
+ pmsg_header.len += payload_size;
+
+ if (pstore_fd >= 0) {
+ TEMP_FAILURE_RETRY(writev(pstore_fd, newVec, i));
+ }
+
+ if (last_uid == AID_LOGD) { /* logd, after initialization and priv drop */
+ /*
+ * ignore log messages we send to ourself (logd).
+ * Such log messages are often generated by libraries we depend on
+ * which use standard Android logging.
+ */
+ return 0;
+ }
+
+ if (logd_fd < 0) {
+ return -EBADF;
+ }
/*
* The write below could be lost, but will never block.
*
+ * To logd, we drop the pmsg_header
+ *
* ENOTCONN occurs if logd dies.
* EAGAIN occurs if logd is overloaded.
*/
- ret = writev(logd_fd, newVec, i);
+ ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, i - 1));
if (ret < 0) {
ret = -errno;
if (ret == -ENOTCONN) {
@@ -249,15 +271,15 @@
return ret;
}
- ret = writev(logd_fd, newVec, nr + header_length);
+ ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, i - 1));
if (ret < 0) {
ret = -errno;
}
}
}
- if (ret > (ssize_t)(sizeof_log_id_t + sizeof(tid) + sizeof(log_time))) {
- ret -= sizeof_log_id_t + sizeof(tid) + sizeof(log_time);
+ if (ret > (ssize_t)sizeof(header)) {
+ ret -= sizeof(header);
}
#endif
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 6307bed..3d0b38f 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -445,7 +445,24 @@
uid_t uid = reader->getUid();
pthread_mutex_lock(&mLogElementsLock);
- for (it = mLogElements.begin(); it != mLogElements.end(); ++it) {
+
+ if (start == LogTimeEntry::EPOCH) {
+ // client wants to start from the beginning
+ it = mLogElements.begin();
+ } else {
+ // Client wants to start from some specified time. Chances are
+ // we are better off starting from the end of the time sorted list.
+ for (it = mLogElements.end(); it != mLogElements.begin(); /* do nothing */) {
+ --it;
+ LogBufferElement *element = *it;
+ if (element->getMonotonicTime() <= start) {
+ it++;
+ break;
+ }
+ }
+ }
+
+ for (; it != mLogElements.end(); ++it) {
LogBufferElement *element = *it;
if (!privileged && (element->getUid() != uid)) {
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp
index 8186cea..fc9e30f 100644
--- a/logd/LogListener.cpp
+++ b/logd/LogListener.cpp
@@ -23,6 +23,7 @@
#include <cutils/sockets.h>
#include <log/logger.h>
+#include <private/android_logger.h>
#include "LogListener.h"
@@ -54,7 +55,7 @@
int socket = cli->getSocket();
ssize_t n = recvmsg(socket, &hdr, 0);
- if (n <= (ssize_t)(sizeof_log_id_t + sizeof(uint16_t) + sizeof(log_time))) {
+ if (n <= (ssize_t)(sizeof(android_log_header_t))) {
return false;
}
@@ -81,28 +82,19 @@
return false;
}
- // First log element is always log_id.
- log_id_t log_id = (log_id_t) *((typeof_log_id_t *) buffer);
- if (log_id < 0 || log_id >= LOG_ID_MAX) {
+ android_log_header_t *header = reinterpret_cast<android_log_header_t *>(buffer);
+ if (/* header->id < LOG_ID_MIN || */ header->id >= LOG_ID_MAX) {
return false;
}
- char *msg = ((char *)buffer) + sizeof_log_id_t;
- n -= sizeof_log_id_t;
- // second element is the thread id of the caller
- pid_t tid = (pid_t) *((uint16_t *) msg);
- msg += sizeof(uint16_t);
- n -= sizeof(uint16_t);
-
- // third element is the realtime at point of caller
- log_time realtime(msg);
- msg += sizeof(log_time);
- n -= sizeof(log_time);
+ char *msg = ((char *)buffer) + sizeof(android_log_header_t);
+ n -= sizeof(android_log_header_t);
// NB: hdr.msg_flags & MSG_TRUNC is not tested, silently passing a
// truncated message to the logs.
- logbuf->log(log_id, realtime, cred->uid, cred->pid, tid, msg,
+ logbuf->log((log_id_t)header->id, header->realtime,
+ cred->uid, cred->pid, header->tid, msg,
((size_t) n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX);
reader->notifyNewLog();