From 3d782d57cc94bcc9147b78b95891d8e75e138ba3 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 29 Jan 2019 13:09:49 -0800 Subject: [PATCH] fastboot: Fix "fastboot gsi". This command erroneously reports that no GSI is installed, because /metadata is not mounted in recovery. To address this, temporarily mount /metadata when the gsi command is invoked. Bug: 122556707 Test: fastboot gsi disable fastboot gsi wipe Change-Id: Ib21971b49b46fd580b902ff75f01cfb96192afc0 --- fastboot/device/commands.cpp | 50 +++++++++++++++++++++++++++++++++--- fastboot/fastboot.cpp | 7 +++-- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp index a2336bf7b..1b09f79f6 100644 --- a/fastboot/device/commands.cpp +++ b/fastboot/device/commands.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -462,13 +463,56 @@ bool UpdateSuperHandler(FastbootDevice* device, const std::vector& return UpdateSuper(device, args[1], wipe); } -bool GsiHandler(FastbootDevice* device, const std::vector& 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& 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 17cab3a54..4cdd8bcd9 100644 --- a/fastboot/fastboot.cpp +++ b/fastboot/fastboot.cpp @@ -1948,11 +1948,10 @@ int FastBootTool::Main(int argc, char* argv[]) { 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'");