fastboot: Delete logical "other" partitions on retrofit devices.
On retrofit devices, if both slots contain dynamic partition builds,
then "flashall" will attempt to write secondary images to dynamic
partitions in the other slot. At worst, this can fail with an error. At
best, it will result in the "other" partition not being mounted on first
boot.
This patch therefore deletes logical partitions for secondary images, on
retrofit devices only. On a Pixel device on the "b" slot, this means
"system_a" and "vendor_a" will be deleted before flashing, and therefore
system_other and vendor_other will be flashed to physical partitions
instead.
Bug: 120034852
Test: fastboot set_active a
fastboot flashall
fastboot set_active b
fastboot flashall
Change-Id: I6affe9a6c639b0495bffc77fcf20f329b86ad159
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 0978ec1..fee0857 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -46,6 +46,7 @@
#include <chrono>
#include <functional>
#include <regex>
+#include <string>
#include <thread>
#include <utility>
#include <vector>
@@ -78,6 +79,7 @@
using android::base::Split;
using android::base::Trim;
using android::base::unique_fd;
+using namespace std::string_literals;
static const char* serial = nullptr;
@@ -1106,6 +1108,14 @@
return fb->GetVar("is-logical:" + partition, &value) == fastboot::SUCCESS && value == "yes";
}
+static bool is_retrofit_device() {
+ std::string value;
+ if (fb->GetVar("super-partition-name", &value) != fastboot::SUCCESS) {
+ return false;
+ }
+ return android::base::StartsWith(value, "system_");
+}
+
static void do_flash(const char* pname, const char* fname) {
struct fastboot_buffer buf;
@@ -1319,6 +1329,19 @@
command += ":wipe";
}
fb->RawCommand(command, "Updating super partition");
+
+ // Retrofit devices have two super partitions, named super_a and super_b.
+ // On these devices, secondary slots must be flashed as physical
+ // partitions (otherwise they would not mount on first boot). To enforce
+ // this, we delete any logical partitions for the "other" slot.
+ if (is_retrofit_device()) {
+ for (const auto& [image, slot] : os_images_) {
+ std::string partition_name = image->part_name + "_"s + slot;
+ if (image->IsSecondary() && is_logical(partition_name)) {
+ fb->DeletePartition(partition_name);
+ }
+ }
+ }
}
class ZipImageSource final : public ImageSource {