libfiemap: Add a MapAllImages() helper.

This adds a helper for first-stage init to easily map partitions backed
by /data. This can be used for the scratch partition as well as DSU
partitions.

Bug: 134949511
Test: fiemap_image_test
Change-Id: I46246b41ce19442d1476b9959e34df0e1bff58c3
This commit is contained in:
David Anderson 2019-12-18 10:43:15 -08:00
parent 734047a231
commit d5745cce70
4 changed files with 52 additions and 0 deletions

View File

@ -46,6 +46,7 @@ class ImageManagerBinder final : public IImageManager {
bool DisableImage(const std::string& name) override;
bool RemoveDisabledImages() override;
bool GetMappedImageDevice(const std::string& name, std::string* device) override;
bool MapAllImages(const std::function<bool(std::set<std::string>)>& init) override;
std::vector<std::string> GetAllBackingImages() override;
@ -191,6 +192,11 @@ bool ImageManagerBinder::GetMappedImageDevice(const std::string& name, std::stri
return !device->empty();
}
bool ImageManagerBinder::MapAllImages(const std::function<bool(std::set<std::string>)>&) {
LOG(ERROR) << __PRETTY_FUNCTION__ << " not available over binder";
return false;
}
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

@ -42,7 +42,10 @@ using android::dm::DmTargetLinear;
using android::dm::LoopControl;
using android::fs_mgr::CreateLogicalPartition;
using android::fs_mgr::CreateLogicalPartitionParams;
using android::fs_mgr::CreateLogicalPartitions;
using android::fs_mgr::DestroyLogicalPartition;
using android::fs_mgr::GetBlockDevicePartitionName;
using android::fs_mgr::GetBlockDevicePartitionNames;
using android::fs_mgr::GetPartitionName;
static constexpr char kTestImageMetadataDir[] = "/metadata/gsi/test";
@ -669,6 +672,29 @@ bool ImageManager::GetMappedImageDevice(const std::string& name, std::string* de
return dm.GetDmDevicePathByName(name, device);
}
bool ImageManager::MapAllImages(const std::function<bool(std::set<std::string>)>& init) {
if (!MetadataExists(metadata_dir_)) {
return true;
}
auto metadata = OpenMetadata(metadata_dir_);
if (!metadata) {
return false;
}
std::set<std::string> devices;
for (const auto& name : GetBlockDevicePartitionNames(*metadata.get())) {
devices.emplace(name);
}
if (!init(std::move(devices))) {
return false;
}
auto data_device = GetMetadataSuperBlockDevice(*metadata.get());
auto data_partition_name = GetBlockDevicePartitionName(*data_device);
return CreateLogicalPartitions(*metadata.get(), data_partition_name);
}
std::unique_ptr<MappedDevice> MappedDevice::Open(IImageManager* manager,
const std::chrono::milliseconds& timeout_ms,
const std::string& name) {

View File

@ -239,9 +239,19 @@ TEST_F(ImageTest, IndirectMount) {
ASSERT_TRUE(submanager_->CreateBackingImage(test_image_name_, kTestImageSize, false, nullptr));
std::set<std::string> backing_devices;
auto init = [&](std::set<std::string> devices) -> bool {
backing_devices = std::move(devices);
return true;
};
std::string path;
ASSERT_TRUE(submanager_->MapImageDevice(test_image_name_, 5s, &path));
ASSERT_TRUE(android::base::StartsWith(path, "/dev/block/dm-"));
ASSERT_TRUE(submanager_->UnmapImageDevice(test_image_name_));
ASSERT_TRUE(submanager_->MapAllImages(init));
ASSERT_FALSE(backing_devices.empty());
ASSERT_TRUE(submanager_->UnmapImageDevice(test_image_name_));
}
bool Mkdir(const std::string& path) {

View File

@ -21,6 +21,7 @@
#include <chrono>
#include <functional>
#include <memory>
#include <set>
#include <string>
#include <android-base/unique_fd.h>
@ -89,6 +90,14 @@ class IImageManager {
// not necessary.
virtual bool GetMappedImageDevice(const std::string& name, std::string* device) = 0;
// Map all images owned by this manager. This is only intended to be used
// during first-stage init, and as such, it does not provide a timeout
// (meaning libdm races can't be resolved, as ueventd is not available),
// and is not available over binder.
//
// The callback provided is given the list of dependent block devices.
virtual bool MapAllImages(const std::function<bool(std::set<std::string>)>& init) = 0;
// Mark an image as disabled. This is useful for marking an image as
// will-be-deleted in recovery, since recovery cannot mount /data.
//
@ -137,6 +146,7 @@ class ImageManager final : public IImageManager {
bool DisableImage(const std::string& name) override;
bool RemoveDisabledImages() override;
bool GetMappedImageDevice(const std::string& name, std::string* device) override;
bool MapAllImages(const std::function<bool(std::set<std::string>)>& init) override;
std::vector<std::string> GetAllBackingImages();
// Same as CreateBackingImage, but provides a progress notification.