Merge "libfiemap: Add helpers to remove images from recovery." am: 8edafa2393 am: 7208d546ef
Change-Id: I47eb95360eea05f79a099eb5c54b31f2c5e2e8cf
diff --git a/fs_mgr/fs_mgr_dm_linear.cpp b/fs_mgr/fs_mgr_dm_linear.cpp
index 0dcb9fe..ea9c957 100644
--- a/fs_mgr/fs_mgr_dm_linear.cpp
+++ b/fs_mgr/fs_mgr_dm_linear.cpp
@@ -151,6 +151,10 @@
LINFO << "Skipping zero-length logical partition: " << GetPartitionName(partition);
continue;
}
+ if (partition.attributes & LP_PARTITION_ATTR_DISABLED) {
+ LINFO << "Skipping disabled partition: " << GetPartitionName(partition);
+ continue;
+ }
params.partition = &partition;
diff --git a/fs_mgr/libfiemap/binder.cpp b/fs_mgr/libfiemap/binder.cpp
index 49779f4..5aa4560 100644
--- a/fs_mgr/libfiemap/binder.cpp
+++ b/fs_mgr/libfiemap/binder.cpp
@@ -43,6 +43,8 @@
std::string* dev) override;
bool ZeroFillNewImage(const std::string& name, uint64_t bytes) override;
bool RemoveAllImages() override;
+ bool DisableImage(const std::string& name) override;
+ bool RemoveDisabledImages() override;
std::vector<std::string> GetAllBackingImages() override;
@@ -163,6 +165,21 @@
return true;
}
+bool ImageManagerBinder::DisableImage(const std::string&) {
+ LOG(ERROR) << __PRETTY_FUNCTION__ << " is not available over binder";
+ return false;
+}
+
+bool ImageManagerBinder::RemoveDisabledImages() {
+ auto status = manager_->removeDisabledImages();
+ if (!status.isOk()) {
+ LOG(ERROR) << __PRETTY_FUNCTION__
+ << " binder returned: " << status.exceptionMessage().string();
+ return false;
+ }
+ return true;
+}
+
static android::sp<IGsid> AcquireIGsid(const std::chrono::milliseconds& timeout_ms) {
if (android::base::GetProperty("init.svc.gsid", "") != "running") {
if (!android::base::SetProperty("ctl.start", "gsid") ||
diff --git a/fs_mgr/libfiemap/image_manager.cpp b/fs_mgr/libfiemap/image_manager.cpp
index fe2018d..5b22eaa 100644
--- a/fs_mgr/libfiemap/image_manager.cpp
+++ b/fs_mgr/libfiemap/image_manager.cpp
@@ -632,6 +632,27 @@
return true;
}
+bool ImageManager::DisableImage(const std::string& name) {
+ return AddAttributes(metadata_dir_, name, LP_PARTITION_ATTR_DISABLED);
+}
+
+bool ImageManager::RemoveDisabledImages() {
+ if (!MetadataExists(metadata_dir_)) {
+ return true;
+ }
+
+ auto metadata = OpenMetadata(metadata_dir_);
+ if (!metadata) {
+ return false;
+ }
+
+ bool ok = true;
+ for (const auto& partition : metadata->partitions) {
+ ok &= DeleteBackingImage(GetPartitionName(partition));
+ }
+ return ok;
+}
+
std::unique_ptr<MappedDevice> MappedDevice::Open(IImageManager* manager,
const std::chrono::milliseconds& timeout_ms,
const std::string& name) {
diff --git a/fs_mgr/libfiemap/image_test.cpp b/fs_mgr/libfiemap/image_test.cpp
index f05825c..90fdb4c 100644
--- a/fs_mgr/libfiemap/image_test.cpp
+++ b/fs_mgr/libfiemap/image_test.cpp
@@ -112,6 +112,14 @@
ASSERT_EQ(android::base::GetProperty(PropertyName(), ""), "");
}
+TEST_F(NativeTest, DisableImage) {
+ ASSERT_TRUE(manager_->CreateBackingImage(base_name_, kTestImageSize, false, nullptr));
+ ASSERT_TRUE(manager_->BackingImageExists(base_name_));
+ ASSERT_TRUE(manager_->DisableImage(base_name_));
+ ASSERT_TRUE(manager_->RemoveDisabledImages());
+ ASSERT_TRUE(!manager_->BackingImageExists(base_name_));
+}
+
// This fixture is for tests against a simulated device environment. Rather
// than use /data, we create an image and then layer a new filesystem within
// it. Each test then decides how to mount and create layered images. This
diff --git a/fs_mgr/libfiemap/include/libfiemap/image_manager.h b/fs_mgr/libfiemap/include/libfiemap/image_manager.h
index 5ff4628..fbc61d1 100644
--- a/fs_mgr/libfiemap/include/libfiemap/image_manager.h
+++ b/fs_mgr/libfiemap/include/libfiemap/image_manager.h
@@ -84,6 +84,16 @@
virtual bool MapImageWithDeviceMapper(const IPartitionOpener& opener, const std::string& name,
std::string* dev) = 0;
+ // Mark an image as disabled. This is useful for marking an image as
+ // will-be-deleted in recovery, since recovery cannot mount /data.
+ //
+ // This is not available in binder, since it is intended for recovery.
+ // When binder is available, images can simply be removed.
+ virtual bool DisableImage(const std::string& name) = 0;
+
+ // Remove all images that been marked as disabled.
+ virtual bool RemoveDisabledImages() = 0;
+
// Get all backing image names.
virtual std::vector<std::string> GetAllBackingImages() = 0;
@@ -119,6 +129,8 @@
bool MapImageWithDeviceMapper(const IPartitionOpener& opener, const std::string& name,
std::string* dev) override;
bool RemoveAllImages() override;
+ bool DisableImage(const std::string& name) override;
+ bool RemoveDisabledImages() override;
std::vector<std::string> GetAllBackingImages();
// Same as CreateBackingImage, but provides a progress notification.
diff --git a/fs_mgr/libfiemap/metadata.cpp b/fs_mgr/libfiemap/metadata.cpp
index 597efe9..ea1f508 100644
--- a/fs_mgr/libfiemap/metadata.cpp
+++ b/fs_mgr/libfiemap/metadata.cpp
@@ -192,5 +192,23 @@
return SaveMetadata(builder.get(), metadata_dir);
}
+bool AddAttributes(const std::string& metadata_dir, const std::string& partition_name,
+ uint32_t attributes) {
+ auto metadata = OpenMetadata(metadata_dir);
+ if (!metadata) {
+ return false;
+ }
+ auto builder = MetadataBuilder::New(*metadata.get());
+ if (!builder) {
+ return false;
+ }
+ auto partition = builder->FindPartition(partition_name);
+ if (!partition) {
+ return false;
+ }
+ partition->set_attributes(partition->attributes() | attributes);
+ return SaveMetadata(builder.get(), metadata_dir);
+}
+
} // namespace fiemap
} // namespace android
diff --git a/fs_mgr/libfiemap/metadata.h b/fs_mgr/libfiemap/metadata.h
index f0ce23e..4eb3ad5 100644
--- a/fs_mgr/libfiemap/metadata.h
+++ b/fs_mgr/libfiemap/metadata.h
@@ -29,6 +29,8 @@
std::unique_ptr<android::fs_mgr::LpMetadata> OpenMetadata(const std::string& metadata_dir);
bool UpdateMetadata(const std::string& metadata_dir, const std::string& partition_name,
SplitFiemap* file, uint64_t partition_size, bool readonly);
+bool AddAttributes(const std::string& metadata_dir, const std::string& partition_name,
+ uint32_t attributes);
bool RemoveImageMetadata(const std::string& metadata_dir, const std::string& partition_name);
bool RemoveAllMetadata(const std::string& dir);
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index 7e7f393..d496466 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -852,7 +852,7 @@
return nullptr;
}
- if (partition->attributes() & LP_PARTITION_ATTR_UPDATED) {
+ if (partition->attributes() & LP_PARTITION_ATTRIBUTE_MASK_V1) {
static const uint16_t kMinVersion = LP_METADATA_VERSION_FOR_UPDATED_ATTR;
metadata->header.minor_version = std::max(metadata->header.minor_version, kMinVersion);
}
diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h
index 851f041..f7738fb 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -145,6 +145,7 @@
std::vector<std::unique_ptr<Extent>> extents_;
uint32_t attributes_;
uint64_t size_;
+ bool disabled_;
};
// An interval in the metadata. This is similar to a LinearExtent with one difference.
diff --git a/fs_mgr/liblp/include/liblp/metadata_format.h b/fs_mgr/liblp/include/liblp/metadata_format.h
index d3c9874..41d8b0c 100644
--- a/fs_mgr/liblp/include/liblp/metadata_format.h
+++ b/fs_mgr/liblp/include/liblp/metadata_format.h
@@ -72,13 +72,17 @@
*/
#define LP_PARTITION_ATTR_UPDATED (1 << 2)
+/* This flag marks a partition as disabled. It should not be used or mapped. */
+#define LP_PARTITION_ATTR_DISABLED (1 << 3)
+
/* Mask that defines all valid attributes. When changing this, make sure to
* update ParseMetadata().
*/
#define LP_PARTITION_ATTRIBUTE_MASK_V0 \
(LP_PARTITION_ATTR_READONLY | LP_PARTITION_ATTR_SLOT_SUFFIXED)
-#define LP_PARTITION_ATTRIBUTE_MASK_V1 (LP_PARTITION_ATTRIBUTE_MASK_V0 | LP_PARTITION_ATTR_UPDATED)
-#define LP_PARTITION_ATTRIBUTE_MASK LP_PARTITION_ATTRIBUTE_MASK_V1
+#define LP_PARTITION_ATTRIBUTE_MASK_V1 (LP_PARTITION_ATTR_UPDATED | LP_PARTITION_ATTR_DISABLED)
+#define LP_PARTITION_ATTRIBUTE_MASK \
+ (LP_PARTITION_ATTRIBUTE_MASK_V0 | LP_PARTITION_ATTRIBUTE_MASK_V1)
/* Default name of the physical partition that holds logical partition entries.
* The layout of this partition will look like:
diff --git a/fs_mgr/liblp/reader.cpp b/fs_mgr/liblp/reader.cpp
index 30c17e4..e6fd9f7 100644
--- a/fs_mgr/liblp/reader.cpp
+++ b/fs_mgr/liblp/reader.cpp
@@ -280,11 +280,9 @@
return nullptr;
}
- uint32_t valid_attributes = 0;
+ uint32_t valid_attributes = LP_PARTITION_ATTRIBUTE_MASK_V0;
if (metadata->header.minor_version >= LP_METADATA_VERSION_FOR_UPDATED_ATTR) {
- valid_attributes = LP_PARTITION_ATTRIBUTE_MASK_V1;
- } else {
- valid_attributes = LP_PARTITION_ATTRIBUTE_MASK_V0;
+ valid_attributes |= LP_PARTITION_ATTRIBUTE_MASK_V1;
}
// ValidateTableSize ensured that |cursor| is valid for the number of