Merge "init-debug.rc: don't mount debugfs"
diff --git a/.clang-format-2 b/.clang-format-2
index fb967d8..aab4665 100644
--- a/.clang-format-2
+++ b/.clang-format-2
@@ -1,8 +1,4 @@
 BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: true
-
-AccessModifierOffset: -1
 ColumnLimit: 100
 CommentPragmas: NOLINT:.*
 DerivePointerAlignment: false
diff --git a/.clang-format-4 b/.clang-format-4
index fc4eb1b..1497447 100644
--- a/.clang-format-4
+++ b/.clang-format-4
@@ -1,7 +1,4 @@
 BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: false
-
 AccessModifierOffset: -2
 ColumnLimit: 100
 CommentPragmas: NOLINT:.*
diff --git a/adb/.clang-format b/adb/.clang-format
deleted file mode 100644
index fc4eb1b..0000000
--- a/adb/.clang-format
+++ /dev/null
@@ -1,13 +0,0 @@
-BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: false
-
-AccessModifierOffset: -2
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
-IndentWidth: 4
-PointerAlignment: Left
-TabWidth: 4
-UseTab: Never
-PenaltyExcessCharacter: 32
diff --git a/adb/.clang-format b/adb/.clang-format
new file mode 120000
index 0000000..1af4f51
--- /dev/null
+++ b/adb/.clang-format
@@ -0,0 +1 @@
+../.clang-format-4
\ No newline at end of file
diff --git a/base/.clang-format b/base/.clang-format
deleted file mode 100644
index 2b83a1f..0000000
--- a/base/.clang-format
+++ /dev/null
@@ -1,11 +0,0 @@
-BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: false
-
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
-IndentWidth: 2
-PointerAlignment: Left
-TabWidth: 2
-UseTab: Never
-PenaltyExcessCharacter: 32
diff --git a/base/.clang-format b/base/.clang-format
new file mode 120000
index 0000000..fd0645f
--- /dev/null
+++ b/base/.clang-format
@@ -0,0 +1 @@
+../.clang-format-2
\ No newline at end of file
diff --git a/base/file.cpp b/base/file.cpp
index 81b04d7..378a405 100644
--- a/base/file.cpp
+++ b/base/file.cpp
@@ -212,6 +212,20 @@
 }
 #endif
 
+#if !defined(_WIN32)
+bool Realpath(const std::string& path, std::string* result) {
+  result->clear();
+
+  char* realpath_buf = realpath(path.c_str(), nullptr);
+  if (realpath_buf == nullptr) {
+    return false;
+  }
+  result->assign(realpath_buf);
+  free(realpath_buf);
+  return true;
+}
+#endif
+
 std::string GetExecutablePath() {
 #if defined(__linux__)
   std::string path;
diff --git a/base/file_test.cpp b/base/file_test.cpp
index 1021326..266131e 100644
--- a/base/file_test.cpp
+++ b/base/file_test.cpp
@@ -159,6 +159,38 @@
 #endif
 }
 
+TEST(file, Realpath) {
+#if !defined(_WIN32)
+  TemporaryDir td;
+  std::string basename = android::base::Basename(td.path);
+  std::string dir_name = android::base::Dirname(td.path);
+  std::string base_dir_name = android::base::Basename(dir_name);
+
+  {
+    std::string path = dir_name + "/../" + base_dir_name + "/" + basename;
+    std::string result;
+    ASSERT_TRUE(android::base::Realpath(path, &result));
+    ASSERT_EQ(td.path, result);
+  }
+
+  {
+    std::string path = std::string(td.path) + "/..";
+    std::string result;
+    ASSERT_TRUE(android::base::Realpath(path, &result));
+    ASSERT_EQ(dir_name, result);
+  }
+
+  {
+    errno = 0;
+    std::string path = std::string(td.path) + "/foo.noent";
+    std::string result = "wrong";
+    ASSERT_TRUE(!android::base::Realpath(path, &result));
+    ASSERT_TRUE(result.empty());
+    ASSERT_EQ(ENOENT, errno);
+  }
+#endif
+}
+
 TEST(file, GetExecutableDirectory) {
   std::string path = android::base::GetExecutableDirectory();
   ASSERT_NE("", path);
diff --git a/base/include/android-base/file.h b/base/include/android-base/file.h
index 33d1ab3..651f529 100644
--- a/base/include/android-base/file.h
+++ b/base/include/android-base/file.h
@@ -47,6 +47,7 @@
 bool RemoveFileIfExists(const std::string& path, std::string* err = nullptr);
 
 #if !defined(_WIN32)
+bool Realpath(const std::string& path, std::string* result);
 bool Readlink(const std::string& path, std::string* result);
 #endif
 
diff --git a/debuggerd/.clang-format b/debuggerd/.clang-format
deleted file mode 100644
index 9b7478c..0000000
--- a/debuggerd/.clang-format
+++ /dev/null
@@ -1,15 +0,0 @@
-BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: false
-
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
-IndentWidth: 2
-ContinuationIndentWidth: 2
-PointerAlignment: Left
-TabWidth: 2
-UseTab: Never
-PenaltyExcessCharacter: 32
-
-Cpp11BracedListStyle: false
diff --git a/debuggerd/.clang-format b/debuggerd/.clang-format
new file mode 120000
index 0000000..fd0645f
--- /dev/null
+++ b/debuggerd/.clang-format
@@ -0,0 +1 @@
+../.clang-format-2
\ No newline at end of file
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index b385ea5..2d6c7f5 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -1,5 +1,6 @@
 cc_defaults {
     name: "debuggerd_defaults",
+    defaults: ["linux_bionic_supported"],
     cflags: [
         "-Wall",
         "-Wextra",
diff --git a/demangle/.clang-format b/demangle/.clang-format
new file mode 120000
index 0000000..fd0645f
--- /dev/null
+++ b/demangle/.clang-format
@@ -0,0 +1 @@
+../.clang-format-2
\ No newline at end of file
diff --git a/fastboot/.clang-format b/fastboot/.clang-format
deleted file mode 100644
index bcb8d8a..0000000
--- a/fastboot/.clang-format
+++ /dev/null
@@ -1,15 +0,0 @@
-BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: Inline
-
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
-IndentWidth: 4
-ContinuationIndentWidth: 8
-ConstructorInitializerIndentWidth: 8
-AccessModifierOffset: -2
-PointerAlignment: Left
-TabWidth: 4
-UseTab: Never
-PenaltyExcessCharacter: 32
diff --git a/fastboot/.clang-format b/fastboot/.clang-format
new file mode 120000
index 0000000..1af4f51
--- /dev/null
+++ b/fastboot/.clang-format
@@ -0,0 +1 @@
+../.clang-format-4
\ No newline at end of file
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index a4a0b52..2927b16 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -1245,20 +1245,17 @@
     return 0;
 }
 
-static int do_oem_command(int argc, char **argv)
-{
-    char command[256];
+static int do_oem_command(int argc, char** argv) {
     if (argc <= 1) return 0;
 
-    command[0] = 0;
-    while(1) {
-        strcat(command,*argv);
+    std::string command;
+    while (argc > 0) {
+        command += *argv;
         skip(1);
-        if(argc == 0) break;
-        strcat(command," ");
+        if (argc != 0) command += " ";
     }
 
-    fb_queue_command(command,"");
+    fb_queue_command(command.c_str(), "");
     return 0;
 }
 
diff --git a/init/action.cpp b/init/action.cpp
index 09de81a..1bba0f2 100644
--- a/init/action.cpp
+++ b/init/action.cpp
@@ -246,20 +246,16 @@
 }
 
 std::string Action::BuildTriggersString() const {
-    std::string result;
+    std::vector<std::string> triggers;
 
     for (const auto& [trigger_name, trigger_value] : property_triggers_) {
-        result += trigger_name;
-        result += '=';
-        result += trigger_value;
-        result += ' ';
+        triggers.emplace_back(trigger_name + '=' + trigger_value);
     }
     if (!event_trigger_.empty()) {
-        result += event_trigger_;
-        result += ' ';
+        triggers.emplace_back(event_trigger_);
     }
-    result.pop_back();
-    return result;
+
+    return Join(triggers, " && ");
 }
 
 void Action::DumpState() const {
@@ -268,7 +264,7 @@
 
     for (const auto& c : commands_) {
         std::string cmd_str = c.BuildCommandString();
-        LOG(INFO) << "  %s" << cmd_str;
+        LOG(INFO) << "  " << cmd_str;
     }
 }
 
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 9e3489e..0b2e761 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -494,6 +494,10 @@
             parser.ParseConfig(args[i]);
         }
     }
+
+    // Turning this on and letting the INFO logging be discarded adds 0.2s to
+    // Nexus 9 boot time, so it's disabled by default.
+    if (false) parser.DumpState();
 }
 
 /* mount_fstab
diff --git a/init/devices.cpp b/init/devices.cpp
index bd11f5f..405f92e 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -390,6 +390,34 @@
     return 0;
 }
 
+/* Given a path that may start with a virtual block device, populate
+ * the supplied buffer with the virtual block device ID and return 0.
+ * If it doesn't start with a virtual block device, or there is some
+ * error, return -1 */
+static int find_vbd_device_prefix(const char *path, char *buf, ssize_t buf_sz)
+{
+    const char *start, *end;
+
+    /* Beginning of the prefix is the initial "vbd-" after "/devices/" */
+    if (strncmp(path, "/devices/vbd-", 13))
+        return -1;
+
+    /* End of the prefix is one path '/' later, capturing the
+       virtual block device ID. Example: 768 */
+    start = path + 13;
+    end = strchr(start, '/');
+    if (!end)
+        return -1;
+
+    /* Make sure we have enough room for the string plus null terminator */
+    if (end - start + 1 > buf_sz)
+        return -1;
+
+    strncpy(buf, start, end - start);
+    buf[end - start] = '\0';
+    return 0;
+}
+
 static void parse_event(const char *msg, struct uevent *uevent)
 {
     uevent->action = "";
@@ -516,6 +544,9 @@
     } else if (!find_pci_device_prefix(uevent->path, buf, sizeof(buf))) {
         device = buf;
         type = "pci";
+    } else if (!find_vbd_device_prefix(uevent->path, buf, sizeof(buf))) {
+        device = buf;
+        type = "vbd";
     } else {
         return NULL;
     }
diff --git a/init/init.cpp b/init/init.cpp
index 5ab421b..4e31865 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -1254,6 +1254,10 @@
         parser.set_is_odm_etc_init_loaded(true);
     }
 
+    // Turning this on and letting the INFO logging be discarded adds 0.2s to
+    // Nexus 9 boot time, so it's disabled by default.
+    if (false) parser.DumpState();
+
     ActionManager& am = ActionManager::GetInstance();
 
     am.QueueEventTrigger("early-init");
diff --git a/init/init_parser.cpp b/init/init_parser.cpp
index 406b339..326ebf2 100644
--- a/init/init_parser.cpp
+++ b/init/init_parser.cpp
@@ -106,10 +106,6 @@
         sp.second->EndFile(path);
     }
 
-    // Turning this on and letting the INFO logging be discarded adds 0.2s to
-    // Nexus 9 boot time, so it's disabled by default.
-    if (false) DumpState();
-
     LOG(VERBOSE) << "(Parsing " << path << " took " << t << ".)";
     return true;
 }
diff --git a/libbacktrace/Android.bp b/libbacktrace/Android.bp
index 5b31ecb..0e7c6f3 100644
--- a/libbacktrace/Android.bp
+++ b/libbacktrace/Android.bp
@@ -80,6 +80,18 @@
             static_libs: ["libcutils"],
             host_ldlibs: ["-lrt"],
         },
+        linux_bionic: {
+            enabled: true,
+            srcs: libbacktrace_sources,
+
+            shared_libs: [
+                "libbase",
+                "liblog",
+                "libunwind",
+            ],
+
+            static_libs: ["libcutils"],
+        },
         android: {
             srcs: libbacktrace_sources,
 
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index cf31195..f668f18 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -41,9 +41,12 @@
     host_supported: true,
     export_include_dirs: ["include"],
     target: {
-       windows: {
-          enabled: true,
-       },
+        linux_bionic: {
+            enabled: true,
+        },
+        windows: {
+            enabled: true,
+        },
     },
 }
 
@@ -68,11 +71,14 @@
         "threads.c",
     ],
 
-
     target: {
         host: {
             srcs: ["dlmalloc_stubs.c"],
         },
+        linux_bionic: {
+            enabled: true,
+            exclude_srcs: ["dlmalloc_stubs.c"],
+        },
         not_windows: {
             srcs: libcutils_nonwindows_sources + [
                 "ashmem-host.c",
diff --git a/libcutils/android_reboot.c b/libcutils/android_reboot.c
index 159a9d4..6bdcc13 100644
--- a/libcutils/android_reboot.c
+++ b/libcutils/android_reboot.c
@@ -209,6 +209,10 @@
                            LINUX_REBOOT_CMD_RESTART2, arg);
             break;
 
+        case ANDROID_RB_THERMOFF:
+            ret = reboot(RB_POWER_OFF);
+            break;
+
         default:
             ret = -1;
     }
diff --git a/libcutils/include/cutils/android_reboot.h b/libcutils/include/cutils/android_reboot.h
index a3861a0..549f258 100644
--- a/libcutils/include/cutils/android_reboot.h
+++ b/libcutils/include/cutils/android_reboot.h
@@ -25,6 +25,7 @@
 #define ANDROID_RB_RESTART  0xDEAD0001
 #define ANDROID_RB_POWEROFF 0xDEAD0002
 #define ANDROID_RB_RESTART2 0xDEAD0003
+#define ANDROID_RB_THERMOFF 0xDEAD0004
 
 /* Properties */
 #define ANDROID_RB_PROPERTY "sys.powerctl"
diff --git a/libprocinfo/.clang-format b/libprocinfo/.clang-format
deleted file mode 100644
index b8c6428..0000000
--- a/libprocinfo/.clang-format
+++ /dev/null
@@ -1,14 +0,0 @@
-BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: false
-
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
-IndentWidth: 2
-PointerAlignment: Left
-TabWidth: 2
-UseTab: Never
-PenaltyExcessCharacter: 32
-
-Cpp11BracedListStyle: false
diff --git a/libprocinfo/.clang-format b/libprocinfo/.clang-format
new file mode 120000
index 0000000..fd0645f
--- /dev/null
+++ b/libprocinfo/.clang-format
@@ -0,0 +1 @@
+../.clang-format-2
\ No newline at end of file
diff --git a/libprocinfo/Android.bp b/libprocinfo/Android.bp
index 8e17f1b..c13ffe9 100644
--- a/libprocinfo/Android.bp
+++ b/libprocinfo/Android.bp
@@ -35,6 +35,9 @@
         darwin: {
             enabled: false,
         },
+        linux_bionic: {
+            enabled: true,
+        },
         windows: {
             enabled: false,
         },
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 0c777b1..2b98fef 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -17,9 +17,12 @@
     host_supported: true,
     export_include_dirs: ["include"],
     target: {
+        linux_bionic: {
+            enabled: true,
+        },
         windows: {
-           enabled: true,
-      },
+            enabled: true,
+        },
     },
 }
 
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index dad74ee..0895834 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -208,9 +208,9 @@
         if ((*ep != '-') && (*ep != '.')) {
             continue;
         }
-        // Find PID field
+        // Find PID field.  Look for ': ' or ':[0-9][0-9][0-9]'
         while (((ep = strchr(ep, ':'))) && (*++ep != ' ')) {
-            ;
+            if (isdigit(ep[0]) && isdigit(ep[1]) && isdigit(ep[2])) break;
         }
         if (!ep) {
             continue;
diff --git a/logd/FlushCommand.cpp b/logd/FlushCommand.cpp
index 5a5c0d9..ff6bff8 100644
--- a/logd/FlushCommand.cpp
+++ b/logd/FlushCommand.cpp
@@ -27,7 +27,7 @@
 #include "LogUtils.h"
 
 FlushCommand::FlushCommand(LogReader& reader, bool nonBlock, unsigned long tail,
-                           unsigned int logMask, pid_t pid, uint64_t start,
+                           unsigned int logMask, pid_t pid, log_time start,
                            uint64_t timeout)
     : mReader(reader),
       mNonBlock(nonBlock),
@@ -35,7 +35,7 @@
       mLogMask(logMask),
       mPid(pid),
       mStart(start),
-      mTimeout((start > 1) ? timeout : 0) {
+      mTimeout((start != log_time::EPOCH) ? timeout : 0) {
 }
 
 // runSocketCommand is called once for every open client on the
diff --git a/logd/FlushCommand.h b/logd/FlushCommand.h
index 45cb9c5..7cdd03f 100644
--- a/logd/FlushCommand.h
+++ b/logd/FlushCommand.h
@@ -16,7 +16,7 @@
 #ifndef _FLUSH_COMMAND_H
 #define _FLUSH_COMMAND_H
 
-#include <android/log.h>
+#include <private/android_logger.h>
 #include <sysutils/SocketClientCommand.h>
 
 class LogBufferElement;
@@ -31,13 +31,13 @@
     unsigned long mTail;
     unsigned int mLogMask;
     pid_t mPid;
-    uint64_t mStart;
+    log_time mStart;
     uint64_t mTimeout;
 
    public:
     explicit FlushCommand(LogReader& mReader, bool nonBlock = false,
                           unsigned long tail = -1, unsigned int logMask = -1,
-                          pid_t pid = 0, uint64_t start = 1,
+                          pid_t pid = 0, log_time start = log_time::EPOCH,
                           uint64_t timeout = 0);
     virtual void runSocketCommand(SocketClient* client);
 
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 9c634f6..1b79e89 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -180,8 +180,13 @@
     if (!avcr) return DIFFERENT;
     lenr -= avcr - msgr;
     if (lenl != lenr) return DIFFERENT;
-    if (fastcmp<memcmp>(avcl + strlen(avc), avcr + strlen(avc), lenl))
+    // TODO: After b/35468874 is addressed, revisit "lenl > strlen(avc)"
+    // condition, it might become superfluous.
+    if (lenl > strlen(avc) &&
+        fastcmp<memcmp>(avcl + strlen(avc), avcr + strlen(avc),
+                        lenl - strlen(avc))) {
         return DIFFERENT;
+    }
     return SAME;
 }
 
@@ -369,18 +374,12 @@
     //  NB: if end is region locked, place element at end of list
     LogBufferElementCollection::iterator it = mLogElements.end();
     LogBufferElementCollection::iterator last = it;
-    while (last != mLogElements.begin()) {
-        --it;
-        if ((*it)->getRealTime() <= elem->getRealTime()) {
-            break;
-        }
-        last = it;
-    }
-
-    if (last == mLogElements.end()) {
+    if (__predict_true(it != mLogElements.begin())) --it;
+    if (__predict_false(it == mLogElements.begin()) ||
+        __predict_true((*it)->getRealTime() <= elem->getRealTime())) {
         mLogElements.push_back(elem);
     } else {
-        uint64_t end = 1;
+        log_time end = log_time::EPOCH;
         bool end_set = false;
         bool end_always = false;
 
@@ -394,6 +393,7 @@
                     end_always = true;
                     break;
                 }
+                // it passing mEnd is blocked by the following checks.
                 if (!end_set || (end <= entry->mEnd)) {
                     end = entry->mEnd;
                     end_set = true;
@@ -402,12 +402,20 @@
             times++;
         }
 
-        if (end_always || (end_set && (end >= (*last)->getSequence()))) {
+        if (end_always || (end_set && (end > (*it)->getRealTime()))) {
             mLogElements.push_back(elem);
         } else {
+            // should be short as timestamps are localized near end()
+            do {
+                last = it;
+                if (__predict_false(it == mLogElements.begin())) {
+                    break;
+                }
+                --it;
+            } while (((*it)->getRealTime() > elem->getRealTime()) &&
+                     (!end_set || (end <= (*it)->getRealTime())));
             mLogElements.insert(last, elem);
         }
-
         LogTimeEntry::unlock();
     }
 
@@ -582,12 +590,12 @@
     }
 
     void clear(LogBufferElement* element) {
-        uint64_t current =
-            element->getRealTime().nsec() - (EXPIRE_RATELIMIT * NS_PER_SEC);
+        log_time current =
+            element->getRealTime() - log_time(EXPIRE_RATELIMIT, 0);
         for (LogBufferElementMap::iterator it = map.begin(); it != map.end();) {
             LogBufferElement* mapElement = it->second;
             if ((mapElement->getDropped() >= EXPIRE_THRESHOLD) &&
-                (current > mapElement->getRealTime().nsec())) {
+                (current > mapElement->getRealTime())) {
                 it = map.erase(it);
             } else {
                 ++it;
@@ -683,7 +691,7 @@
                 mLastSet[id] = true;
             }
 
-            if (oldest && (oldest->mStart <= element->getSequence())) {
+            if (oldest && (oldest->mStart <= element->getRealTime().nsec())) {
                 busy = true;
                 if (oldest->mTimeout.tv_sec || oldest->mTimeout.tv_nsec) {
                     oldest->triggerReader_Locked();
@@ -775,7 +783,7 @@
         while (it != mLogElements.end()) {
             LogBufferElement* element = *it;
 
-            if (oldest && (oldest->mStart <= element->getSequence())) {
+            if (oldest && (oldest->mStart <= element->getRealTime().nsec())) {
                 busy = true;
                 if (oldest->mTimeout.tv_sec || oldest->mTimeout.tv_nsec) {
                     oldest->triggerReader_Locked();
@@ -929,7 +937,7 @@
             mLastSet[id] = true;
         }
 
-        if (oldest && (oldest->mStart <= element->getSequence())) {
+        if (oldest && (oldest->mStart <= element->getRealTime().nsec())) {
             busy = true;
             if (whitelist) {
                 break;
@@ -973,7 +981,7 @@
                 mLastSet[id] = true;
             }
 
-            if (oldest && (oldest->mStart <= element->getSequence())) {
+            if (oldest && (oldest->mStart <= element->getRealTime().nsec())) {
                 busy = true;
                 if (stats.sizes(id) > (2 * log_buffer_size(id))) {
                     // kick a misbehaving log reader client off the island
@@ -1066,32 +1074,37 @@
     return retval;
 }
 
-uint64_t LogBuffer::flushTo(
-    SocketClient* reader, const uint64_t start, bool privileged, bool security,
+log_time LogBuffer::flushTo(
+    SocketClient* reader, const log_time& start, bool privileged, bool security,
     int (*filter)(const LogBufferElement* element, void* arg), void* arg) {
     LogBufferElementCollection::iterator it;
-    uint64_t max = start;
     uid_t uid = reader->getUid();
 
     pthread_mutex_lock(&mLogElementsLock);
 
-    if (start <= 1) {
+    if (start == log_time::EPOCH) {
         // client wants to start from the beginning
         it = mLogElements.begin();
     } else {
+        LogBufferElementCollection::iterator last = mLogElements.begin();
+        // 30 second limit to continue search for out-of-order entries.
+        log_time min = start - log_time(30, 0);
         // 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->getSequence() <= start) {
-                it++;
+            if (element->getRealTime() > start) {
+                last = it;
+            } else if (element->getRealTime() < min) {
                 break;
             }
         }
+        it = last;
     }
 
+    log_time max = start;
     // Help detect if the valid message before is from the same source so
     // we can differentiate chatty filter types.
     pid_t lastTid[LOG_ID_MAX] = { 0 };
@@ -1107,7 +1120,7 @@
             continue;
         }
 
-        if (element->getSequence() <= start) {
+        if (element->getRealTime() <= start) {
             continue;
         }
 
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index 92b0297..fcf6b9a 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -115,7 +115,7 @@
 
     int log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
             const char* msg, unsigned short len);
-    uint64_t flushTo(SocketClient* writer, const uint64_t start,
+    log_time flushTo(SocketClient* writer, const log_time& start,
                      bool privileged, bool security,
                      int (*filter)(const LogBufferElement* element,
                                    void* arg) = NULL,
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
index 5ba3a15..81356fe 100644
--- a/logd/LogBufferElement.cpp
+++ b/logd/LogBufferElement.cpp
@@ -30,7 +30,7 @@
 #include "LogReader.h"
 #include "LogUtils.h"
 
-const uint64_t LogBufferElement::FLUSH_ERROR(0);
+const log_time LogBufferElement::FLUSH_ERROR((uint32_t)-1, (uint32_t)-1);
 atomic_int_fast64_t LogBufferElement::sequence(1);
 
 LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime,
@@ -39,7 +39,6 @@
     : mUid(uid),
       mPid(pid),
       mTid(tid),
-      mSequence(sequence.fetch_add(1, memory_order_relaxed)),
       mRealTime(realtime),
       mMsgLen(len),
       mLogId(log_id) {
@@ -55,7 +54,6 @@
       mUid(elem.mUid),
       mPid(elem.mPid),
       mTid(elem.mTid),
-      mSequence(elem.mSequence),
       mRealTime(elem.mRealTime),
       mMsgLen(elem.mMsgLen),
       mLogId(elem.mLogId) {
@@ -206,7 +204,7 @@
     return retval;
 }
 
-uint64_t LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent,
+log_time LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent,
                                    bool privileged, bool lastSame) {
     struct logger_entry_v4 entry;
 
@@ -229,7 +227,7 @@
 
     if (!mMsg) {
         entry.len = populateDroppedMessage(buffer, parent, lastSame);
-        if (!entry.len) return mSequence;
+        if (!entry.len) return mRealTime;
         iovec[1].iov_base = buffer;
     } else {
         entry.len = mMsgLen;
@@ -237,7 +235,7 @@
     }
     iovec[1].iov_len = entry.len;
 
-    uint64_t retval = reader->sendDatav(iovec, 2) ? FLUSH_ERROR : mSequence;
+    log_time retval = reader->sendDatav(iovec, 2) ? FLUSH_ERROR : mRealTime;
 
     if (buffer) free(buffer);
 
diff --git a/logd/LogBufferElement.h b/logd/LogBufferElement.h
index 43990e8..814ec87 100644
--- a/logd/LogBufferElement.h
+++ b/logd/LogBufferElement.h
@@ -40,7 +40,6 @@
     const uint32_t mUid;
     const uint32_t mPid;
     const uint32_t mTid;
-    const uint64_t mSequence;
     log_time mRealTime;
     char* mMsg;
     union {
@@ -96,18 +95,12 @@
     const char* getMsg() const {
         return mMsg;
     }
-    uint64_t getSequence(void) const {
-        return mSequence;
-    }
-    static uint64_t getCurrentSequence(void) {
-        return sequence.load(memory_order_relaxed);
-    }
     log_time getRealTime(void) const {
         return mRealTime;
     }
 
-    static const uint64_t FLUSH_ERROR;
-    uint64_t flushTo(SocketClient* writer, LogBuffer* parent, bool privileged,
+    static const log_time FLUSH_ERROR;
+    log_time flushTo(SocketClient* writer, LogBuffer* parent, bool privileged,
                      bool lastSame);
 };
 
diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp
index 9ae95f9..9dfa14e 100644
--- a/logd/LogKlog.cpp
+++ b/logd/LogKlog.cpp
@@ -754,7 +754,7 @@
     //   eg: [143:healthd]healthd -> [143:healthd]
     taglen = etag - tag;
     // Mediatek-special printk induced stutter
-    const char* mp = strnrchr(tag, ']', taglen);
+    const char* mp = strnrchr(tag, taglen, ']');
     if (mp && (++mp < etag)) {
         size_t s = etag - mp;
         if (((s + s) < taglen) && !fastcmp<memcmp>(mp, mp - 1 - s, s)) {
diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp
index 76f5798..620d4d0 100644
--- a/logd/LogReader.cpp
+++ b/logd/LogReader.cpp
@@ -116,57 +116,70 @@
         nonBlock = true;
     }
 
-    uint64_t sequence = 1;
-    // Convert realtime to sequence number
-    if (start != log_time::EPOCH) {
-        class LogFindStart {
+    log_time sequence = start;
+    //
+    // This somewhat expensive data validation operation is required
+    // for non-blocking, with timeout.  The incoming timestamp must be
+    // in range of the list, if not, return immediately.  This is
+    // used to prevent us from from getting stuck in timeout processing
+    // with an invalid time.
+    //
+    // Find if time is really present in the logs, monotonic or real, implicit
+    // conversion from monotonic or real as necessary to perform the check.
+    // Exit in the check loop ASAP as you find a transition from older to
+    // newer, but use the last entry found to ensure overlap.
+    //
+    if (nonBlock && (sequence != log_time::EPOCH) && timeout) {
+        class LogFindStart {  // A lambda by another name
+           private:
             const pid_t mPid;
             const unsigned mLogMask;
-            bool startTimeSet;
-            log_time& start;
-            uint64_t& sequence;
-            uint64_t last;
-            bool isMonotonic;
+            bool mStartTimeSet;
+            log_time mStart;
+            log_time& mSequence;
+            log_time mLast;
+            bool mIsMonotonic;
 
            public:
-            LogFindStart(unsigned logMask, pid_t pid, log_time& start,
-                         uint64_t& sequence, bool isMonotonic)
+            LogFindStart(pid_t pid, unsigned logMask, log_time& sequence,
+                         bool isMonotonic)
                 : mPid(pid),
                   mLogMask(logMask),
-                  startTimeSet(false),
-                  start(start),
-                  sequence(sequence),
-                  last(sequence),
-                  isMonotonic(isMonotonic) {
+                  mStartTimeSet(false),
+                  mStart(sequence),
+                  mSequence(sequence),
+                  mLast(sequence),
+                  mIsMonotonic(isMonotonic) {
             }
 
             static int callback(const LogBufferElement* element, void* obj) {
                 LogFindStart* me = reinterpret_cast<LogFindStart*>(obj);
                 if ((!me->mPid || (me->mPid == element->getPid())) &&
                     (me->mLogMask & (1 << element->getLogId()))) {
-                    if (me->start == element->getRealTime()) {
-                        me->sequence = element->getSequence();
-                        me->startTimeSet = true;
+                    log_time real = element->getRealTime();
+                    if (me->mStart == real) {
+                        me->mSequence = real;
+                        me->mStartTimeSet = true;
                         return -1;
-                    } else if (!me->isMonotonic ||
-                               android::isMonotonic(element->getRealTime())) {
-                        if (me->start < element->getRealTime()) {
-                            me->sequence = me->last;
-                            me->startTimeSet = true;
+                    } else if (!me->mIsMonotonic || android::isMonotonic(real)) {
+                        if (me->mStart < real) {
+                            me->mSequence = me->mLast;
+                            me->mStartTimeSet = true;
                             return -1;
                         }
-                        me->last = element->getSequence();
+                        me->mLast = real;
                     } else {
-                        me->last = element->getSequence();
+                        me->mLast = real;
                     }
                 }
                 return false;
             }
 
             bool found() {
-                return startTimeSet;
+                return mStartTimeSet;
             }
-        } logFindStart(logMask, pid, start, sequence,
+
+        } logFindStart(pid, logMask, sequence,
                        logbuf().isMonotonic() && android::isMonotonic(start));
 
         logbuf().flushTo(cli, sequence, FlushCommand::hasReadLogs(cli),
@@ -174,11 +187,8 @@
                          logFindStart.callback, &logFindStart);
 
         if (!logFindStart.found()) {
-            if (nonBlock) {
-                doSocketDelete(cli);
-                return false;
-            }
-            sequence = LogBufferElement::getCurrentSequence();
+            doSocketDelete(cli);
+            return false;
         }
     }
 
diff --git a/logd/LogTimes.cpp b/logd/LogTimes.cpp
index bdaeb75..04e531f 100644
--- a/logd/LogTimes.cpp
+++ b/logd/LogTimes.cpp
@@ -17,6 +17,8 @@
 #include <errno.h>
 #include <sys/prctl.h>
 
+#include <private/android_logger.h>
+
 #include "FlushCommand.h"
 #include "LogBuffer.h"
 #include "LogReader.h"
@@ -26,7 +28,7 @@
 
 LogTimeEntry::LogTimeEntry(LogReader& reader, SocketClient* client,
                            bool nonBlock, unsigned long tail,
-                           unsigned int logMask, pid_t pid, uint64_t start,
+                           unsigned int logMask, pid_t pid, log_time start,
                            uint64_t timeout)
     : mRefCount(1),
       mRelease(false),
@@ -42,7 +44,7 @@
       mClient(client),
       mStart(start),
       mNonBlock(nonBlock),
-      mEnd(LogBufferElement::getCurrentSequence()) {
+      mEnd(log_time(android_log_clockid())) {
     mTimeout.tv_sec = timeout / NS_PER_SEC;
     mTimeout.tv_nsec = timeout % NS_PER_SEC;
     pthread_cond_init(&threadTriggeredCondition, NULL);
@@ -132,7 +134,7 @@
 
     lock();
 
-    uint64_t start = me->mStart;
+    log_time start = me->mStart;
 
     while (me->threadRunning && !me->isError_Locked()) {
         if (me->mTimeout.tv_sec || me->mTimeout.tv_nsec) {
@@ -163,7 +165,7 @@
             break;
         }
 
-        me->mStart = start + 1;
+        me->mStart = start + log_time(0, 1);
 
         if (me->mNonBlock || !me->threadRunning || me->isError_Locked()) {
             break;
@@ -198,7 +200,7 @@
     }
 
     if (me->mCount == 0) {
-        me->mStart = element->getSequence();
+        me->mStart = element->getRealTime();
     }
 
     if ((!me->mPid || (me->mPid == element->getPid())) &&
@@ -217,7 +219,7 @@
 
     LogTimeEntry::lock();
 
-    me->mStart = element->getSequence();
+    me->mStart = element->getRealTime();
 
     if (me->skipAhead[element->getLogId()]) {
         me->skipAhead[element->getLogId()]--;
diff --git a/logd/LogTimes.h b/logd/LogTimes.h
index 23fdf4e..9a3ddab 100644
--- a/logd/LogTimes.h
+++ b/logd/LogTimes.h
@@ -51,13 +51,13 @@
    public:
     LogTimeEntry(LogReader& reader, SocketClient* client, bool nonBlock,
                  unsigned long tail, unsigned int logMask, pid_t pid,
-                 uint64_t start, uint64_t timeout);
+                 log_time start, uint64_t timeout);
 
     SocketClient* mClient;
-    uint64_t mStart;
+    log_time mStart;
     struct timespec mTimeout;
     const bool mNonBlock;
-    const uint64_t mEnd;  // only relevant if mNonBlock
+    const log_time mEnd;  // only relevant if mNonBlock
 
     // Protect List manipulations
     static void lock(void) {