fastbootd: Cancel snapshots when modifying partitions.
When flashing or resizing partitions, remove the
LP_PARTITION_ATTR_UPDATED flag. This will cause first-stage init to skip
any snapshots for that partition, and the backing storage (if any)
will later be reclaimed.
Bug: 139155473
Test: manual test
Change-Id: I3b185f68dfecb5a93636af0b5ae289ead1363fd0
diff --git a/fastboot/device/commands.cpp b/fastboot/device/commands.cpp
index 409ef70..4c77c75 100644
--- a/fastboot/device/commands.cpp
+++ b/fastboot/device/commands.cpp
@@ -194,23 +194,6 @@
return device->WriteStatus(FastbootResult::FAIL, "Couldn't download data");
}
-bool FlashHandler(FastbootDevice* device, const std::vector<std::string>& args) {
- if (args.size() < 2) {
- return device->WriteStatus(FastbootResult::FAIL, "Invalid arguments");
- }
-
- if (GetDeviceLockStatus()) {
- return device->WriteStatus(FastbootResult::FAIL,
- "Flashing is not allowed on locked devices");
- }
-
- int ret = Flash(device, args[1]);
- if (ret < 0) {
- return device->WriteStatus(FastbootResult::FAIL, strerror(-ret));
- }
- return device->WriteStatus(FastbootResult::OKAY, "Flashing succeeded");
-}
-
bool SetActiveHandler(FastbootDevice* device, const std::vector<std::string>& args) {
if (args.size() < 2) {
return device->WriteStatus(FastbootResult::FAIL, "Missing slot argument");
@@ -440,6 +423,11 @@
if (!partition) {
return device->WriteFail("Partition does not exist");
}
+
+ // Remove the updated flag to cancel any snapshots.
+ uint32_t attrs = partition->attributes();
+ partition->set_attributes(attrs & ~LP_PARTITION_ATTR_UPDATED);
+
if (!builder->ResizePartition(partition, partition_size)) {
return device->WriteFail("Not enough space to resize partition");
}
@@ -449,6 +437,42 @@
return device->WriteOkay("Partition resized");
}
+void CancelPartitionSnapshot(FastbootDevice* device, const std::string& partition_name) {
+ PartitionBuilder builder(device, partition_name);
+ if (!builder.Valid()) return;
+
+ auto partition = builder->FindPartition(partition_name);
+ if (!partition) return;
+
+ // Remove the updated flag to cancel any snapshots.
+ uint32_t attrs = partition->attributes();
+ partition->set_attributes(attrs & ~LP_PARTITION_ATTR_UPDATED);
+
+ builder.Write();
+}
+
+bool FlashHandler(FastbootDevice* device, const std::vector<std::string>& args) {
+ if (args.size() < 2) {
+ return device->WriteStatus(FastbootResult::FAIL, "Invalid arguments");
+ }
+
+ if (GetDeviceLockStatus()) {
+ return device->WriteStatus(FastbootResult::FAIL,
+ "Flashing is not allowed on locked devices");
+ }
+
+ const auto& partition_name = args[1];
+ if (LogicalPartitionExists(device, partition_name)) {
+ CancelPartitionSnapshot(device, partition_name);
+ }
+
+ int ret = Flash(device, partition_name);
+ if (ret < 0) {
+ return device->WriteStatus(FastbootResult::FAIL, strerror(-ret));
+ }
+ return device->WriteStatus(FastbootResult::OKAY, "Flashing succeeded");
+}
+
bool UpdateSuperHandler(FastbootDevice* device, const std::vector<std::string>& args) {
if (args.size() < 2) {
return device->WriteFail("Invalid arguments");
diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h
index c3f6e91..5f854c5 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -123,6 +123,7 @@
const std::string& name() const { return name_; }
const std::string& group_name() const { return group_name_; }
uint32_t attributes() const { return attributes_; }
+ void set_attributes(uint32_t attributes) { attributes_ = attributes; }
const std::vector<std::unique_ptr<Extent>>& extents() const { return extents_; }
uint64_t size() const { return size_; }