Merge "healthd: Adds fake battery properties for devices with no battery." into mnc-dr-dev
diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c
index 60f5398..a9e3358 100644
--- a/fs_mgr/fs_mgr_verity.c
+++ b/fs_mgr/fs_mgr_verity.c
@@ -47,6 +47,8 @@
 
 #define VERITY_METADATA_SIZE 32768
 #define VERITY_TABLE_RSA_KEY "/verity_key"
+#define VERITY_TABLE_HASH_IDX 8
+#define VERITY_TABLE_SALT_IDX 9
 
 #define METADATA_MAGIC 0x01564c54
 #define METADATA_TAG_MAX_LENGTH 63
@@ -141,6 +143,33 @@
     return retval;
 }
 
+static int invalidate_table(char *table, int table_length)
+{
+    int n = 0;
+    int idx = 0;
+    int cleared = 0;
+
+    while (n < table_length) {
+        if (table[n++] == ' ') {
+            ++idx;
+        }
+
+        if (idx != VERITY_TABLE_HASH_IDX && idx != VERITY_TABLE_SALT_IDX) {
+            continue;
+        }
+
+        while (n < table_length && table[n] != ' ') {
+            table[n++] = '0';
+        }
+
+        if (++cleared == 2) {
+            return 0;
+        }
+    }
+
+    return -1;
+}
+
 static int squashfs_get_target_device_size(char *blk_device, uint64_t *device_size)
 {
     struct squashfs_info sq_info;
@@ -957,6 +986,7 @@
     char *verity_blk_name = 0;
     char *verity_table = 0;
     char *verity_table_signature = 0;
+    int verity_table_length = 0;
     uint64_t device_size = 0;
 
     _Alignas(struct dm_ioctl) char buffer[DM_BUF_SIZE];
@@ -983,6 +1013,7 @@
     }
 
     retval = FS_MGR_SETUP_VERITY_FAIL;
+    verity_table_length = strlen(verity_table);
 
     // get the device mapper fd
     if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
@@ -1002,13 +1033,6 @@
         goto out;
     }
 
-    // verify the signature on the table
-    if (verify_table(verity_table_signature,
-                            verity_table,
-                            strlen(verity_table)) < 0) {
-        goto out;
-    }
-
     if (load_verity_state(fstab, &mode) < 0) {
         /* if accessing or updating the state failed, switch to the default
          * safe mode. This makes sure the device won't end up in an endless
@@ -1017,6 +1041,22 @@
         mode = VERITY_MODE_EIO;
     }
 
+    // verify the signature on the table
+    if (verify_table(verity_table_signature,
+                            verity_table,
+                            verity_table_length) < 0) {
+        if (mode == VERITY_MODE_LOGGING) {
+            // the user has been warned, allow mounting without dm-verity
+            retval = FS_MGR_SETUP_VERITY_SUCCESS;
+            goto out;
+        }
+
+        // invalidate root hash and salt to trigger device-specific recovery
+        if (invalidate_table(verity_table, verity_table_length) < 0) {
+            goto out;
+        }
+    }
+
     INFO("Enabling dm-verity for %s (mode %d)\n",  mount_point, mode);
 
     // load the verity mapping table
diff --git a/libutils/tests/Vector_test.cpp b/libutils/tests/Vector_test.cpp
index 09914bd..96d3168 100644
--- a/libutils/tests/Vector_test.cpp
+++ b/libutils/tests/Vector_test.cpp
@@ -16,6 +16,8 @@
 
 #define LOG_TAG "Vector_test"
 
+#define __STDC_LIMIT_MACROS
+#include <stdint.h>
 #include <utils/Vector.h>
 #include <cutils/log.h>
 #include <gtest/gtest.h>
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 4933a46..559fa2e 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -242,8 +242,8 @@
         LogBufferElementCollection::iterator it, bool engageStats) {
     LogBufferElement *e = *it;
     log_id_t id = e->getLogId();
-    LogBufferIteratorMap::iterator f = mLastWorstUid[id].find(e->getUid());
 
+    LogBufferIteratorMap::iterator f = mLastWorstUid[id].find(e->getUid());
     if ((f != mLastWorstUid[id].end()) && (it == f->second)) {
         mLastWorstUid[id].erase(f);
     }
@@ -329,7 +329,51 @@
 
 // prune "pruneRows" of type "id" from the buffer.
 //
+// This garbage collection task is used to expire log entries. It is called to
+// remove all logs (clear), all UID logs (unprivileged clear), or every
+// 256 or 10% of the total logs (whichever is less) to prune the logs.
+//
+// First there is a prep phase where we discover the reader region lock that
+// acts as a backstop to any pruning activity to stop there and go no further.
+//
+// There are three major pruning loops that follow. All expire from the oldest
+// entries. Since there are multiple log buffers, the Android logging facility
+// will appear to drop entries 'in the middle' when looking at multiple log
+// sources and buffers. This effect is slightly more prominent when we prune
+// the worst offender by logging source. Thus the logs slowly loose content
+// and value as you move back in time. This is preferred since chatty sources
+// invariably move the logs value down faster as less chatty sources would be
+// expired in the noise.
+//
+// The first loop performs blacklisting and worst offender pruning. Falling
+// through when there are no notable worst offenders and have not hit the
+// region lock preventing further worst offender pruning. This loop also looks
+// after managing the chatty log entries and merging to help provide
+// statistical basis for blame. The chatty entries are not a notification of
+// how much logs you may have, but instead represent how much logs you would
+// have had in a virtual log buffer that is extended to cover all the in-memory
+// logs without loss. They last much longer than the represented pruned logs
+// since they get multiplied by the gains in the non-chatty log sources.
+//
+// The second loop get complicated because an algorithm of watermarks and
+// history is maintained to reduce the order and keep processing time
+// down to a minimum at scale. These algorithms can be costly in the face
+// of larger log buffers, or severly limited processing time granted to a
+// background task at lowest priority.
+//
+// This second loop does straight-up expiration from the end of the logs
+// (again, remember for the specified log buffer id) but does some whitelist
+// preservation. Thus whitelist is a Hail Mary low priority, blacklists and
+// spam filtration all take priority. This second loop also checks if a region
+// lock is causing us to buffer too much in the logs to help the reader(s),
+// and will tell the slowest reader thread to skip log entries, and if
+// persistent and hits a further threshold, kill the reader thread.
+//
+// The third thread is optional, and only gets hit if there was a whitelist
+// and more needs to be pruned against the backstop of the region lock.
+//
 // mLogElementsLock must be held when this function is called.
+//
 void LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
     LogTimeEntry *oldest = NULL;
 
@@ -410,7 +454,12 @@
         bool kick = false;
         bool leading = true;
         it = mLogElements.begin();
-        if (worst != (uid_t) -1) {
+        // Perform at least one mandatory garbage collection cycle in following
+        // - clear leading chatty tags
+        // - merge chatty tags
+        // - check age-out of preserved logs
+        bool gc = pruneRows <= 1;
+        if (!gc && (worst != (uid_t) -1)) {
             LogBufferIteratorMap::iterator f = mLastWorstUid[id].find(worst);
             if ((f != mLastWorstUid[id].end())
                     && (f->second != mLogElements.end())) {
@@ -481,7 +530,7 @@
             // unmerged drop message
             if (dropped) {
                 last.add(e);
-                if ((e->getUid() == worst)
+                if ((!gc && (e->getUid() == worst))
                         || (mLastWorstUid[id].find(e->getUid())
                             == mLastWorstUid[id].end())) {
                     mLastWorstUid[id][e->getUid()] = it;
@@ -516,7 +565,10 @@
                     it = erase(it, false);
                 } else {
                     last.add(e);
-                    mLastWorstUid[id][e->getUid()] = it;
+                    if (!gc || (mLastWorstUid[id].find(worst)
+                                == mLastWorstUid[id].end())) {
+                        mLastWorstUid[id][worst] = it;
+                    }
                     ++it;
                 }
             }
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 2b1a97c..8ea72e8 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -143,14 +143,20 @@
     mkdir /dev/cpuset/foreground
     mkdir /dev/cpuset/foreground/boost
     mkdir /dev/cpuset/background
+    # system-background is for system tasks that should only run on
+    # little cores, not on bigs
+    # to be used only by init, so don't change the permissions
+    mkdir /dev/cpuset/system-background
     # this ensures that the cpusets are present and usable, but the device's
     # init.rc must actually set the correct cpus
     write /dev/cpuset/foreground/cpus 0
     write /dev/cpuset/foreground/boost/cpus 0
     write /dev/cpuset/background/cpus 0
+    write /dev/cpuset/system-background/cpus 0
     write /dev/cpuset/foreground/mems 0
     write /dev/cpuset/foreground/boost/mems 0
     write /dev/cpuset/background/mems 0
+    write /dev/cpuset/system-background/mems 0
     chown system system /dev/cpuset
     chown system system /dev/cpuset/foreground
     chown system system /dev/cpuset/foreground/boost
@@ -548,9 +554,11 @@
     socket logdr seqpacket 0666 logd logd
     socket logdw dgram 0222 logd logd
     group root system
+     writepid /dev/cpuset/system-background/tasks
 
 service logd-reinit /system/bin/logd --reinit
     oneshot
+    writepid /dev/cpuset/system-background/tasks
     disabled
 
 service healthd /sbin/healthd
@@ -585,6 +593,7 @@
     class core
     critical
     socket lmkd seqpacket 0660 system system
+    writepid /dev/cpuset/system-background/tasks
 
 service servicemanager /system/bin/servicemanager
     class core
@@ -614,9 +623,11 @@
 
 service debuggerd /system/bin/debuggerd
     class main
+    writepid /dev/cpuset/system-background/tasks
 
 service debuggerd64 /system/bin/debuggerd64
     class main
+    writepid /dev/cpuset/system-background/tasks
 
 service ril-daemon /system/bin/rild
     class main
@@ -631,6 +642,7 @@
     user system
     group graphics drmrpc
     onrestart restart zygote
+    writepid /dev/cpuset/system-background/tasks
 
 service drm /system/bin/drmserver
     class main
@@ -725,6 +737,7 @@
     class late_start
     user root
     oneshot
+    writepid /dev/cpuset/system-background/tasks
 
 on property:persist.logd.logpersistd=logcatd
     # all exec/services are called with umask(077), so no gain beyond 0700
@@ -739,3 +752,4 @@
     # logd for write to /data/misc/logd, log group for read from log daemon
     user logd
     group log
+    writepid /dev/cpuset/system-background/tasks