Merge "llkd: Use more inclusive language" into rvc-dev
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 7f6e723..5307a00 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -986,10 +986,69 @@
            fb->GetVar("partition-type:vbmeta_b", &partition_type) == fastboot::SUCCESS;
 }
 
+static std::string fb_fix_numeric_var(std::string var) {
+    // Some bootloaders (angler, for example), send spurious leading whitespace.
+    var = android::base::Trim(var);
+    // Some bootloaders (hammerhead, for example) use implicit hex.
+    // This code used to use strtol with base 16.
+    if (!android::base::StartsWith(var, "0x")) var = "0x" + var;
+    return var;
+}
+
+static void copy_boot_avb_footer(const std::string& partition, struct fastboot_buffer* buf) {
+    if (buf->sz < AVB_FOOTER_SIZE) {
+        return;
+    }
+
+    std::string partition_size_str;
+    if (fb->GetVar("partition-size:" + partition, &partition_size_str) != fastboot::SUCCESS) {
+        die("cannot get boot partition size");
+    }
+
+    partition_size_str = fb_fix_numeric_var(partition_size_str);
+    int64_t partition_size;
+    if (!android::base::ParseInt(partition_size_str, &partition_size)) {
+        die("Couldn't parse partition size '%s'.", partition_size_str.c_str());
+    }
+    if (partition_size == buf->sz) {
+        return;
+    }
+    if (partition_size < buf->sz) {
+        die("boot partition is smaller than boot image");
+    }
+
+    std::string data;
+    if (!android::base::ReadFdToString(buf->fd, &data)) {
+        die("Failed reading from boot");
+    }
+
+    uint64_t footer_offset = buf->sz - AVB_FOOTER_SIZE;
+    if (0 != data.compare(footer_offset, AVB_FOOTER_MAGIC_LEN, AVB_FOOTER_MAGIC)) {
+        return;
+    }
+
+    int fd = make_temporary_fd("boot rewriting");
+    if (!android::base::WriteStringToFd(data, fd)) {
+        die("Failed writing to modified boot");
+    }
+    lseek(fd, partition_size - AVB_FOOTER_SIZE, SEEK_SET);
+    if (!android::base::WriteStringToFd(data.substr(footer_offset), fd)) {
+        die("Failed copying AVB footer in boot");
+    }
+    close(buf->fd);
+    buf->fd = fd;
+    buf->sz = partition_size;
+    lseek(fd, 0, SEEK_SET);
+}
+
 static void flash_buf(const std::string& partition, struct fastboot_buffer *buf)
 {
     sparse_file** s;
 
+    if (partition == "boot" || partition == "boot_a" || partition == "boot_b") {
+        copy_boot_avb_footer(partition, buf);
+    }
+
     // Rewrite vbmeta if that's what we're flashing and modification has been requested.
     if (g_disable_verity || g_disable_verification) {
         if (partition == "vbmeta" || partition == "vbmeta_a" || partition == "vbmeta_b") {
@@ -1485,15 +1544,6 @@
     fb->RawCommand(command, "");
 }
 
-static std::string fb_fix_numeric_var(std::string var) {
-    // Some bootloaders (angler, for example), send spurious leading whitespace.
-    var = android::base::Trim(var);
-    // Some bootloaders (hammerhead, for example) use implicit hex.
-    // This code used to use strtol with base 16.
-    if (!android::base::StartsWith(var, "0x")) var = "0x" + var;
-    return var;
-}
-
 static unsigned fb_get_flash_block_size(std::string name) {
     std::string sizeString;
     if (fb->GetVar(name, &sizeString) != fastboot::SUCCESS || sizeString.empty()) {
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index f5daf91..cd64599 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -162,10 +162,13 @@
     defaults: ["fs_mgr_defaults"],
     static_libs: [
         "libavb_user",
+        "libutils",
+        "libvold_binder",
     ],
     shared_libs: [
         "libbootloader_message",
         "libbase",
+        "libbinder",
         "libcutils",
         "libcrypto",
         "libext4_utils",
diff --git a/fs_mgr/fs_mgr_remount.cpp b/fs_mgr/fs_mgr_remount.cpp
index 24cbad7..def1c21 100644
--- a/fs_mgr/fs_mgr_remount.cpp
+++ b/fs_mgr/fs_mgr_remount.cpp
@@ -24,6 +24,7 @@
 #include <unistd.h>
 
 #include <string>
+#include <thread>
 #include <utility>
 #include <vector>
 
@@ -31,6 +32,8 @@
 #include <android-base/logging.h>
 #include <android-base/properties.h>
 #include <android-base/strings.h>
+#include <android/os/IVold.h>
+#include <binder/IServiceManager.h>
 #include <bootloader_message/bootloader_message.h>
 #include <cutils/android_reboot.h>
 #include <fec/io.h>
@@ -103,8 +106,23 @@
     ::exit(0);  // SUCCESS
 }
 
+static android::sp<android::os::IVold> GetVold() {
+    while (true) {
+        if (auto sm = android::defaultServiceManager()) {
+            if (auto binder = sm->getService(android::String16("vold"))) {
+                if (auto vold = android::interface_cast<android::os::IVold>(binder)) {
+                    return vold;
+                }
+            }
+        }
+        std::this_thread::sleep_for(2s);
+    }
+}
+
 }  // namespace
 
+using namespace std::chrono_literals;
+
 static int do_remount(int argc, char* argv[]) {
     enum {
         SUCCESS = 0,
@@ -118,6 +136,9 @@
         BAD_OVERLAY,
         NO_MOUNTS,
         REMOUNT_FAILED,
+        MUST_REBOOT,
+        BINDER_ERROR,
+        CHECKPOINTING
     } retval = SUCCESS;
 
     // If somehow this executable is delivered on a "user" build, it can
@@ -191,6 +212,22 @@
         return NO_FSTAB;
     }
 
+    if (android::base::GetBoolProperty("ro.virtual_ab.enabled", false) &&
+        !android::base::GetBoolProperty("ro.virtual_ab.retrofit", false)) {
+        // Virtual A/B devices can use /data as backing storage; make sure we're
+        // not checkpointing.
+        auto vold = GetVold();
+        bool checkpointing = false;
+        if (!vold->isCheckpointing(&checkpointing).isOk()) {
+            LOG(ERROR) << "Could not determine checkpointing status.";
+            return BINDER_ERROR;
+        }
+        if (checkpointing) {
+            LOG(ERROR) << "Cannot use remount when a checkpoint is in progress.";
+            return CHECKPOINTING;
+        }
+    }
+
     // Generate the list of supported overlayfs mount points.
     auto overlayfs_candidates = fs_mgr_overlayfs_candidate_list(fstab);