Merge "Add TrustyKeyMintDevice"
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index a152740..5bb1d75 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -32,6 +32,7 @@
 #include <set>
 #include <vector>
 
+#include <android-base/errno_restorer.h>
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/macros.h>
@@ -67,8 +68,9 @@
 #include "protocol.h"
 #include "util.h"
 
-using android::base::unique_fd;
+using android::base::ErrnoRestorer;
 using android::base::StringPrintf;
+using android::base::unique_fd;
 
 static bool pid_contains_tid(int pid_proc_fd, pid_t tid) {
   struct stat st;
@@ -89,10 +91,11 @@
 static bool ptrace_seize_thread(int pid_proc_fd, pid_t tid, std::string* error, int flags = 0) {
   if (ptrace(PTRACE_SEIZE, tid, 0, flags) != 0) {
     if (errno == EPERM) {
-      pid_t tracer = get_tracer(tid);
-      if (tracer != -1) {
+      ErrnoRestorer errno_restorer;  // In case get_tracer() fails and we fall through.
+      pid_t tracer_pid = get_tracer(tid);
+      if (tracer_pid > 0) {
         *error = StringPrintf("failed to attach to thread %d, already traced by %d (%s)", tid,
-                              tracer, get_process_name(tracer).c_str());
+                              tracer_pid, get_process_name(tracer_pid).c_str());
         return false;
       }
     }
diff --git a/debuggerd/handler/debuggerd_fallback.cpp b/debuggerd/handler/debuggerd_fallback.cpp
index f615780..baf994f 100644
--- a/debuggerd/handler/debuggerd_fallback.cpp
+++ b/debuggerd/handler/debuggerd_fallback.cpp
@@ -1,29 +1,17 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
- * All rights reserved.
+ * Copyright 2017 The Android Open Source Project
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
+ * 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
  *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ *     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 <dirent.h>
diff --git a/debuggerd/handler/debuggerd_fallback_nop.cpp b/debuggerd/handler/debuggerd_fallback_nop.cpp
index 331301f..5666d98 100644
--- a/debuggerd/handler/debuggerd_fallback_nop.cpp
+++ b/debuggerd/handler/debuggerd_fallback_nop.cpp
@@ -1,29 +1,17 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
- * All rights reserved.
+ * Copyright 2017 The Android Open Source Project
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
+ * 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
  *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ *     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.
  */
 
 extern "C" void debuggerd_fallback_handler(struct siginfo_t*, struct ucontext_t*, void*) {
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index b607397..375dbed 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -1,29 +1,17 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
+ * Copyright 2008 The Android Open Source Project
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
+ * 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
  *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ *     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 "debuggerd/handler.h"
diff --git a/debuggerd/tombstoned/tombstoned.rc b/debuggerd/tombstoned/tombstoned.rc
index c39f4e4..fc43f4e 100644
--- a/debuggerd/tombstoned/tombstoned.rc
+++ b/debuggerd/tombstoned/tombstoned.rc
@@ -5,4 +5,4 @@
     socket tombstoned_crash seqpacket 0666 system system
     socket tombstoned_intercept seqpacket 0666 system system
     socket tombstoned_java_trace seqpacket 0666 system system
-    writepid /dev/cpuset/system-background/tasks
+    task_profiles ServiceCapacityLow
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index 5356b00..3d63a44 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -141,6 +141,7 @@
     // Do not ever allow this library to be vendor_available as a shared library.
     // It does not have a stable interface.
     name: "libfs_mgr",
+    ramdisk_available: true,
     recovery_available: true,
     defaults: [
         "libfs_mgr_defaults",
@@ -165,6 +166,7 @@
     // It does not have a stable interface.
     name: "libfstab",
     vendor_available: true,
+    ramdisk_available: true,
     recovery_available: true,
     host_supported: true,
     defaults: ["fs_mgr_defaults"],
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index af71fe6..01c8ad3 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -2092,7 +2092,7 @@
         }
 
         if (entry.zram_size > 0) {
-	    if (!PrepareZramBackingDevice(entry.zram_backingdev_size)) {
+            if (!PrepareZramBackingDevice(entry.zram_backingdev_size)) {
                 LERROR << "Failure of zram backing device file for '" << entry.blk_device << "'";
             }
             // A zram_size was specified, so we need to configure the
diff --git a/fs_mgr/libfiemap/Android.bp b/fs_mgr/libfiemap/Android.bp
index 1c5872e..b62e33f 100644
--- a/fs_mgr/libfiemap/Android.bp
+++ b/fs_mgr/libfiemap/Android.bp
@@ -20,6 +20,7 @@
 
 cc_library_headers {
     name: "libfiemap_headers",
+    ramdisk_available: true,
     recovery_available: true,
     export_include_dirs: ["include"],
 }
diff --git a/fs_mgr/libfs_avb/Android.bp b/fs_mgr/libfs_avb/Android.bp
index 6892025..62493eb 100644
--- a/fs_mgr/libfs_avb/Android.bp
+++ b/fs_mgr/libfs_avb/Android.bp
@@ -27,6 +27,7 @@
 cc_library_static {
     name: "libfs_avb",
     defaults: ["fs_mgr_defaults"],
+    ramdisk_available: true,
     recovery_available: true,
     host_supported: true,
     export_include_dirs: ["include"],
diff --git a/fs_mgr/liblp/Android.bp b/fs_mgr/liblp/Android.bp
index 7e528b1..86ca8f3 100644
--- a/fs_mgr/liblp/Android.bp
+++ b/fs_mgr/liblp/Android.bp
@@ -30,6 +30,7 @@
 cc_library {
     name: "liblp",
     host_supported: true,
+    ramdisk_available: true,
     recovery_available: true,
     defaults: ["fs_mgr_defaults"],
     cppflags: [
diff --git a/fs_mgr/libsnapshot/Android.bp b/fs_mgr/libsnapshot/Android.bp
index 6a764e4..aa1f415 100644
--- a/fs_mgr/libsnapshot/Android.bp
+++ b/fs_mgr/libsnapshot/Android.bp
@@ -118,6 +118,7 @@
     native_coverage : true,
     defaults: ["libsnapshot_defaults"],
     srcs: [":libsnapshot_sources"],
+    ramdisk_available: true,
     recovery_available: true,
     cflags: [
         "-DLIBSNAPSHOT_NO_COW_WRITE",
diff --git a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
index 77ed92c..c0649ca 100644
--- a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
+++ b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
@@ -158,6 +158,13 @@
     ExpectedMergeTarget = 11;
     UnmergedSectorsAfterCompletion = 12;
     UnexpectedMergeState = 13;
+    GetCowPathConsistencyCheck = 14;
+    OpenCowConsistencyCheck = 15;
+    ParseCowConsistencyCheck = 16;
+    OpenCowDirectConsistencyCheck = 17;
+    MemAlignConsistencyCheck = 18;
+    DirectReadConsistencyCheck = 19;
+    WrongMergeCountConsistencyCheck = 20;
 };
 
 // Next: 8
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
index 9ebcfd9..669e58a 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
@@ -143,12 +143,11 @@
 
     void InitializeMerge();
 
+    // Number of copy, replace, and zero ops. Set if InitializeMerge is called.
     void set_total_data_ops(uint64_t size) { total_data_ops_ = size; }
-
     uint64_t total_data_ops() { return total_data_ops_; }
-
+    // Number of copy ops. Set if InitializeMerge is called.
     void set_copy_ops(uint64_t size) { copy_ops_ = size; }
-
     uint64_t total_copy_ops() { return copy_ops_; }
 
     void CloseCowFd() { owned_fd_ = {}; }
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
index 603e896..65034f7 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/snapshot.h
@@ -603,6 +603,8 @@
     MergeResult CheckMergeState(LockedFile* lock, const std::function<bool()>& before_cancel);
     MergeResult CheckTargetMergeState(LockedFile* lock, const std::string& name,
                                       const SnapshotUpdateStatus& update_status);
+    MergeFailureCode CheckMergeConsistency(LockedFile* lock, const std::string& name,
+                                           const SnapshotStatus& update_status);
 
     // Interact with status files under /metadata/ota/snapshots.
     bool WriteSnapshotStatus(LockedFile* lock, const SnapshotStatus& status);
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index e2c03ae..be732ec 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -1126,6 +1126,11 @@
         return MergeResult(UpdateState::Merging);
     }
 
+    auto code = CheckMergeConsistency(lock, name, snapshot_status);
+    if (code != MergeFailureCode::Ok) {
+        return MergeResult(UpdateState::MergeFailed, code);
+    }
+
     // Merging is done. First, update the status file to indicate the merge
     // is complete. We do this before calling OnSnapshotMergeComplete, even
     // though this means the write is potentially wasted work (since in the
@@ -1144,6 +1149,91 @@
     return MergeResult(UpdateState::MergeCompleted, MergeFailureCode::Ok);
 }
 
+// This returns the backing device, not the dm-user layer.
+static std::string GetMappedCowDeviceName(const std::string& snapshot,
+                                          const SnapshotStatus& status) {
+    // If no partition was created (the COW exists entirely on /data), the
+    // device-mapper layering is different than if we had a partition.
+    if (status.cow_partition_size() == 0) {
+        return GetCowImageDeviceName(snapshot);
+    }
+    return GetCowName(snapshot);
+}
+
+MergeFailureCode SnapshotManager::CheckMergeConsistency(LockedFile* lock, const std::string& name,
+                                                        const SnapshotStatus& status) {
+    CHECK(lock);
+
+    if (!status.compression_enabled()) {
+        // Do not try to verify old-style COWs yet.
+        return MergeFailureCode::Ok;
+    }
+
+    auto& dm = DeviceMapper::Instance();
+
+    std::string cow_image_name = GetMappedCowDeviceName(name, status);
+    std::string cow_image_path;
+    if (!dm.GetDmDevicePathByName(cow_image_name, &cow_image_path)) {
+        LOG(ERROR) << "Failed to get path for cow device: " << cow_image_name;
+        return MergeFailureCode::GetCowPathConsistencyCheck;
+    }
+
+    // First pass, count # of ops.
+    size_t num_ops = 0;
+    {
+        unique_fd fd(open(cow_image_path.c_str(), O_RDONLY | O_CLOEXEC));
+        if (fd < 0) {
+            PLOG(ERROR) << "Failed to open " << cow_image_name;
+            return MergeFailureCode::OpenCowConsistencyCheck;
+        }
+
+        CowReader reader;
+        if (!reader.Parse(std::move(fd))) {
+            LOG(ERROR) << "Failed to parse cow " << cow_image_path;
+            return MergeFailureCode::ParseCowConsistencyCheck;
+        }
+
+        for (auto iter = reader.GetOpIter(); !iter->Done(); iter->Next()) {
+            if (!IsMetadataOp(iter->Get())) {
+                num_ops++;
+            }
+        }
+    }
+
+    // Second pass, try as hard as we can to get the actual number of blocks
+    // the system thinks is merged.
+    unique_fd fd(open(cow_image_path.c_str(), O_RDONLY | O_DIRECT | O_SYNC | O_CLOEXEC));
+    if (fd < 0) {
+        PLOG(ERROR) << "Failed to open direct " << cow_image_name;
+        return MergeFailureCode::OpenCowDirectConsistencyCheck;
+    }
+
+    void* addr;
+    size_t page_size = getpagesize();
+    if (posix_memalign(&addr, page_size, page_size) < 0) {
+        PLOG(ERROR) << "posix_memalign with page size " << page_size;
+        return MergeFailureCode::MemAlignConsistencyCheck;
+    }
+
+    // COWs are always at least 2MB, this is guaranteed in snapshot creation.
+    std::unique_ptr<void, decltype(&::free)> buffer(addr, ::free);
+    if (!android::base::ReadFully(fd, buffer.get(), page_size)) {
+        PLOG(ERROR) << "Direct read failed " << cow_image_name;
+        return MergeFailureCode::DirectReadConsistencyCheck;
+    }
+
+    auto header = reinterpret_cast<CowHeader*>(buffer.get());
+    if (header->num_merge_ops != num_ops) {
+        LOG(ERROR) << "COW consistency check failed, expected " << num_ops << " to be merged, "
+                   << "but " << header->num_merge_ops << " were actually recorded.";
+        LOG(ERROR) << "Aborting merge progress for snapshot " << name
+                   << ", will try again next boot";
+        return MergeFailureCode::WrongMergeCountConsistencyCheck;
+    }
+
+    return MergeFailureCode::Ok;
+}
+
 MergeFailureCode SnapshotManager::MergeSecondPhaseSnapshots(LockedFile* lock) {
     std::vector<std::string> snapshots;
     if (!ListSnapshots(lock, &snapshots)) {
@@ -1429,14 +1519,7 @@
             continue;
         }
 
-        // If no partition was created (the COW exists entirely on /data), the
-        // device-mapper layering is different than if we had a partition.
-        std::string cow_image_name;
-        if (snapshot_status.cow_partition_size() == 0) {
-            cow_image_name = GetCowImageDeviceName(snapshot);
-        } else {
-            cow_image_name = GetCowName(snapshot);
-        }
+        std::string cow_image_name = GetMappedCowDeviceName(snapshot, snapshot_status);
 
         std::string cow_image_device;
         if (!dm.GetDmDevicePathByName(cow_image_name, &cow_image_device)) {
diff --git a/fs_mgr/libstorage_literals/Android.bp b/fs_mgr/libstorage_literals/Android.bp
index 5b07168..fd7ea04 100644
--- a/fs_mgr/libstorage_literals/Android.bp
+++ b/fs_mgr/libstorage_literals/Android.bp
@@ -6,6 +6,7 @@
 cc_library_headers {
     name: "libstorage_literals_headers",
     host_supported: true,
+    ramdisk_available: true,
     recovery_available: true,
     export_include_dirs: ["."],
     target: {
diff --git a/gatekeeperd/gatekeeperd.rc b/gatekeeperd/gatekeeperd.rc
index 8b126d5..f572b11 100644
--- a/gatekeeperd/gatekeeperd.rc
+++ b/gatekeeperd/gatekeeperd.rc
@@ -1,4 +1,4 @@
 service gatekeeperd /system/bin/gatekeeperd /data/misc/gatekeeper
     class late_start
     user system
-    writepid /dev/cpuset/system-background/tasks
+    task_profiles ServiceCapacityLow
diff --git a/init/Android.bp b/init/Android.bp
index 1381c1d..3e8d4e3 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -253,11 +253,32 @@
     visibility: ["//packages/modules/Virtualization/microdroid"],
 }
 
-// This currently is only for the VM usecase.
-// TODO(jiyong): replace init_first_stage in Android.mk with this
+soong_config_module_type {
+    name: "init_first_stage_cc_defaults",
+    module_type: "cc_defaults",
+    config_namespace: "ANDROID",
+    bool_variables: ["BOARD_BUILD_SYSTEM_ROOT_IMAGE", "BOARD_USES_RECOVERY_AS_BOOT"],
+    properties: ["installable"],
+}
+
+// Do not install init_first_stage even with mma if we're system-as-root.
+// Otherwise, it will overwrite the symlink.
+init_first_stage_cc_defaults {
+    name: "init_first_stage_defaults",
+    soong_config_variables: {
+        BOARD_BUILD_SYSTEM_ROOT_IMAGE: {
+            installable: false,
+        },
+        BOARD_USES_RECOVERY_AS_BOOT: {
+            installable: false,
+        },
+    },
+}
+
 cc_binary {
-    name: "init_first_stage_soong",
-    stem: "init_vendor",
+    name: "init_first_stage",
+    stem: "init",
+    defaults: ["init_first_stage_defaults"],
 
     srcs: [
         "block_dev_initializer.cpp",
@@ -313,6 +334,7 @@
     ],
 
     static_executable: true,
+    system_shared_libs: [],
 
     cflags: [
         "-Wall",
@@ -363,8 +385,23 @@
 
     sanitize: {
         misc_undefined: ["signed-integer-overflow"],
+
+        // First stage init is weird: it may start without stdout/stderr, and no /proc.
         hwaddress: false,
     },
+
+    // Install adb_debug.prop into debug ramdisk.
+    // This allows adb root on a user build, when debug ramdisk is used.
+    required: ["adb_debug.prop"],
+
+    ramdisk: true,
+
+    install_in_root: true,
+}
+
+phony {
+    name: "init_system",
+    required: ["init_second_stage"],
 }
 
 // Tests
diff --git a/init/Android.mk b/init/Android.mk
index 3c7d95a..c08fe03 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -2,153 +2,6 @@
 
 LOCAL_PATH:= $(call my-dir)
 
--include system/sepolicy/policy_version.mk
-
-# --
-
-ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
-init_options += \
-    -DALLOW_FIRST_STAGE_CONSOLE=1 \
-    -DALLOW_LOCAL_PROP_OVERRIDE=1 \
-    -DALLOW_PERMISSIVE_SELINUX=1 \
-    -DREBOOT_BOOTLOADER_ON_PANIC=1 \
-    -DWORLD_WRITABLE_KMSG=1 \
-    -DDUMP_ON_UMOUNT_FAILURE=1
-else
-init_options += \
-    -DALLOW_FIRST_STAGE_CONSOLE=0 \
-    -DALLOW_LOCAL_PROP_OVERRIDE=0 \
-    -DALLOW_PERMISSIVE_SELINUX=0 \
-    -DREBOOT_BOOTLOADER_ON_PANIC=0 \
-    -DWORLD_WRITABLE_KMSG=0 \
-    -DDUMP_ON_UMOUNT_FAILURE=0
-endif
-
-ifneq (,$(filter eng,$(TARGET_BUILD_VARIANT)))
-init_options += \
-    -DSHUTDOWN_ZERO_TIMEOUT=1
-else
-init_options += \
-    -DSHUTDOWN_ZERO_TIMEOUT=0
-endif
-
-init_options += -DLOG_UEVENTS=0 \
-    -DSEPOLICY_VERSION=$(POLICYVERS)
-
-init_cflags += \
-    $(init_options) \
-    -Wall -Wextra \
-    -Wno-unused-parameter \
-    -Werror \
-
-# --
-
-# Do not build this even with mmma if we're system-as-root, otherwise it will overwrite the symlink.
-ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
-include $(CLEAR_VARS)
-LOCAL_CPPFLAGS := $(init_cflags)
-LOCAL_SRC_FILES := \
-    block_dev_initializer.cpp \
-    devices.cpp \
-    first_stage_console.cpp \
-    first_stage_init.cpp \
-    first_stage_main.cpp \
-    first_stage_mount.cpp \
-    reboot_utils.cpp \
-    selabel.cpp \
-    selinux.cpp \
-    service_utils.cpp \
-    snapuserd_transition.cpp \
-    switch_root.cpp \
-    uevent_listener.cpp \
-    util.cpp \
-
-LOCAL_MODULE := init_first_stage
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
-LOCAL_MODULE_STEM := init
-
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-
-LOCAL_MODULE_PATH := $(TARGET_RAMDISK_OUT)
-LOCAL_UNSTRIPPED_PATH := $(TARGET_RAMDISK_OUT_UNSTRIPPED)
-
-# Install adb_debug.prop into debug ramdisk.
-# This allows adb root on a user build, when debug ramdisk is used.
-LOCAL_REQUIRED_MODULES := \
-   adb_debug.prop \
-
-# Set up the directories that first stage init mounts on.
-
-my_ramdisk_dirs := \
-    debug_ramdisk \
-    dev \
-    metadata \
-    mnt \
-    proc \
-    second_stage_resources \
-    sys \
-
-LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_RAMDISK_OUT)/,$(my_ramdisk_dirs))
-ifeq (true,$(BOARD_USES_GENERIC_KERNEL_IMAGE))
-    LOCAL_POST_INSTALL_CMD += $(addprefix $(TARGET_RAMDISK_OUT)/first_stage_ramdisk/,$(my_ramdisk_dirs))
-endif
-
-my_ramdisk_dirs :=
-
-LOCAL_STATIC_LIBRARIES := \
-    libc++fs \
-    libfs_avb \
-    libfs_mgr \
-    libfec \
-    libfec_rs \
-    libsquashfs_utils \
-    liblogwrap \
-    libext4_utils \
-    libcrypto_utils \
-    libsparse \
-    libavb \
-    libkeyutils \
-    liblp \
-    libcutils \
-    libbase \
-    liblog \
-    libcrypto_static \
-    libdl \
-    libz \
-    libselinux \
-    libcap \
-    libgsi \
-    libcom.android.sysprop.apex \
-    liblzma \
-    libunwindstack_no_dex \
-    libbacktrace_no_dex \
-    libmodprobe \
-    libext2_uuid \
-    libprotobuf-cpp-lite \
-    libsnapshot_cow \
-    libsnapshot_init \
-    update_metadata-protos \
-    libprocinfo \
-
-LOCAL_SANITIZE := signed-integer-overflow
-# First stage init is weird: it may start without stdout/stderr, and no /proc.
-LOCAL_NOSANITIZE := hwaddress
-include $(BUILD_EXECUTABLE)
-endif
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := init_system
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
-LOCAL_REQUIRED_MODULES := \
-   init_second_stage \
-
-include $(BUILD_PHONY_PACKAGE)
-
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := init_vendor
@@ -156,8 +9,10 @@
 LOCAL_LICENSE_CONDITIONS := notice
 LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
 ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
+ifneq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
 LOCAL_REQUIRED_MODULES := \
    init_first_stage \
 
-endif
+endif  # BOARD_USES_RECOVERY_AS_BOOT
+endif  # BOARD_BUILD_SYSTEM_ROOT_IMAGE
 include $(BUILD_PHONY_PACKAGE)
diff --git a/init/reboot_utils.cpp b/init/reboot_utils.cpp
index 98f6857..b3fa9fd 100644
--- a/init/reboot_utils.cpp
+++ b/init/reboot_utils.cpp
@@ -31,6 +31,7 @@
 
 #include "capabilities.h"
 #include "reboot_utils.h"
+#include "util.h"
 
 namespace android {
 namespace init {
@@ -38,31 +39,51 @@
 static std::string init_fatal_reboot_target = "bootloader";
 static bool init_fatal_panic = false;
 
+// this needs to read the /proc/* files directly because it is called before
+// ro.boot.* properties are initialized
 void SetFatalRebootTarget(const std::optional<std::string>& reboot_target) {
     std::string cmdline;
     android::base::ReadFileToString("/proc/cmdline", &cmdline);
     cmdline = android::base::Trim(cmdline);
 
-    const char kInitFatalPanicString[] = "androidboot.init_fatal_panic=true";
-    init_fatal_panic = cmdline.find(kInitFatalPanicString) != std::string::npos;
+    const std::string kInitFatalPanicParamString = "androidboot.init_fatal_panic";
+    if (cmdline.find(kInitFatalPanicParamString) == std::string::npos) {
+        init_fatal_panic = false;
+        ImportBootconfig(
+                [kInitFatalPanicParamString](const std::string& key, const std::string& value) {
+                    if (key == kInitFatalPanicParamString && value == "true") {
+                        init_fatal_panic = true;
+                    }
+                });
+    } else {
+        const std::string kInitFatalPanicString = kInitFatalPanicParamString + "=true";
+        init_fatal_panic = cmdline.find(kInitFatalPanicString) != std::string::npos;
+    }
 
     if (reboot_target) {
         init_fatal_reboot_target = *reboot_target;
         return;
     }
 
-    const char kRebootTargetString[] = "androidboot.init_fatal_reboot_target=";
+    const std::string kRebootTargetString = "androidboot.init_fatal_reboot_target";
     auto start_pos = cmdline.find(kRebootTargetString);
     if (start_pos == std::string::npos) {
-        return;  // We already default to bootloader if no setting is provided.
-    }
-    start_pos += sizeof(kRebootTargetString) - 1;
+        ImportBootconfig([kRebootTargetString](const std::string& key, const std::string& value) {
+            if (key == kRebootTargetString) {
+                init_fatal_reboot_target = value;
+            }
+        });
+        // We already default to bootloader if no setting is provided.
+    } else {
+        const std::string kRebootTargetStringPattern = kRebootTargetString + "=";
+        start_pos += sizeof(kRebootTargetStringPattern) - 1;
 
-    auto end_pos = cmdline.find(' ', start_pos);
-    // if end_pos isn't found, then we've run off the end, but this is okay as this is the last
-    // entry, and -1 is a valid size for string::substr();
-    auto size = end_pos == std::string::npos ? -1 : end_pos - start_pos;
-    init_fatal_reboot_target = cmdline.substr(start_pos, size);
+        auto end_pos = cmdline.find(' ', start_pos);
+        // if end_pos isn't found, then we've run off the end, but this is okay as this is the last
+        // entry, and -1 is a valid size for string::substr();
+        auto size = end_pos == std::string::npos ? -1 : end_pos - start_pos;
+        init_fatal_reboot_target = cmdline.substr(start_pos, size);
+    }
 }
 
 bool IsRebootCapable() {
diff --git a/libcrypto_utils/Android.bp b/libcrypto_utils/Android.bp
index b33d46d..c8a183b 100644
--- a/libcrypto_utils/Android.bp
+++ b/libcrypto_utils/Android.bp
@@ -21,6 +21,7 @@
 cc_library {
     name: "libcrypto_utils",
     vendor_available: true,
+    ramdisk_available: true,
     recovery_available: true,
     vndk: {
         enabled: true,
diff --git a/libkeyutils/Android.bp b/libkeyutils/Android.bp
index 86f68fb..a940b8c 100644
--- a/libkeyutils/Android.bp
+++ b/libkeyutils/Android.bp
@@ -15,6 +15,7 @@
     name: "libkeyutils",
     cflags: ["-Werror"],
     defaults: ["linux_bionic_supported"],
+    ramdisk_available: true,
     recovery_available: true,
     export_include_dirs: ["include/"],
     local_include_dirs: ["include/"],
diff --git a/libkeyutils/NOTICE b/libkeyutils/NOTICE
new file mode 100644
index 0000000..5828550
--- /dev/null
+++ b/libkeyutils/NOTICE
@@ -0,0 +1,25 @@
+Copyright (C) 2017 The Android Open Source Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+ * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in
+   the documentation and/or other materials provided with the
+   distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/libmodprobe/Android.bp b/libmodprobe/Android.bp
index ba11dc9..525a880 100644
--- a/libmodprobe/Android.bp
+++ b/libmodprobe/Android.bp
@@ -8,6 +8,7 @@
         "-Werror",
     ],
     vendor_available: true,
+    ramdisk_available: true,
     recovery_available: true,
     srcs: [
         "libmodprobe.cpp",
diff --git a/llkd/llkd-debuggable.rc b/llkd/llkd-debuggable.rc
index 4b11b1c..8697e9a 100644
--- a/llkd/llkd-debuggable.rc
+++ b/llkd/llkd-debuggable.rc
@@ -16,4 +16,4 @@
     capabilities KILL IPC_LOCK SYS_PTRACE DAC_OVERRIDE SYS_ADMIN
     file /dev/kmsg w
     file /proc/sysrq-trigger w
-    writepid /dev/cpuset/system-background/tasks
+    task_profiles ServiceCapacityLow
diff --git a/llkd/llkd.rc b/llkd/llkd.rc
index b1f96a8..5d701fc 100644
--- a/llkd/llkd.rc
+++ b/llkd/llkd.rc
@@ -42,4 +42,4 @@
     capabilities KILL IPC_LOCK
     file /dev/kmsg w
     file /proc/sysrq-trigger w
-    writepid /dev/cpuset/system-background/tasks
+    task_profiles ServiceCapacityLow
diff --git a/rootdir/Android.bp b/rootdir/Android.bp
index ae21633..e98733a 100644
--- a/rootdir/Android.bp
+++ b/rootdir/Android.bp
@@ -45,4 +45,11 @@
     src: "etc/public.libraries.android.txt",
     filename: "public.libraries.txt",
     installable: false,
-}
\ No newline at end of file
+}
+
+// adb_debug.prop in debug ramdisk
+prebuilt_root {
+    name: "adb_debug.prop",
+    src: "adb_debug.prop",
+    debug_ramdisk: true,
+}
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 99d8f9a..9b80575 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -210,15 +210,4 @@
 	$(hide) $(foreach lib,$(PRIVATE_SANITIZER_RUNTIME_LIBRARIES), \
 		echo $(lib) >> $@;)
 
-#######################################
-# adb_debug.prop in debug ramdisk
-include $(CLEAR_VARS)
-LOCAL_MODULE := adb_debug.prop
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_DEBUG_RAMDISK_OUT)
-include $(BUILD_PREBUILT)
-
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/rootdir/init.zygote32.rc b/rootdir/init.zygote32.rc
index 9469a48..0090841 100644
--- a/rootdir/init.zygote32.rc
+++ b/rootdir/init.zygote32.rc
@@ -12,5 +12,5 @@
     onrestart restart media
     onrestart restart netd
     onrestart restart wificond
-    writepid /dev/cpuset/foreground/tasks
+    task_profiles ProcessCapacityHigh
     critical window=${zygote.critical_window.minute:-off} target=zygote-fatal
diff --git a/rootdir/init.zygote64.rc b/rootdir/init.zygote64.rc
index 98dc088..63772bd 100644
--- a/rootdir/init.zygote64.rc
+++ b/rootdir/init.zygote64.rc
@@ -12,5 +12,5 @@
     onrestart restart media
     onrestart restart netd
     onrestart restart wificond
-    writepid /dev/cpuset/foreground/tasks
+    task_profiles ProcessCapacityHigh
     critical window=${zygote.critical_window.minute:-off} target=zygote-fatal
diff --git a/storaged/storaged.rc b/storaged/storaged.rc
index 0614fad..7085743 100644
--- a/storaged/storaged.rc
+++ b/storaged/storaged.rc
@@ -3,6 +3,6 @@
     capabilities DAC_READ_SEARCH
     priority 10
     file /d/mmc0/mmc0:0001/ext_csd r
-    writepid /dev/cpuset/system-background/tasks
+    task_profiles ServiceCapacityLow
     user root
     group package_info