Merge "libfiemap: Add helpers to remove images from recovery."

This commit is contained in:
David Anderson 2019-12-27 20:28:48 +00:00 committed by Gerrit Code Review
commit 8edafa2393
11 changed files with 92 additions and 7 deletions

View file

@ -151,6 +151,10 @@ bool CreateLogicalPartitions(const LpMetadata& metadata, const std::string& supe
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;

View file

@ -43,6 +43,8 @@ class ImageManagerBinder final : public IImageManager {
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 @@ bool ImageManagerBinder::RemoveAllImages() {
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") ||

View file

@ -632,6 +632,27 @@ bool ImageManager::Validate() {
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) {

View file

@ -112,6 +112,14 @@ TEST_F(NativeTest, CreateAndMap) {
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

View file

@ -84,6 +84,16 @@ class IImageManager {
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 @@ class ImageManager final : public IImageManager {
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.

View file

@ -192,5 +192,23 @@ bool UpdateMetadata(const std::string& metadata_dir, const std::string& partitio
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

View file

@ -29,6 +29,8 @@ bool MetadataExists(const std::string& metadata_dir);
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);

View file

@ -852,7 +852,7 @@ std::unique_ptr<LpMetadata> MetadataBuilder::Export() {
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);
}

View file

@ -145,6 +145,7 @@ class Partition final {
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.

View file

@ -72,13 +72,17 @@ extern "C" {
*/
#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:

View file

@ -280,11 +280,9 @@ static std::unique_ptr<LpMetadata> ParseMetadata(const LpMetadataGeometry& geome
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