Merge "fastboot: Fix "fastboot gsi"." am: b7062df8c0
am: 75e9ef5252

Change-Id: I536f55c07406084e4311fe9ede4ae6c1511fe04c
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index a2336bf..1b09f79 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -28,6 +28,7 @@
 #include <cutils/android_reboot.h>
 #include <ext4_utils/wipe.h>
 #include <fs_mgr.h>
+#include <fs_mgr/roots.h>
 #include <libgsi/libgsi.h>
 #include <liblp/builder.h>
 #include <liblp/liblp.h>
@@ -462,13 +463,56 @@
     return UpdateSuper(device, args[1], wipe);
 }
 
-bool GsiHandler(FastbootDevice* device, const std::vector<std::string>& args) {
-    if (!android::gsi::IsGsiInstalled()) {
-        return device->WriteStatus(FastbootResult::FAIL, "No GSI is installed");
+class AutoMountMetadata {
+  public:
+    AutoMountMetadata() {
+        Fstab proc_mounts;
+        if (!ReadFstabFromFile("/proc/mounts", &proc_mounts)) {
+            LOG(ERROR) << "Could not read /proc/mounts";
+            return;
+        }
+
+        auto iter = std::find_if(proc_mounts.begin(), proc_mounts.end(),
+                [](const auto& entry) { return entry.mount_point == "/metadata"; });
+        if (iter != proc_mounts.end()) {
+            mounted_ = true;
+            return;
+        }
+
+        if (!ReadDefaultFstab(&fstab_)) {
+            LOG(ERROR) << "Could not read default fstab";
+            return;
+        }
+        mounted_ = EnsurePathMounted(&fstab_, "/metadata");
+        should_unmount_ = true;
     }
+    ~AutoMountMetadata() {
+        if (mounted_ && should_unmount_) {
+            EnsurePathUnmounted(&fstab_, "/metadata");
+        }
+    }
+    explicit operator bool() const { return mounted_; }
+
+  private:
+    Fstab fstab_;
+    bool mounted_ = false;
+    bool should_unmount_ = false;
+};
+
+bool GsiHandler(FastbootDevice* device, const std::vector<std::string>& args) {
     if (args.size() != 2) {
         return device->WriteFail("Invalid arguments");
     }
+
+    AutoMountMetadata mount_metadata;
+    if (!mount_metadata) {
+        return device->WriteFail("Could not find GSI install");
+    }
+
+    if (!android::gsi::IsGsiInstalled()) {
+        return device->WriteStatus(FastbootResult::FAIL, "No GSI is installed");
+    }
+
     if (args[1] == "wipe") {
         if (!android::gsi::UninstallGsi()) {
             return device->WriteStatus(FastbootResult::FAIL, strerror(errno));
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 17cab3a..4cdd8bc 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -1948,11 +1948,10 @@
             std::string size = next_arg(&args);
             fb->ResizePartition(partition, size);
         } else if (command == "gsi") {
-            if (args.empty()) {
-                syntax_error("missing 'wipe' or 'disable' argument");
-            } else if (args.size() == 1 && args[0] == "wipe") {
+            std::string arg = next_arg(&args);
+            if (arg == "wipe") {
                 fb->RawCommand("gsi:wipe", "wiping GSI");
-            } else if (args.size() == 1 && args[0] == "disable") {
+            } else if (arg == "disable") {
                 fb->RawCommand("gsi:disable", "disabling GSI");
             } else {
                 syntax_error("expected 'wipe' or 'disable'");