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
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));