Merge changes I9f380f31,Ieab6bed7,Ia870e4be,I939b1e01,I8b723dda

* changes:
  Add skip-secondary flag
  Switch fastboot to new A/B spec
  Add Fastboot support for flashing secondary images
  Handle invalid suffix lists
  Call set_active after flashall and update
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 45d26f8..be390d9 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -360,7 +360,7 @@
                 adb_auth_verified(t);
                 t->failed_auth_attempts = 0;
             } else {
-                if (t->failed_auth_attempts++ > 10) adb_sleep_ms(1000);
+                if (t->failed_auth_attempts++ > 256) adb_sleep_ms(1000);
                 send_auth_request(t);
             }
         } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) {
diff --git a/adb/adb_auth.cpp b/adb/adb_auth.cpp
index 446c3df..0b07158 100644
--- a/adb/adb_auth.cpp
+++ b/adb/adb_auth.cpp
@@ -64,12 +64,14 @@
 
     p->msg.command = A_AUTH;
     p->msg.arg0 = ADB_AUTH_RSAPUBLICKEY;
-    p->msg.data_length = key.size();
+
+    // adbd expects a null-terminated string.
+    p->msg.data_length = key.size() + 1;
     send_packet(p, t);
 }
 
 void send_auth_response(uint8_t* token, size_t token_size, atransport* t) {
-    RSA* key = t->NextKey();
+    std::shared_ptr<RSA> key = t->NextKey();
     if (key == nullptr) {
         // No more private keys to try, send the public key.
         send_auth_publickey(t);
@@ -79,12 +81,7 @@
     LOG(INFO) << "Calling send_auth_response";
     apacket* p = get_apacket();
 
-    int ret = adb_auth_sign(key, token, token_size, p->data);
-
-    // Stop sharing this key.
-    RSA_free(key);
-    key = nullptr;
-
+    int ret = adb_auth_sign(key.get(), token, token_size, p->data);
     if (!ret) {
         D("Error signing the token");
         put_apacket(p);
diff --git a/adb/adb_auth.h b/adb/adb_auth.h
index 723ded5..59b80d8 100644
--- a/adb/adb_auth.h
+++ b/adb/adb_auth.h
@@ -20,6 +20,7 @@
 #include "adb.h"
 
 #include <deque>
+#include <memory>
 
 #include <openssl/rsa.h>
 
@@ -43,7 +44,7 @@
 void adb_auth_init();
 int adb_auth_sign(RSA* key, const unsigned char* token, size_t token_size, unsigned char* sig);
 std::string adb_auth_get_userkey();
-std::deque<RSA*> adb_auth_get_private_keys();
+std::deque<std::shared_ptr<RSA>> adb_auth_get_private_keys();
 
 static inline bool adb_auth_generate_token(void*, size_t) { abort(); }
 static inline bool adb_auth_verify(void*, size_t, void*, int) { abort(); }
@@ -53,7 +54,7 @@
 
 static inline int adb_auth_sign(void*, const unsigned char*, size_t, unsigned char*) { abort(); }
 static inline std::string adb_auth_get_userkey() { abort(); }
-static inline std::deque<RSA*> adb_auth_get_private_keys() { abort(); }
+static inline std::deque<std::shared_ptr<RSA>> adb_auth_get_private_keys() { abort(); }
 
 void adbd_auth_init(void);
 void adbd_cloexec_auth_socket();
diff --git a/adb/adb_auth_host.cpp b/adb/adb_auth_host.cpp
index ce269cc..4f4f382 100644
--- a/adb/adb_auth_host.cpp
+++ b/adb/adb_auth_host.cpp
@@ -16,16 +16,18 @@
 
 #define TRACE_TAG AUTH
 
-#include "adb_auth.h"
-#include "adb.h"
-#include "adb_utils.h"
-#include "sysdeps.h"
-
+#include <dirent.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#if defined(__linux__)
+#include <sys/inotify.h>
+#endif
 
+#include <map>
 #include <mutex>
+#include <set>
+#include <string>
 
 #include <android-base/errors.h>
 #include <android-base/file.h>
@@ -39,10 +41,16 @@
 #include <openssl/rsa.h>
 #include <openssl/sha.h>
 
+#include "adb.h"
+#include "adb_auth.h"
+#include "adb_utils.h"
+#include "sysdeps.h"
 #include "sysdeps/mutex.h"
 
-static std::mutex& g_key_list_mutex = *new std::mutex;
-static std::deque<RSA*>& g_key_list = *new std::deque<RSA*>;
+static std::mutex& g_keys_mutex = *new std::mutex;
+static std::map<std::string, std::shared_ptr<RSA>>& g_keys =
+    *new std::map<std::string, std::shared_ptr<RSA>>;
+static std::map<int, std::string>& g_monitored_paths = *new std::map<int, std::string>;
 
 static std::string get_user_info() {
     LOG(INFO) << "get_user_info...";
@@ -146,8 +154,23 @@
     return ret;
 }
 
-static bool read_key(const std::string& file) {
-    LOG(INFO) << "read_key '" << file << "'...";
+static std::string hash_key(RSA* key) {
+    unsigned char* pubkey = nullptr;
+    int len = i2d_RSA_PUBKEY(key, &pubkey);
+    if (len < 0) {
+        LOG(ERROR) << "failed to encode RSA public key";
+        return std::string();
+    }
+
+    std::string result;
+    result.resize(SHA256_DIGEST_LENGTH);
+    SHA256(pubkey, len, reinterpret_cast<unsigned char*>(&result[0]));
+    OPENSSL_free(pubkey);
+    return result;
+}
+
+static bool read_key_file(const std::string& file) {
+    LOG(INFO) << "read_key_file '" << file << "'...";
 
     std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(file.c_str(), "r"), fclose);
     if (!fp) {
@@ -162,10 +185,66 @@
         return false;
     }
 
-    g_key_list.push_back(key);
+    std::lock_guard<std::mutex> lock(g_keys_mutex);
+    std::string fingerprint = hash_key(key);
+    if (g_keys.find(fingerprint) != g_keys.end()) {
+        LOG(INFO) << "ignoring already-loaded key: " << file;
+        RSA_free(key);
+    } else {
+        g_keys[fingerprint] = std::shared_ptr<RSA>(key, RSA_free);
+    }
+
     return true;
 }
 
+static bool read_keys(const std::string& path, bool allow_dir = true) {
+    LOG(INFO) << "read_keys '" << path << "'...";
+
+    struct stat st;
+    if (stat(path.c_str(), &st) != 0) {
+        PLOG(ERROR) << "failed to stat '" << path << "'";
+        return false;
+    }
+
+    if (S_ISREG(st.st_mode)) {
+        if (!android::base::EndsWith(path, ".adb_key")) {
+            LOG(INFO) << "skipping non-adb_key '" << path << "'";
+            return false;
+        }
+
+        return read_key_file(path);
+    } else if (S_ISDIR(st.st_mode)) {
+        if (!allow_dir) {
+            // inotify isn't recursive. It would break expectations to load keys in nested
+            // directories but not monitor them for new keys.
+            LOG(WARNING) << "refusing to recurse into directory '" << path << "'";
+            return false;
+        }
+
+        std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir);
+        if (!dir) {
+            PLOG(ERROR) << "failed to open directory '" << path << "'";
+            return false;
+        }
+
+        bool result = false;
+        while (struct dirent* dent = readdir(dir.get())) {
+            std::string name = dent->d_name;
+
+            // We can't use dent->d_type here because it's not available on Windows.
+            if (name == "." || name == "..") {
+                continue;
+            }
+
+            result |= read_keys((path + OS_PATH_SEPARATOR + name).c_str(), false);
+        }
+        return result;
+    }
+
+    LOG(ERROR) << "unexpected type for '" << path << "': 0x" << std::hex << st.st_mode;
+    return false;
+}
+
 static std::string get_user_key_path() {
     const std::string home = adb_get_homedir_path(true);
     LOG(DEBUG) << "adb_get_homedir_path returned '" << home << "'";
@@ -200,31 +279,29 @@
         }
     }
 
-    return read_key(path);
+    return read_key_file(path);
 }
 
-static void get_vendor_keys() {
+static std::set<std::string> get_vendor_keys() {
     const char* adb_keys_path = getenv("ADB_VENDOR_KEYS");
     if (adb_keys_path == nullptr) {
-        return;
+        return std::set<std::string>();
     }
 
+    std::set<std::string> result;
     for (const auto& path : android::base::Split(adb_keys_path, ENV_PATH_SEPARATOR_STR)) {
-        if (!read_key(path.c_str())) {
-            PLOG(ERROR) << "Failed to read '" << path << "'";
-        }
+        result.emplace(path);
     }
+    return result;
 }
 
-std::deque<RSA*> adb_auth_get_private_keys() {
-    std::deque<RSA*> result;
+std::deque<std::shared_ptr<RSA>> adb_auth_get_private_keys() {
+    std::deque<std::shared_ptr<RSA>> result;
 
-    // Copy all the currently known keys, increasing their reference count so they're
-    // usable until both we and the caller have freed our pointers.
-    std::lock_guard<std::mutex> lock(g_key_list_mutex);
-    for (const auto& key : g_key_list) {
-        RSA_up_ref(key); // Since we're handing out another pointer to this key...
-        result.push_back(key);
+    // Copy all the currently known keys.
+    std::lock_guard<std::mutex> lock(g_keys_mutex);
+    for (const auto& it : g_keys) {
+        result.push_back(it.second);
     }
 
     // Add a sentinel to the list. Our caller uses this to mean "out of private keys,
@@ -270,6 +347,77 @@
     return (generate_key(filename) == 0);
 }
 
+#if defined(__linux__)
+static void adb_auth_inotify_update(int fd, unsigned fd_event, void*) {
+    LOG(INFO) << "adb_auth_inotify_update called";
+    if (!(fd_event & FDE_READ)) {
+        return;
+    }
+
+    char buf[sizeof(struct inotify_event) + NAME_MAX + 1];
+    while (true) {
+        ssize_t rc = TEMP_FAILURE_RETRY(unix_read(fd, buf, sizeof(buf)));
+        if (rc == -1) {
+            if (errno == EAGAIN) {
+                LOG(INFO) << "done reading inotify fd";
+                break;
+            }
+            PLOG(FATAL) << "read of inotify event failed";
+        }
+
+        // The read potentially returned multiple events.
+        char* start = buf;
+        char* end = buf + rc;
+
+        while (start < end) {
+            inotify_event* event = reinterpret_cast<inotify_event*>(start);
+            auto root_it = g_monitored_paths.find(event->wd);
+            if (root_it == g_monitored_paths.end()) {
+                LOG(FATAL) << "observed inotify event for unmonitored path, wd = " << event->wd;
+            }
+
+            std::string path = root_it->second;
+            if (event->len > 0) {
+                path += '/';
+                path += event->name;
+            }
+
+            if (event->mask & (IN_CREATE | IN_MOVED_TO)) {
+                if (event->mask & IN_ISDIR) {
+                    LOG(INFO) << "ignoring new directory at '" << path << "'";
+                } else {
+                    LOG(INFO) << "observed new file at '" << path << "'";
+                    read_keys(path, false);
+                }
+            } else {
+                LOG(WARNING) << "unmonitored event for " << path << ": 0x" << std::hex
+                             << event->mask;
+            }
+
+            start += sizeof(struct inotify_event) + event->len;
+        }
+    }
+}
+
+static void adb_auth_inotify_init(const std::set<std::string>& paths) {
+    LOG(INFO) << "adb_auth_inotify_init...";
+    int infd = inotify_init1(IN_CLOEXEC | IN_NONBLOCK);
+    for (const std::string& path : paths) {
+        int wd = inotify_add_watch(infd, path.c_str(), IN_CREATE | IN_MOVED_TO);
+        if (wd < 0) {
+            PLOG(ERROR) << "failed to inotify_add_watch on path '" << path;
+            continue;
+        }
+
+        g_monitored_paths[wd] = path;
+        LOG(INFO) << "watch descriptor " << wd << " registered for " << path;
+    }
+
+    fdevent* event = fdevent_create(infd, adb_auth_inotify_update, nullptr);
+    fdevent_add(event, FDE_READ);
+}
+#endif
+
 void adb_auth_init() {
     LOG(INFO) << "adb_auth_init...";
 
@@ -278,6 +426,13 @@
         return;
     }
 
-    std::lock_guard<std::mutex> lock(g_key_list_mutex);
-    get_vendor_keys();
+    const auto& key_paths = get_vendor_keys();
+
+#if defined(__linux__)
+    adb_auth_inotify_init(key_paths);
+#endif
+
+    for (const std::string& path : key_paths) {
+        read_keys(path.c_str());
+    }
 }
diff --git a/adb/transport.cpp b/adb/transport.cpp
index e0216e3..f5ef174 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -1076,10 +1076,10 @@
     }
 }
 
-RSA* atransport::NextKey() {
+std::shared_ptr<RSA> atransport::NextKey() {
     if (keys_.empty()) keys_ = adb_auth_get_private_keys();
 
-    RSA* result = keys_[0];
+    std::shared_ptr<RSA> result = keys_[0];
     keys_.pop_front();
     return result;
 }
diff --git a/adb/transport.h b/adb/transport.h
index d41c8bd..959681f 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -21,6 +21,7 @@
 
 #include <deque>
 #include <list>
+#include <memory>
 #include <string>
 #include <unordered_set>
 
@@ -107,7 +108,7 @@
         return type == kTransportLocal && local_port_for_emulator_ == -1;
     }
 
-    RSA* NextKey();
+    std::shared_ptr<RSA> NextKey();
 
     unsigned char token[TOKEN_SIZE] = {};
     size_t failed_auth_attempts = 0;
@@ -160,7 +161,7 @@
     // A list of adisconnect callbacks called when the transport is kicked.
     std::list<adisconnect*> disconnects_;
 
-    std::deque<RSA*> keys_;
+    std::deque<std::shared_ptr<RSA>> keys_;
 
     DISALLOW_COPY_AND_ASSIGN(atransport);
 };
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index 1b3893f..4a85689 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -905,3 +905,22 @@
 
     return 0;
 }
+
+int fs_mgr_early_setup_verity(struct fstab_rec *fstab_rec)
+{
+    if ((fstab_rec->fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
+        int rc = fs_mgr_setup_verity(fstab_rec);
+        if (device_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
+            INFO("Verity disabled");
+            return FS_MGR_EARLY_SETUP_VERITY_NO_VERITY;
+        } else if (rc == FS_MGR_SETUP_VERITY_SUCCESS) {
+            return FS_MGR_EARLY_SETUP_VERITY_SUCCESS;
+        } else {
+            return FS_MGR_EARLY_SETUP_VERITY_FAIL;
+        }
+    } else if (device_is_secure()) {
+        ERROR("Verity must be enabled for early mounted partitions on secured devices.\n");
+        return FS_MGR_EARLY_SETUP_VERITY_FAIL;
+    }
+    return FS_MGR_EARLY_SETUP_VERITY_NO_VERITY;
+}
diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c
index 5b92db7..b302354 100644
--- a/fs_mgr/fs_mgr_fstab.c
+++ b/fs_mgr/fs_mgr_fstab.c
@@ -210,9 +210,8 @@
     return f;
 }
 
-struct fstab *fs_mgr_read_fstab(const char *fstab_path)
+struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file)
 {
-    FILE *fstab_file;
     int cnt, entries;
     ssize_t len;
     size_t alloc_len = 0;
@@ -224,12 +223,6 @@
 #define FS_OPTIONS_LEN 1024
     char tmp_fs_options[FS_OPTIONS_LEN];
 
-    fstab_file = fopen(fstab_path, "r");
-    if (!fstab_file) {
-        ERROR("Cannot open file %s\n", fstab_path);
-        return 0;
-    }
-
     entries = 0;
     while ((len = getline(&line, &alloc_len, fstab_file)) != -1) {
         /* if the last character is a newline, shorten the string by 1 byte */
@@ -255,7 +248,6 @@
     /* Allocate and init the fstab structure */
     fstab = calloc(1, sizeof(struct fstab));
     fstab->num_entries = entries;
-    fstab->fstab_filename = strdup(fstab_path);
     fstab->recs = calloc(fstab->num_entries, sizeof(struct fstab_rec));
 
     fseek(fstab_file, 0, SEEK_SET);
@@ -338,18 +330,34 @@
         ERROR("Error updating for slotselect\n");
         goto err;
     }
-    fclose(fstab_file);
     free(line);
     return fstab;
 
 err:
-    fclose(fstab_file);
     free(line);
     if (fstab)
         fs_mgr_free_fstab(fstab);
     return NULL;
 }
 
+struct fstab *fs_mgr_read_fstab(const char *fstab_path)
+{
+    FILE *fstab_file;
+    struct fstab *fstab;
+
+    fstab_file = fopen(fstab_path, "r");
+    if (!fstab_file) {
+        ERROR("Cannot open file %s\n", fstab_path);
+        return NULL;
+    }
+    fstab = fs_mgr_read_fstab_file(fstab_file);
+    if (fstab) {
+        fstab->fstab_filename = strdup(fstab_path);
+    }
+    fclose(fstab_file);
+    return fstab;
+}
+
 void fs_mgr_free_fstab(struct fstab *fstab)
 {
     int i;
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index 67104cc..767b3b3 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -341,17 +341,6 @@
     return 0;
 }
 
-static int test_access(char *device) {
-    int tries = 25;
-    while (tries--) {
-        if (!access(device, F_OK) || errno != ENOENT) {
-            return 0;
-        }
-        usleep(40 * 1000);
-    }
-    return -1;
-}
-
 static int check_verity_restart(const char *fname)
 {
     char buffer[VERITY_KMSG_BUFSIZE + 1];
@@ -1031,11 +1020,6 @@
     fstab->blk_device = verity_blk_name;
     verity_blk_name = 0;
 
-    // make sure we've set everything up properly
-    if (test_access(fstab->blk_device) < 0) {
-        goto out;
-    }
-
     retval = FS_MGR_SETUP_VERITY_SUCCESS;
 
 out:
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 3c27ede..17d0277 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -17,6 +17,7 @@
 #ifndef __CORE_FS_MGR_H
 #define __CORE_FS_MGR_H
 
+#include <stdio.h>
 #include <stdint.h>
 #include <stdbool.h>
 #include <linux/dm-ioctl.h>
@@ -72,6 +73,7 @@
 typedef void (*fs_mgr_verity_state_callback)(struct fstab_rec *fstab,
         const char *mount_point, int mode, int status);
 
+struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file);
 struct fstab *fs_mgr_read_fstab(const char *fstab_path);
 void fs_mgr_free_fstab(struct fstab *fstab);
 
@@ -111,6 +113,11 @@
 
 int fs_mgr_do_format(struct fstab_rec *fstab, bool reserve_footer);
 
+#define FS_MGR_EARLY_SETUP_VERITY_NO_VERITY -2
+#define FS_MGR_EARLY_SETUP_VERITY_FAIL -1
+#define FS_MGR_EARLY_SETUP_VERITY_SUCCESS 0
+int fs_mgr_early_setup_verity(struct fstab_rec *fstab);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/cutils/process_name.h b/include/cutils/process_name.h
deleted file mode 100644
index 1e72e5c..0000000
--- a/include/cutils/process_name.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-/**
- * Gives the current process a name.
- */
-
-#ifndef __PROCESS_NAME_H
-#define __PROCESS_NAME_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Sets the current process name.
- *
- * Warning: This leaks a string every time you call it. Use judiciously!
- */
-void set_process_name(const char* process_name);
-
-/** Gets the current process name. */
-const char* get_process_name(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __PROCESS_NAME_H */ 
diff --git a/init/devices.cpp b/init/devices.cpp
index 373177e..830b74c 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -44,6 +44,7 @@
 
 #include <android-base/file.h>
 #include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
 #include <cutils/list.h>
 #include <cutils/uevent.h>
 
@@ -601,14 +602,17 @@
     return name;
 }
 
+#define DEVPATH_LEN 96
+#define MAX_DEV_NAME 64
+
 static void handle_block_device_event(struct uevent *uevent)
 {
     const char *base = "/dev/block/";
     const char *name;
-    char devpath[96];
+    char devpath[DEVPATH_LEN];
     char **links = NULL;
 
-    name = parse_device_name(uevent, 64);
+    name = parse_device_name(uevent, MAX_DEV_NAME);
     if (!name)
         return;
 
@@ -622,8 +626,6 @@
             uevent->major, uevent->minor, links);
 }
 
-#define DEVPATH_LEN 96
-
 static bool assemble_devpath(char *devpath, const char *dirname,
         const char *devname)
 {
@@ -657,7 +659,7 @@
     char devpath[DEVPATH_LEN] = {0};
     char **links = NULL;
 
-    name = parse_device_name(uevent, 64);
+    name = parse_device_name(uevent, MAX_DEV_NAME);
     if (!name)
         return;
 
@@ -900,7 +902,8 @@
 }
 
 #define UEVENT_MSG_LEN  2048
-void handle_device_fd()
+
+static inline void handle_device_fd_with(void (handle_uevent)(struct uevent*))
 {
     char msg[UEVENT_MSG_LEN+2];
     int n;
@@ -913,21 +916,28 @@
 
         struct uevent uevent;
         parse_event(msg, &uevent);
-
-        if (selinux_status_updated() > 0) {
-            struct selabel_handle *sehandle2;
-            sehandle2 = selinux_android_file_context_handle();
-            if (sehandle2) {
-                selabel_close(sehandle);
-                sehandle = sehandle2;
-            }
-        }
-
-        handle_device_event(&uevent);
-        handle_firmware_event(&uevent);
+        handle_uevent(&uevent);
     }
 }
 
+void handle_device_fd()
+{
+    handle_device_fd_with(
+        [](struct uevent *uevent) {
+            if (selinux_status_updated() > 0) {
+                struct selabel_handle *sehandle2;
+                sehandle2 = selinux_android_file_context_handle();
+                if (sehandle2) {
+                    selabel_close(sehandle);
+                    sehandle = sehandle2;
+                }
+            }
+
+            handle_device_event(uevent);
+            handle_firmware_event(uevent);
+        });
+}
+
 /* Coldboot walks parts of the /sys tree and pokes the uevent files
 ** to cause the kernel to regenerate device add events that happened
 ** before init's device manager was started
@@ -979,6 +989,65 @@
     }
 }
 
+static void early_uevent_handler(struct uevent *uevent, const char *base, bool is_block)
+{
+    const char *name;
+    char devpath[DEVPATH_LEN];
+
+    if (is_block && strncmp(uevent->subsystem, "block", 5))
+        return;
+
+    name = parse_device_name(uevent, MAX_DEV_NAME);
+    if (!name) {
+        LOG(ERROR) << "Failed to parse dev name from uevent: " << uevent->action
+                   << " " << uevent->partition_name << " " << uevent->partition_num
+                   << " " << uevent->major << ":" << uevent->minor;
+        return;
+    }
+
+    snprintf(devpath, sizeof(devpath), "%s%s", base, name);
+    make_dir(base, 0755);
+
+    dev_t dev = makedev(uevent->major, uevent->minor);
+    mode_t mode = 0600 | (is_block ? S_IFBLK : S_IFCHR);
+    mknod(devpath, mode, dev);
+}
+
+void early_create_dev(const std::string& syspath, early_device_type dev_type)
+{
+    android::base::unique_fd dfd(open(syspath.c_str(), O_RDONLY));
+    if (dfd < 0) {
+        LOG(ERROR) << "Failed to open " << syspath;
+        return;
+    }
+
+    android::base::unique_fd fd(openat(dfd, "uevent", O_WRONLY));
+    if (fd < 0) {
+        LOG(ERROR) << "Failed to open " << syspath << "/uevent";
+        return;
+    }
+
+    fcntl(device_fd, F_SETFL, O_NONBLOCK);
+
+    write(fd, "add\n", 4);
+    handle_device_fd_with(dev_type == EARLY_BLOCK_DEV ?
+        [](struct uevent *uevent) {
+            early_uevent_handler(uevent, "/dev/block/", true);
+        } :
+        [](struct uevent *uevent) {
+            early_uevent_handler(uevent, "/dev/", false);
+        });
+}
+
+int early_device_socket_open() {
+    device_fd = uevent_open_socket(256*1024, true);
+    return device_fd < 0;
+}
+
+void early_device_socket_close() {
+    close(device_fd);
+}
+
 void device_init() {
     sehandle = selinux_android_file_context_handle();
     selinux_status_open(true);
diff --git a/init/devices.h b/init/devices.h
index 6cb0a77..8e9ab7d 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -21,6 +21,13 @@
 
 extern void handle_device_fd();
 extern void device_init(void);
+
+enum early_device_type { EARLY_BLOCK_DEV, EARLY_CHAR_DEV };
+
+extern int early_device_socket_open();
+extern void early_device_socket_close();
+extern void early_create_dev(const std::string& syspath, early_device_type dev_type);
+
 extern int add_dev_perms(const char *name, const char *attr,
                          mode_t perm, unsigned int uid,
                          unsigned int gid, unsigned short prefix,
diff --git a/init/init.cpp b/init/init.cpp
index 78d71a8..957527b 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -54,6 +54,7 @@
 #include "action.h"
 #include "bootchart.h"
 #include "devices.h"
+#include "fs_mgr.h"
 #include "import_parser.h"
 #include "init.h"
 #include "init_parser.h"
@@ -342,9 +343,6 @@
 }
 
 static void process_kernel_cmdline() {
-    // Don't expose the raw commandline to unprivileged processes.
-    chmod("/proc/cmdline", 0440);
-
     // The first pass does the common stuff, and finds if we are in qemu.
     // The second pass is only necessary for qemu to export all kernel params
     // as properties.
@@ -461,6 +459,104 @@
     }
 }
 
+/* Returns a new path consisting of base_path and the file name in reference_path. */
+static std::string get_path(const std::string& base_path, const std::string& reference_path) {
+    std::string::size_type pos = reference_path.rfind('/');
+    if (pos == std::string::npos) {
+        return base_path + '/' + reference_path;
+    } else {
+        return base_path + reference_path.substr(pos);
+    }
+}
+
+/* Imports the fstab info from cmdline. */
+static std::string import_cmdline_fstab() {
+    std::string prefix, fstab, fstab_full;
+
+    import_kernel_cmdline(false,
+        [&](const std::string& key, const std::string& value, bool in_qemu __attribute__((__unused__))) {
+            if (key == "android.early.prefix") {
+                prefix = value;
+            } else if (key == "android.early.fstab") {
+                fstab = value;
+            }
+        });
+    if (!fstab.empty()) {
+        // Convert "mmcblk0p09+/odm+ext4+ro+verify" to "mmcblk0p09 /odm ext4 ro verify"
+        std::replace(fstab.begin(), fstab.end(), '+', ' ');
+        for (const auto& entry : android::base::Split(fstab, "\n")) {
+            fstab_full += prefix + entry + '\n';
+        }
+    }
+    return fstab_full;
+}
+
+/* Early mount vendor and ODM partitions. The fstab info is read from kernel cmdline. */
+static void early_mount() {
+    std::string fstab_string = import_cmdline_fstab();
+    if (fstab_string.empty()) {
+        LOG(INFO) << "Failed to load vendor fstab from kernel cmdline";
+        return;
+    }
+    FILE *fstab_file = fmemopen((void *)fstab_string.c_str(), fstab_string.length(), "r");
+    if (!fstab_file) {
+        PLOG(ERROR) << "Failed to open fstab string as FILE";
+        return;
+    }
+    std::unique_ptr<struct fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_file(fstab_file), fs_mgr_free_fstab);
+    fclose(fstab_file);
+    if (!fstab) {
+        LOG(ERROR) << "Failed to parse fstab string: " << fstab_string;
+        return;
+    }
+    LOG(INFO) << "Loaded vendor fstab from cmdline";
+
+    if (early_device_socket_open()) {
+        LOG(ERROR) << "Failed to open device uevent socket";
+        return;
+    }
+
+    /* Create /dev/device-mapper for dm-verity */
+    early_create_dev("/sys/devices/virtual/misc/device-mapper", EARLY_CHAR_DEV);
+
+    for (int i = 0; i < fstab->num_entries; ++i) {
+        struct fstab_rec *rec = &fstab->recs[i];
+        std::string mount_point = rec->mount_point;
+        std::string syspath = rec->blk_device;
+
+        if (mount_point != "/vendor" && mount_point != "/odm")
+            continue;
+
+        /* Create mount target under /dev/block/ from sysfs via uevent */
+        LOG(INFO) << "Mounting " << mount_point << " from " << syspath << "...";
+        char *devpath = strdup(get_path("/dev/block", syspath).c_str());
+        if (!devpath) {
+            PLOG(ERROR) << "Failed to strdup dev path in early mount " << syspath;
+            continue;
+        }
+        rec->blk_device = devpath;
+        early_create_dev(syspath, EARLY_BLOCK_DEV);
+
+        int rc = fs_mgr_early_setup_verity(rec);
+        if (rc == FS_MGR_EARLY_SETUP_VERITY_SUCCESS) {
+            /* Mount target is changed to /dev/block/dm-<n>; initiate its creation from sysfs counterpart */
+            early_create_dev(get_path("/sys/devices/virtual/block", rec->blk_device), EARLY_BLOCK_DEV);
+        } else if (rc == FS_MGR_EARLY_SETUP_VERITY_FAIL) {
+            LOG(ERROR) << "Failed to set up dm-verity on " << rec->blk_device;
+            continue;
+        } else { /* FS_MGR_EARLY_SETUP_VERITY_NO_VERITY */
+            LOG(INFO) << "dm-verity disabled on debuggable device; mount directly on " << rec->blk_device;
+        }
+
+        mkdir(mount_point.c_str(), 0755);
+        rc = mount(rec->blk_device, mount_point.c_str(), rec->fs_type, rec->flags, rec->fs_options);
+        if (rc) {
+            PLOG(ERROR) << "Failed to mount on " << rec->blk_device;
+        }
+    }
+    early_device_socket_close();
+}
+
 int main(int argc, char** argv) {
     if (!strcmp(basename(argv[0]), "ueventd")) {
         return ueventd_main(argc, argv);
@@ -477,6 +573,9 @@
 
     bool is_first_stage = (argc == 1) || (strcmp(argv[1], "--second-stage") != 0);
 
+    // Don't expose the raw commandline to unprivileged processes.
+    chmod("/proc/cmdline", 0440);
+
     // Get the basic filesystem setup we need put together in the initramdisk
     // on / and then we'll let the rc file figure out the rest.
     if (is_first_stage) {
@@ -489,6 +588,7 @@
         mount("sysfs", "/sys", "sysfs", 0, NULL);
         mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
         mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
+        early_mount();
     }
 
     // Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually
@@ -541,6 +641,8 @@
     restorecon("/dev/__properties__");
     restorecon("/property_contexts");
     restorecon_recursive("/sys");
+    restorecon_recursive("/dev/block");
+    restorecon("/dev/device-mapper");
 
     epoll_fd = epoll_create1(EPOLL_CLOEXEC);
     if (epoll_fd == -1) {
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index 4f26034..8624d13 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -42,7 +42,6 @@
         "load_file.c",
         "native_handle.c",
         "open_memstream.c",
-        "process_name.c",
         "record_stream.c",
         "sched_policy.c",
         "sockets.cpp",
diff --git a/libcutils/process_name.c b/libcutils/process_name.c
deleted file mode 100644
index 5d28b6f..0000000
--- a/libcutils/process_name.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2008 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 <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#if defined(__linux__)
-#include <sys/prctl.h>
-#endif
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <cutils/process_name.h>
-#if defined(__ANDROID__)
-#include <cutils/properties.h>
-#endif
-
-#define PROCESS_NAME_DEVICE "/sys/qemu_trace/process_name"
-
-static const char* process_name = "unknown";
-#if defined(__ANDROID__)
-static int running_in_emulator = -1;
-#endif
-
-void set_process_name(const char* new_name) {
-#if defined(__ANDROID__)
-    char  propBuf[PROPERTY_VALUE_MAX];
-#endif
-
-    if (new_name == NULL) {
-        return;
-    }
-
-    // We never free the old name. Someone else could be using it.
-    int len = strlen(new_name);
-    char* copy = (char*) malloc(len + 1);
-    strcpy(copy, new_name);
-    process_name = (const char*) copy;
-
-#if defined(__linux__)
-    if (len < 16) {
-        prctl(PR_SET_NAME, (unsigned long) new_name, 0, 0, 0);
-    } else {
-        prctl(PR_SET_NAME, (unsigned long) new_name + len - 15, 0, 0, 0);
-    }
-#endif
-
-#if defined(__ANDROID__)
-    // If we know we are not running in the emulator, then return.
-    if (running_in_emulator == 0) {
-        return;
-    }
-
-    // If the "running_in_emulator" variable has not been initialized,
-    // then do it now.
-    if (running_in_emulator == -1) {
-        property_get("ro.kernel.qemu", propBuf, "");
-        if (propBuf[0] == '1') {
-            running_in_emulator = 1;
-        } else {
-            running_in_emulator = 0;
-            return;
-        }
-    }
-
-    // If the emulator was started with the "-trace file" command line option
-    // then we want to record the process name in the trace even if we are
-    // not currently tracing instructions (so that we will know the process
-    // name when we do start tracing instructions).  We do not need to execute
-    // this code if we are just running in the emulator without the "-trace"
-    // command line option, but we don't know that here and this function
-    // isn't called frequently enough to bother optimizing that case.
-    int fd = open(PROCESS_NAME_DEVICE, O_RDWR);
-    if (fd < 0)
-        return;
-    write(fd, process_name, strlen(process_name) + 1);
-    close(fd);
-#endif
-}
-
-const char* get_process_name(void) {
-    return process_name;
-}
diff --git a/liblog/logd_writer.c b/liblog/logd_writer.c
index 059f170..ed82902 100644
--- a/liblog/logd_writer.c
+++ b/liblog/logd_writer.c
@@ -67,12 +67,9 @@
     int i, ret = 0;
 
     if (logdLoggerWrite.context.sock < 0) {
-        i = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+        i = TEMP_FAILURE_RETRY(socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0));
         if (i < 0) {
             ret = -errno;
-        } else if (TEMP_FAILURE_RETRY(fcntl(i, F_SETFL, O_NONBLOCK)) < 0) {
-            ret = -errno;
-            close(i);
         } else {
             struct sockaddr_un un;
             memset(&un, 0, sizeof(struct sockaddr_un));
diff --git a/libpixelflinger/codeflinger/CodeCache.cpp b/libpixelflinger/codeflinger/CodeCache.cpp
index 4b498c1..ae38519 100644
--- a/libpixelflinger/codeflinger/CodeCache.cpp
+++ b/libpixelflinger/codeflinger/CodeCache.cpp
@@ -23,7 +23,6 @@
 #include <sys/mman.h>
 
 #include <cutils/ashmem.h>
-#include <cutils/atomic.h>
 #define LOG_TAG "CodeCache"
 #include <cutils/log.h>
 
@@ -101,7 +100,7 @@
 }
 
 Assembly::Assembly(size_t size)
-    : mCount(1), mSize(0)
+    : mCount(0), mSize(0)
 {
     mBase = (uint32_t*)mspace_malloc(getMspace(), size);
     LOG_ALWAYS_FATAL_IF(mBase == NULL,
@@ -117,12 +116,12 @@
 
 void Assembly::incStrong(const void*) const
 {
-    android_atomic_inc(&mCount);
+    mCount.fetch_add(1, std::memory_order_relaxed);
 }
 
 void Assembly::decStrong(const void*) const
 {
-    if (android_atomic_dec(&mCount) == 1) {
+    if (mCount.fetch_sub(1, std::memory_order_acq_rel) == 1) {
         delete this;
     }
 }
diff --git a/libpixelflinger/codeflinger/CodeCache.h b/libpixelflinger/codeflinger/CodeCache.h
index c0e0684..9326453 100644
--- a/libpixelflinger/codeflinger/CodeCache.h
+++ b/libpixelflinger/codeflinger/CodeCache.h
@@ -19,6 +19,7 @@
 #ifndef ANDROID_CODECACHE_H
 #define ANDROID_CODECACHE_H
 
+#include <atomic>
 #include <stdint.h>
 #include <pthread.h>
 #include <sys/types.h>
@@ -69,7 +70,7 @@
     typedef void    weakref_type;
 
 private:
-    mutable int32_t     mCount;
+    mutable std::atomic<int32_t>     mCount;
             uint32_t*   mBase;
             size_t      mSize;
 };
diff --git a/libpixelflinger/tests/arch-arm64/assembler/arm64_assembler_test.cpp b/libpixelflinger/tests/arch-arm64/assembler/arm64_assembler_test.cpp
index 5f58797..63642c4 100644
--- a/libpixelflinger/tests/arch-arm64/assembler/arm64_assembler_test.cpp
+++ b/libpixelflinger/tests/arch-arm64/assembler/arm64_assembler_test.cpp
@@ -34,7 +34,6 @@
 
 #include <sys/mman.h>
 #include <cutils/ashmem.h>
-#include <cutils/atomic.h>
 
 #define __STDC_FORMAT_MACROS
 #include <inttypes.h>
diff --git a/libpixelflinger/tests/arch-mips64/assembler/mips64_assembler_test.cpp b/libpixelflinger/tests/arch-mips64/assembler/mips64_assembler_test.cpp
index b680b60..e8c4626 100644
--- a/libpixelflinger/tests/arch-mips64/assembler/mips64_assembler_test.cpp
+++ b/libpixelflinger/tests/arch-mips64/assembler/mips64_assembler_test.cpp
@@ -34,7 +34,6 @@
 
 #include <sys/mman.h>
 #include <cutils/ashmem.h>
-#include <cutils/atomic.h>
 #include <cutils/log.h>
 
 #define __STDC_FORMAT_MACROS