Merge "Doc Thread requirement."
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index 9ae2c37..5c07eb0 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -130,12 +130,10 @@
         "-Werror",
         "-Wvla",
         "-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION",
+        "-Wthread-safety",
     ],
     rtti: true,
 
-    clang_cflags: [
-        "-Wthread-safety",
-    ],
 }
 
 cc_binary {
@@ -215,7 +213,7 @@
         "-Werror",
         "-Wunreachable-code",
         "-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION",
-        "-D_FILE_OFFSET_BITS=64"
+        "-D_FILE_OFFSET_BITS=64",
     ],
 
     target: {
@@ -411,7 +409,7 @@
         ":fastboot_test_vendor_ramdisk_replace",
         ":fastboot_test_vendor_boot_v3",
         ":fastboot_test_vendor_boot_v4_without_frag",
-        ":fastboot_test_vendor_boot_v4_with_frag"
+        ":fastboot_test_vendor_boot_v4_with_frag",
     ],
 }
 
diff --git a/fastboot/fuzzy_fastboot/Android.bp b/fastboot/fuzzy_fastboot/Android.bp
index 159c314..2031170 100644
--- a/fastboot/fuzzy_fastboot/Android.bp
+++ b/fastboot/fuzzy_fastboot/Android.bp
@@ -9,6 +9,7 @@
 
 cc_test_host {
   name: "fuzzy_fastboot",
+  isolated: false,
   compile_multilib: "first",
 
   srcs: [
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 6863894..7639ce5 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -124,8 +124,8 @@
     FS_STAT_RO_MOUNT_FAILED = 0x0040,
     FS_STAT_RO_UNMOUNT_FAILED = 0x0080,
     FS_STAT_FULL_MOUNT_FAILED = 0x0100,
-    FS_STAT_E2FSCK_FAILED = 0x0200,
-    FS_STAT_E2FSCK_FS_FIXED = 0x0400,
+    FS_STAT_FSCK_FAILED = 0x0200,
+    FS_STAT_FSCK_FS_FIXED = 0x0400,
     FS_STAT_INVALID_MAGIC = 0x0800,
     FS_STAT_TOGGLE_QUOTAS_FAILED = 0x10000,
     FS_STAT_SET_RESERVED_BLOCKS_FAILED = 0x20000,
@@ -136,7 +136,6 @@
 };
 
 static void log_fs_stat(const std::string& blk_device, int fs_stat) {
-    if ((fs_stat & FS_STAT_IS_EXT4) == 0) return; // only log ext4
     std::string msg =
             android::base::StringPrintf("\nfs_stat,%s,0x%x\n", blk_device.c_str(), fs_stat);
     android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(FSCK_LOG_FILE, O_WRONLY | O_CLOEXEC |
@@ -166,7 +165,7 @@
     return fs_stat &
            (FS_STAT_E2FSCK_F_ALWAYS | FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED |
             FS_STAT_RO_MOUNT_FAILED | FS_STAT_RO_UNMOUNT_FAILED | FS_STAT_FULL_MOUNT_FAILED |
-            FS_STAT_E2FSCK_FAILED | FS_STAT_TOGGLE_QUOTAS_FAILED |
+            FS_STAT_FSCK_FAILED | FS_STAT_TOGGLE_QUOTAS_FAILED |
             FS_STAT_SET_RESERVED_BLOCKS_FAILED | FS_STAT_ENABLE_ENCRYPTION_FAILED);
 }
 
@@ -255,10 +254,10 @@
             if (ret < 0) {
                 /* No need to check for error in fork, we can't really handle it now */
                 LERROR << "Failed trying to run " << E2FSCK_BIN;
-                *fs_stat |= FS_STAT_E2FSCK_FAILED;
+                *fs_stat |= FS_STAT_FSCK_FAILED;
             } else if (status != 0) {
                 LINFO << "e2fsck returned status 0x" << std::hex << status;
-                *fs_stat |= FS_STAT_E2FSCK_FS_FIXED;
+                *fs_stat |= FS_STAT_FSCK_FS_FIXED;
             }
         }
     } else if (is_f2fs(fs_type)) {
@@ -271,16 +270,20 @@
             LINFO << "Running " << F2FS_FSCK_BIN << " -f -c 10000 --debug-cache "
                   << realpath(blk_device);
             ret = logwrap_fork_execvp(ARRAY_SIZE(f2fs_fsck_forced_argv), f2fs_fsck_forced_argv,
-                                      &status, false, LOG_KLOG | LOG_FILE, false, nullptr);
+                                      &status, false, LOG_KLOG | LOG_FILE, false, FSCK_LOG_FILE);
         } else {
             LINFO << "Running " << F2FS_FSCK_BIN << " -a -c 10000 --debug-cache "
                   << realpath(blk_device);
             ret = logwrap_fork_execvp(ARRAY_SIZE(f2fs_fsck_argv), f2fs_fsck_argv, &status, false,
-                                      LOG_KLOG | LOG_FILE, false, nullptr);
+                                      LOG_KLOG | LOG_FILE, false, FSCK_LOG_FILE);
         }
         if (ret < 0) {
             /* No need to check for error in fork, we can't really handle it now */
             LERROR << "Failed trying to run " << F2FS_FSCK_BIN;
+            *fs_stat |= FS_STAT_FSCK_FAILED;
+        } else if (status != 0) {
+            LINFO << F2FS_FSCK_BIN << " returned status 0x" << std::hex << status;
+            *fs_stat |= FS_STAT_FSCK_FS_FIXED;
         }
     }
     android::base::SetProperty("ro.boottime.init.fsck." + Basename(target),
@@ -1911,6 +1914,7 @@
         while (retry_count-- > 0) {
             if (!__mount(n_blk_device, mount_point, fstab_entry)) {
                 fs_stat &= ~FS_STAT_FULL_MOUNT_FAILED;
+                log_fs_stat(fstab_entry.blk_device, fs_stat);
                 return FS_MGR_DOMNT_SUCCESS;
             } else {
                 if (retry_count <= 0) break;  // run check_fs only once
diff --git a/fs_mgr/liblp/TEST_MAPPING b/fs_mgr/liblp/TEST_MAPPING
index 875ccb0..cf0d22b 100644
--- a/fs_mgr/liblp/TEST_MAPPING
+++ b/fs_mgr/liblp/TEST_MAPPING
@@ -4,7 +4,7 @@
       "name": "liblp_test"
     }
   ],
-  "hwasan-postsubmit": [
+  "hwasan-presubmit": [
     {
       "name": "liblp_test"
     }
diff --git a/init/init_test.cpp b/init/init_test.cpp
index 8550ec8..8c19d5f 100644
--- a/init/init_test.cpp
+++ b/init/init_test.cpp
@@ -156,6 +156,7 @@
 
     ServiceList service_list;
     TestInitText(init_script, test_function_map, commands, &service_list);
+    EXPECT_EQ(3, num_executed);
 }
 
 TEST(init, OverrideService) {
diff --git a/init/service.cpp b/init/service.cpp
index 077477a..95a5328 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -288,6 +288,10 @@
 
     if (flags_ & SVC_EXEC) UnSetExec();
 
+    if (name_ == "zygote" || name_ == "zygote64") {
+        removeAllEmptyProcessGroups();
+    }
+
     if (flags_ & SVC_TEMPORARY) return;
 
     pid_ = 0;
diff --git a/libprocessgroup/include/processgroup/processgroup.h b/libprocessgroup/include/processgroup/processgroup.h
index c5badc9..39b9f3f 100644
--- a/libprocessgroup/include/processgroup/processgroup.h
+++ b/libprocessgroup/include/processgroup/processgroup.h
@@ -67,6 +67,7 @@
 bool setProcessGroupLimit(uid_t uid, int initialPid, int64_t limitInBytes);
 
 void removeAllProcessGroups(void);
+void removeAllEmptyProcessGroups(void);
 
 // Provides the path for an attribute in a specific process group
 // Returns false in case of error, true in case of success
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index e3a80e9..267e62c 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -200,7 +200,7 @@
     return ret;
 }
 
-static bool RemoveUidProcessGroups(const std::string& uid_path) {
+static bool RemoveUidProcessGroups(const std::string& uid_path, bool empty_only) {
     std::unique_ptr<DIR, decltype(&closedir)> uid(opendir(uid_path.c_str()), closedir);
     bool empty = true;
     if (uid != NULL) {
@@ -215,6 +215,21 @@
             }
 
             auto path = StringPrintf("%s/%s", uid_path.c_str(), dir->d_name);
+            if (empty_only) {
+                struct stat st;
+                auto procs_file = StringPrintf("%s/%s", path.c_str(),
+                                               PROCESSGROUP_CGROUP_PROCS_FILE);
+                if (stat(procs_file.c_str(), &st) == -1) {
+                    PLOG(ERROR) << "Failed to get stats for " << procs_file;
+                    continue;
+                }
+                if (st.st_size > 0) {
+                    // skip non-empty groups
+                    LOG(VERBOSE) << "Skipping non-empty group " << path;
+                    empty = false;
+                    continue;
+                }
+            }
             LOG(VERBOSE) << "Removing " << path;
             if (rmdir(path.c_str()) == -1) {
                 if (errno != EBUSY) {
@@ -227,9 +242,7 @@
     return empty;
 }
 
-void removeAllProcessGroups() {
-    LOG(VERBOSE) << "removeAllProcessGroups()";
-
+void removeAllProcessGroupsInternal(bool empty_only) {
     std::vector<std::string> cgroups;
     std::string path, memcg_apps_path;
 
@@ -256,7 +269,7 @@
                 }
 
                 auto path = StringPrintf("%s/%s", cgroup_root_path.c_str(), dir->d_name);
-                if (!RemoveUidProcessGroups(path)) {
+                if (!RemoveUidProcessGroups(path, empty_only)) {
                     LOG(VERBOSE) << "Skip removing " << path;
                     continue;
                 }
@@ -269,6 +282,16 @@
     }
 }
 
+void removeAllProcessGroups() {
+    LOG(VERBOSE) << "removeAllProcessGroups()";
+    removeAllProcessGroupsInternal(false);
+}
+
+void removeAllEmptyProcessGroups() {
+    LOG(VERBOSE) << "removeAllEmptyProcessGroups()";
+    removeAllProcessGroupsInternal(true);
+}
+
 /**
  * Process groups are primarily created by the Zygote, meaning that uid/pid groups are created by
  * the user root. Ownership for the newly created cgroup and all of its files must thus be
diff --git a/libstats/socket_lazy/TEST_MAPPING b/libstats/socket_lazy/TEST_MAPPING
index b182660..03506cd 100644
--- a/libstats/socket_lazy/TEST_MAPPING
+++ b/libstats/socket_lazy/TEST_MAPPING
@@ -4,7 +4,7 @@
       "name" : "libstatssocket_lazy_test"
     }
   ],
-  "hwasan-postsubmit" : [
+  "hwasan-presubmit" : [
     {
       "name" : "libstatssocket_lazy_test"
     }
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 1b29285..f663671 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -44,14 +44,6 @@
     export_include_dirs: ["include"],
 
     target: {
-        android: {
-            header_libs: ["libbacktrace_headers"],
-            export_header_lib_headers: ["libbacktrace_headers"],
-        },
-        host_linux: {
-            header_libs: ["libbacktrace_headers"],
-            export_header_lib_headers: ["libbacktrace_headers"],
-        },
         linux_bionic: {
             enabled: true,
         },
@@ -196,7 +188,7 @@
 
     shared_libs: [
         "libutils",
-        "libbacktrace",
+        "libunwindstack",
     ],
 
     target: {
diff --git a/libutils/CallStack.cpp b/libutils/CallStack.cpp
index fe6f33d..f19ba6a 100644
--- a/libutils/CallStack.cpp
+++ b/libutils/CallStack.cpp
@@ -20,7 +20,7 @@
 #include <utils/Errors.h>
 #include <utils/Log.h>
 
-#include <backtrace/Backtrace.h>
+#include <unwindstack/AndroidUnwinder.h>
 
 #define CALLSTACK_WEAK  // Don't generate weak definitions.
 #include <utils/CallStack.h>
@@ -39,14 +39,25 @@
 }
 
 void CallStack::update(int32_t ignoreDepth, pid_t tid) {
+    if (ignoreDepth < 0) {
+        ignoreDepth = 0;
+    }
+
     mFrameLines.clear();
 
-    std::unique_ptr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, tid));
-    if (!backtrace->Unwind(ignoreDepth)) {
-        ALOGW("%s: Failed to unwind callstack.", __FUNCTION__);
+    unwindstack::AndroidLocalUnwinder unwinder;
+    unwindstack::AndroidUnwinderData data;
+    std::optional<pid_t> tid_val;
+    if (tid != -1) {
+        *tid_val = tid;
     }
-    for (size_t i = 0; i < backtrace->NumFrames(); i++) {
-      mFrameLines.push_back(String8(backtrace->FormatFrameData(i).c_str()));
+    if (!unwinder.Unwind(tid_val, data)) {
+        ALOGW("%s: Failed to unwind callstack: %s", __FUNCTION__, data.GetErrorString().c_str());
+    }
+    for (size_t i = ignoreDepth; i < data.frames.size(); i++) {
+        auto& frame = data.frames[i];
+        frame.num -= ignoreDepth;
+        mFrameLines.push_back(String8(unwinder.FormatFrame(frame).c_str()));
     }
 }
 
diff --git a/libutils/include/utils/CallStack.h b/libutils/include/utils/CallStack.h
index 7a4a345..fe4d4f5 100644
--- a/libutils/include/utils/CallStack.h
+++ b/libutils/include/utils/CallStack.h
@@ -20,7 +20,6 @@
 #include <memory>
 
 #include <android/log.h>
-#include <backtrace/backtrace_constants.h>
 #include <utils/String8.h>
 #include <utils/Vector.h>
 
@@ -59,7 +58,7 @@
 
     // Immediately collect the stack traces for the specified thread.
     // The default is to dump the stack of the current call.
-    void update(int32_t ignoreDepth = 1, pid_t tid = BACKTRACE_CURRENT_THREAD);
+    void update(int32_t ignoreDepth = 1, pid_t tid = -1);
 
     // Dump a stack trace to the log using the supplied logtag.
     void log(const char* logtag,
diff --git a/property_service/TEST_MAPPING b/property_service/TEST_MAPPING
index 20f6c84..7b02b51 100644
--- a/property_service/TEST_MAPPING
+++ b/property_service/TEST_MAPPING
@@ -4,7 +4,7 @@
       "name": "propertyinfoserializer_tests"
     }
   ],
-  "hwasan-postsubmit": [
+  "hwasan-presubmit": [
     {
       "name": "propertyinfoserializer_tests"
     }
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 56e8f31..69e06d0 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -86,6 +86,10 @@
     mkdir /dev/sys/fs 0755 system system
     mkdir /dev/sys/block 0755 system system
 
+    # Create location for fs_mgr to store abbreviated output from filesystem
+    # checker programs.
+    mkdir /dev/fscklogs 0770 root system
+
 # Run boringssl self test for each ABI so that later processes can skip it. http://b/139348610
 on early-init && property:ro.product.cpu.abilist32=*
     exec_start boringssl_self_test32
@@ -447,10 +451,6 @@
 
     mount bpf bpf /sys/fs/bpf nodev noexec nosuid
 
-    # Create location for fs_mgr to store abbreviated output from filesystem
-    # checker programs.
-    mkdir /dev/fscklogs 0770 root system
-
     # pstore/ramoops previous console log
     mount pstore pstore /sys/fs/pstore nodev noexec nosuid
     chown system log /sys/fs/pstore
@@ -828,11 +828,11 @@
     # directory used for odsign metrics
     mkdir /data/misc/odsign/metrics 0770 root system
 
-    # Directory for VirtualizationService temporary image files. Always create
-    # a fresh new empty directory to remove any stale files from the previous
-    # boot.
-    rmdir /data/misc/virtualizationservice
-    mkdir /data/misc/virtualizationservice 0700 system system
+    # Directory for VirtualizationService temporary image files.
+    # Delete any stale files owned by the old virtualizationservice uid (b/230056726).
+    chmod 0770 /data/misc/virtualizationservice
+    exec - virtualizationservice system -- /bin/rm -rf /data/misc/virtualizationservice
+    mkdir /data/misc/virtualizationservice 0770 system system
 
     mkdir /data/preloads 0775 system system encryption=None
 
@@ -1135,9 +1135,11 @@
     chown system system /sys/devices/system/cpu/cpufreq/interactive/io_is_busy
     chmod 0660 /sys/devices/system/cpu/cpufreq/interactive/io_is_busy
 
-    # Assume SMP uses shared cpufreq policy for all CPUs
+    # Assume SMP uses shared cpufreq policy for all CPUs in the same cluster.
+    # Here is for initial cluster (cpu0...) which is not hot-plugged in most cases.
+    # The rest of hot-plugged clusters are covered by ueventd.rc.
     chown system system /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
-    chmod 0660 /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
+    chmod 0664 /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
 
     chown system system /sys/class/leds/vibrator/trigger
     chown system system /sys/class/leds/vibrator/activate
diff --git a/trusty/keymaster/keymint/TEST_MAPPING b/trusty/keymaster/keymint/TEST_MAPPING
index ae24fb4..6671355 100644
--- a/trusty/keymaster/keymint/TEST_MAPPING
+++ b/trusty/keymaster/keymint/TEST_MAPPING
@@ -4,7 +4,7 @@
       "name" : "vts_treble_vintf_framework_test"
     }
   ],
-  "hwasan-postsubmit" : [
+  "hwasan-presubmit" : [
     {
       "name" : "vts_treble_vintf_framework_test"
     }