Merge "dm_test.cpp: DeleteDeviceWithTimeout asserts that unique path is deleted" into main
diff --git a/fs_mgr/TEST_MAPPING b/fs_mgr/TEST_MAPPING
index edecd7c..1989a5c 100644
--- a/fs_mgr/TEST_MAPPING
+++ b/fs_mgr/TEST_MAPPING
@@ -42,9 +42,6 @@
       "name": "liblp_test"
     },
     {
-      "name": "vts_libsnapshot_test"
-    },
-    {
       "name": "vab_legacy_tests"
     },
     // TODO(b/279009697):
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index af2b35a..8c0c1ef 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -16,7 +16,6 @@
 
 #include "fs_mgr.h"
 
-#include <ctype.h>
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -819,9 +818,13 @@
 // __mount(): wrapper around the mount() system call which also
 // sets the underlying block device to read-only if the mount is read-only.
 // See "man 2 mount" for return values.
-static int __mount(const std::string& source, const std::string& target, const FstabEntry& entry) {
+static int __mount(const std::string& source, const std::string& target, const FstabEntry& entry,
+                   bool read_only = false) {
     errno = 0;
     unsigned long mountflags = entry.flags;
+    if (read_only) {
+        mountflags |= MS_RDONLY;
+    }
     int ret = 0;
     int save_errno = 0;
     int gc_allowance = 0;
@@ -915,6 +918,10 @@
     return true;
 }
 
+static bool should_use_metadata_encryption(const FstabEntry& entry) {
+    return !entry.metadata_key_dir.empty() && entry.fs_mgr_flags.file_encryption;
+}
+
 // Tries to mount any of the consecutive fstab entries that match
 // the mountpoint of the one given by fstab[start_idx].
 //
@@ -922,8 +929,7 @@
 // attempted_idx: On return, will indicate which fstab entry
 //     succeeded. In case of failure, it will be the start_idx.
 // Sets errno to match the 1st mount failure on failure.
-static bool mount_with_alternatives(Fstab& fstab, int start_idx, int* end_idx,
-                                    int* attempted_idx) {
+static bool mount_with_alternatives(Fstab& fstab, int start_idx, int* end_idx, int* attempted_idx) {
     unsigned long i;
     int mount_errno = 0;
     bool mounted = false;
@@ -961,8 +967,15 @@
         }
 
         int retry_count = 2;
+        const auto read_only = should_use_metadata_encryption(fstab[i]);
+        if (read_only) {
+            LOG(INFO) << "Mount point " << fstab[i].blk_device << " @ " << fstab[i].mount_point
+                      << " uses metadata encryption, which means we need to unmount it later and "
+                         "call encryptFstab/encrypt_inplace. To avoid file operations before "
+                         "encryption, we will mount it as read-only first";
+        }
         while (retry_count-- > 0) {
-            if (!__mount(fstab[i].blk_device, fstab[i].mount_point, fstab[i])) {
+            if (!__mount(fstab[i].blk_device, fstab[i].mount_point, fstab[i], read_only)) {
                 *attempted_idx = i;
                 mounted = true;
                 if (i != start_idx) {
@@ -1054,10 +1067,6 @@
     return false;
 }
 
-static bool should_use_metadata_encryption(const FstabEntry& entry) {
-    return !entry.metadata_key_dir.empty() && entry.fs_mgr_flags.file_encryption;
-}
-
 // Check to see if a mountable volume has encryption requirements
 static int handle_encryptable(const FstabEntry& entry) {
     if (should_use_metadata_encryption(entry)) {
@@ -1541,6 +1550,7 @@
                 }
                 encryptable = status;
                 if (status == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) {
+                    fs_mgr_set_blk_ro(attempted_entry.blk_device, false);
                     if (!call_vdc({"cryptfs", "encryptFstab", attempted_entry.blk_device,
                                    attempted_entry.mount_point, wiped ? "true" : "false",
                                    attempted_entry.fs_type, attempted_entry.zoned_device},
@@ -1978,6 +1988,8 @@
                 if (retry_count <= 0) break;  // run check_fs only once
                 if (!first_mount_errno) first_mount_errno = errno;
                 mount_errors++;
+                PERROR << "Cannot mount filesystem on " << n_blk_device << " at " << mount_point
+                       << " with fstype " << fstab_entry.fs_type;
                 fs_stat |= FS_STAT_FULL_MOUNT_FAILED;
                 // try again after fsck
                 check_fs(n_blk_device, fstab_entry.fs_type, mount_point, &fs_stat);
diff --git a/fs_mgr/libsnapshot/snapuserd/Android.bp b/fs_mgr/libsnapshot/snapuserd/Android.bp
index 6b8e084..bd296a3 100644
--- a/fs_mgr/libsnapshot/snapuserd/Android.bp
+++ b/fs_mgr/libsnapshot/snapuserd/Android.bp
@@ -86,10 +86,15 @@
         "libext4_utils",
         "libsnapshot_cow",
         "liburing",
+        "libprocessgroup",
+        "libjsoncpp",
+        "libcgrouprc",
+        "libcgrouprc_format",
     ],
     include_dirs: ["bionic/libc/kernel"],
     export_include_dirs: ["include"],
     header_libs: [
+        "libcutils_headers",
         "libstorage_literals_headers",
     ],
     ramdisk_available: true,
@@ -126,6 +131,10 @@
         "liblog",
         "libsnapshot_cow",
         "libsnapuserd",
+        "libprocessgroup",
+        "libjsoncpp",
+        "libcgrouprc",
+        "libcgrouprc_format",
         "libsnapuserd_client",
         "libz",
         "liblz4",
@@ -135,6 +144,7 @@
     ],
 
     header_libs: [
+        "libcutils_headers",
         "libstorage_literals_headers",
     ],
 
@@ -251,6 +261,10 @@
         "libgtest",
         "libsnapshot_cow",
         "libsnapuserd",
+        "libprocessgroup",
+        "libjsoncpp",
+        "libcgrouprc",
+        "libcgrouprc_format",
         "liburing",
         "libz",
     ],
@@ -261,6 +275,7 @@
     header_libs: [
         "libstorage_literals_headers",
         "libfiemap_headers",
+        "libcutils_headers",
     ],
     test_options: {
         min_shipping_api_level: 30,
@@ -320,6 +335,10 @@
         "libgflags",
         "libsnapshot_cow",
         "libsnapuserd",
+        "libprocessgroup",
+        "libjsoncpp",
+        "libcgrouprc",
+        "libcgrouprc_format",
         "liburing",
         "libz",
     ],
@@ -330,5 +349,6 @@
     header_libs: [
         "libstorage_literals_headers",
         "libfiemap_headers",
+        "libcutils_headers",
     ],
 }
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/merge_worker.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/merge_worker.cpp
index bcf9aab..1e7d0c0 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/merge_worker.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/merge_worker.cpp
@@ -80,16 +80,16 @@
 }
 
 bool MergeWorker::MergeReplaceZeroOps() {
-    // Flush after merging 2MB. Since all ops are independent and there is no
+    // Flush after merging 1MB. Since all ops are independent and there is no
     // dependency between COW ops, we will flush the data and the number
     // of ops merged in COW block device. If there is a crash, we will
     // end up replaying some of the COW ops which were already merged. That is
     // ok.
     //
-    // Although increasing this greater than 2MB may help in improving merge
+    // Although increasing this greater than 1MB may help in improving merge
     // times; however, on devices with low memory, this can be problematic
     // when there are multiple merge threads in parallel.
-    int total_ops_merged_per_commit = (PAYLOAD_BUFFER_SZ / BLOCK_SZ) * 2;
+    int total_ops_merged_per_commit = (PAYLOAD_BUFFER_SZ / BLOCK_SZ);
     int num_ops_merged = 0;
 
     SNAP_LOG(INFO) << "MergeReplaceZeroOps started....";
@@ -561,6 +561,10 @@
         SNAP_PLOG(ERROR) << "Failed to set thread priority";
     }
 
+    if (!SetProfiles({"CPUSET_SP_BACKGROUND"})) {
+        SNAP_PLOG(ERROR) << "Failed to assign task profile to Mergeworker thread";
+    }
+
     SNAP_LOG(INFO) << "Merge starting..";
 
     bufsink_.Initialize(PAYLOAD_BUFFER_SZ);
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp
index c08c1b1..2baf20d 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp
@@ -782,6 +782,10 @@
         SNAP_PLOG(ERROR) << "Failed to set thread priority";
     }
 
+    if (!SetProfiles({"CPUSET_SP_BACKGROUND"})) {
+        SNAP_PLOG(ERROR) << "Failed to assign task profile to readahead thread";
+    }
+
     SNAP_LOG(INFO) << "ReadAhead processing.";
     while (!RAIterDone()) {
         if (!ReadAheadIOStart()) {
diff --git a/fs_mgr/libsnapshot/snapuserd/utility.cpp b/fs_mgr/libsnapshot/snapuserd/utility.cpp
index fcdb69d..684ca3d 100644
--- a/fs_mgr/libsnapshot/snapuserd/utility.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/utility.cpp
@@ -19,6 +19,9 @@
 #include <unistd.h>
 
 #include <android-base/file.h>
+#include <processgroup/processgroup.h>
+
+#include <private/android_filesystem_config.h>
 
 namespace android {
 namespace snapshot {
@@ -33,6 +36,17 @@
 #endif
 }
 
+bool SetProfiles([[maybe_unused]] std::initializer_list<std::string_view> profiles) {
+#ifdef __ANDROID__
+    if (setgid(AID_SYSTEM)) {
+        return false;
+    }
+    return SetTaskProfiles(gettid(), profiles);
+#else
+    return true;
+#endif
+}
+
 bool KernelSupportsIoUring() {
     struct utsname uts {};
     unsigned int major, minor;
diff --git a/fs_mgr/libsnapshot/snapuserd/utility.h b/fs_mgr/libsnapshot/snapuserd/utility.h
index 255aee1..c3c3cba 100644
--- a/fs_mgr/libsnapshot/snapuserd/utility.h
+++ b/fs_mgr/libsnapshot/snapuserd/utility.h
@@ -14,10 +14,14 @@
 
 #pragma once
 
+#include <initializer_list>
+#include <string_view>
+
 namespace android {
 namespace snapshot {
 
 bool SetThreadPriority(int priority);
+bool SetProfiles(std::initializer_list<std::string_view> profiles);
 bool KernelSupportsIoUring();
 
 }  // namespace snapshot
diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh
index c87e564..7ac7a16 100755
--- a/fs_mgr/tests/adb-remount-test.sh
+++ b/fs_mgr/tests/adb-remount-test.sh
@@ -1233,6 +1233,12 @@
 adb_sh grep -q " /vendor [^ ]* rw," /proc/mounts </dev/null &&
   die "/vendor is not RO"
 
+data_device=$(adb_sh awk '$2 == "/data" { print $1; exit }' /proc/mounts)
+RO=$(adb_sh grep " ro," /proc/mounts </dev/null |
+    grep -v "^${data_device}" |
+    skip_administrative_mounts |
+    awk '{ print $1 }')
+
 T=$(adb_date)
 adb remount >&2 ||
   die -t "${T}" "adb remount"
@@ -1241,6 +1247,12 @@
 adb_sh grep -q " /vendor [^ ]* rw," /proc/mounts </dev/null ||
   die -t "${T}" "/vendor is not RW"
 
+# Only find mounts that are remounted RO -> RW
+RW=$(adb_sh grep " rw," /proc/mounts </dev/null |
+    grep -v "^${data_device}" |
+    skip_administrative_mounts |
+    grep -E "^($(join_with '|' ${RO})) ")
+
 scratch_on_super=false
 if ${overlayfs_needed}; then
   is_overlayfs_mounted /system ||
@@ -1287,27 +1299,19 @@
     fi
   done
 
-  data_device=$(adb_sh awk '$2 == "/data" { print $1; exit }' /proc/mounts)
   # KISS (we do not support sub-mounts for system partitions currently)
   adb_sh grep "^overlay " /proc/mounts </dev/null |
     grep -vE "^overlay.* /(apex|system|vendor)/[^ ]" |
     grep " overlay ro," &&
     die "expected overlay to be RW after remount"
-  adb_sh grep -v noatime /proc/mounts </dev/null |
-    grep -v "^${data_device}" |
-    skip_administrative_mounts |
-    grep -v ' ro,' &&
-    die "mounts are not noatime"
 
-  D=$(adb_sh grep " rw," /proc/mounts </dev/null |
-      grep -v "^${data_device}" |
-      skip_administrative_mounts |
+  D=$(echo "${RW}" |
       awk '{ print $1 }' |
       sed 's|/dev/root|/|' |
       sort -u)
   if [ -n "${D}" ]; then
     adb_sh df -k ${D} </dev/null |
-      sed -e 's/^Filesystem      /Filesystem (rw) /'
+      sed -e 's/^Filesystem     /Filesystem (rw)/'
   fi >&2
   for d in ${D}; do
     if adb_sh tune2fs -l "${d}" </dev/null 2>&1 | grep -q "Filesystem features:.*shared_blocks" ||
@@ -1319,6 +1323,10 @@
   is_overlayfs_mounted && die -t "${T}" "unexpected overlay takeover"
 fi
 
+echo -n "${RW}" |
+  grep -v noatime &&
+  die "mounts (rw) are not noatime"
+
 LOG OK "adb remount RW"
 
 ################################################################################
diff --git a/fs_mgr/tests/vts_fs_test.cpp b/fs_mgr/tests/vts_fs_test.cpp
index 2f2db0c..9503072 100644
--- a/fs_mgr/tests/vts_fs_test.cpp
+++ b/fs_mgr/tests/vts_fs_test.cpp
@@ -133,9 +133,10 @@
             std::vector<std::string> allowed = {"erofs", "ext4", "f2fs"};
             EXPECT_NE(std::find(allowed.begin(), allowed.end(), entry.fs_type), allowed.end())
                     << entry.mount_point;
-        } else {
+        } else if (std::find(data_fs.begin(), data_fs.end(), entry.mount_point) != data_fs.end()) {
             std::vector<std::string> allowed = {"ext4", "f2fs"};
-            EXPECT_NE(std::find(allowed.begin(), allowed.end(), entry.fs_type), allowed.end());
+            EXPECT_NE(std::find(allowed.begin(), allowed.end(), entry.fs_type), allowed.end())
+                    << entry.mount_point << ", " << entry.fs_type;
         }
     }
 }
diff --git a/healthd/Android.bp b/healthd/Android.bp
index 427ac48..e158e07 100644
--- a/healthd/Android.bp
+++ b/healthd/Android.bp
@@ -100,44 +100,6 @@
     ],
 }
 
-cc_defaults {
-    name: "android.hardware.health@2.0-service_defaults",
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    static_libs: [
-        "android.hardware.health@2.0-impl",
-        "android.hardware.health@1.0-convert",
-        "libhealthservice",
-        "libhealthstoragedefault",
-        "libbatterymonitor",
-    ],
-
-    shared_libs: [
-        "libbase",
-        "libcutils",
-        "libhidlbase",
-        "liblog",
-        "libutils",
-        "android.hardware.health@2.0",
-    ],
-}
-
-cc_binary {
-    name: "android.hardware.health@2.0-service",
-    defaults: ["android.hardware.health@2.0-service_defaults"],
-
-    vendor: true,
-    relative_install_path: "hw",
-    init_rc: ["android.hardware.health@2.0-service.rc"],
-    srcs: [
-        "HealthServiceDefault.cpp",
-    ],
-}
-
 cc_library_static {
     name: "libhealthd_charger_nops",
     recovery_available: true,
diff --git a/healthd/HealthServiceDefault.cpp b/healthd/HealthServiceDefault.cpp
deleted file mode 100644
index 89ecc2f..0000000
--- a/healthd/HealthServiceDefault.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 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 <health2/service.h>
-#include <healthd/healthd.h>
-
-void healthd_board_init(struct healthd_config*) {
-    // Implementation-defined init logic goes here.
-    // 1. config->periodic_chores_interval_* variables
-    // 2. config->battery*Path variables
-    // 3. config->energyCounter. In this implementation, energyCounter is not defined.
-
-    // use defaults
-}
-
-int healthd_board_battery_update(struct android::BatteryProperties*) {
-    // Implementation-defined update logic goes here. An implementation
-    // can make modifications to prop before broadcasting it to all callbacks.
-
-    // return 0 to log periodic polled battery status to kernel log
-    return 0;
-}
-
-int main() {
-    return health_service_main();
-}
diff --git a/healthd/android.hardware.health@2.0-service.rc b/healthd/android.hardware.health@2.0-service.rc
deleted file mode 100644
index 762771e..0000000
--- a/healthd/android.hardware.health@2.0-service.rc
+++ /dev/null
@@ -1,6 +0,0 @@
-service health-hal-2-0 /vendor/bin/hw/android.hardware.health@2.0-service
-    class hal
-    user system
-    group system
-    capabilities WAKE_ALARM BLOCK_SUSPEND
-    file /dev/kmsg w
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 12c46eb..a8e867d 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -782,7 +782,6 @@
     mkdir /data/misc/vpn 0770 system vpn
     mkdir /data/misc/shared_relro 0771 shared_relro shared_relro
     mkdir /data/misc/systemkeys 0700 system system
-    mkdir /data/misc/threadnetwork 0770 thread_network thread_network
     mkdir /data/misc/wifi 0770 wifi wifi
     mkdir /data/misc/wifi/sockets 0770 wifi wifi
     mkdir /data/misc/wifi/wpa_supplicant 0770 wifi wifi