libfiemap: Add a way to get the block device path of a mapped image.

This is needed for adb remount, to find the scratch device if it is
already mapped. Note that on devices without metadata encryption, this
cannot be done by querying device-mapper, since scratch will be a loop
device.

Bug: 134949511
Test: fiemap_image_test
Change-Id: Ia25d279c6f8a4838be32a8c01aefc67b5ec1e002
This commit is contained in:
David Anderson 2019-12-17 21:02:36 -08:00
parent f41c7bbb96
commit 734047a231
4 changed files with 45 additions and 1 deletions

View file

@ -45,6 +45,7 @@ class ImageManagerBinder final : public IImageManager {
bool RemoveAllImages() override;
bool DisableImage(const std::string& name) override;
bool RemoveDisabledImages() override;
bool GetMappedImageDevice(const std::string& name, std::string* device) override;
std::vector<std::string> GetAllBackingImages() override;
@ -180,6 +181,16 @@ bool ImageManagerBinder::RemoveDisabledImages() {
return true;
}
bool ImageManagerBinder::GetMappedImageDevice(const std::string& name, std::string* device) {
auto status = manager_->getMappedImageDevice(name, device);
if (!status.isOk()) {
LOG(ERROR) << __PRETTY_FUNCTION__
<< " binder returned: " << status.exceptionMessage().string();
return false;
}
return !device->empty();
}
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

@ -648,11 +648,27 @@ bool ImageManager::RemoveDisabledImages() {
bool ok = true;
for (const auto& partition : metadata->partitions) {
ok &= DeleteBackingImage(GetPartitionName(partition));
if (partition.attributes & LP_PARTITION_ATTR_DISABLED) {
ok &= DeleteBackingImage(GetPartitionName(partition));
}
}
return ok;
}
bool ImageManager::GetMappedImageDevice(const std::string& name, std::string* device) {
auto prop_name = GetStatusPropertyName(name);
*device = android::base::GetProperty(prop_name, "");
if (!device->empty()) {
return true;
}
auto& dm = DeviceMapper::Instance();
if (dm.GetState(name) == DmDeviceState::INVALID) {
return false;
}
return dm.GetDmDevicePathByName(name, device);
}
std::unique_ptr<MappedDevice> MappedDevice::Open(IImageManager* manager,
const std::chrono::milliseconds& timeout_ms,
const std::string& name) {

View file

@ -120,6 +120,17 @@ TEST_F(NativeTest, DisableImage) {
ASSERT_TRUE(!manager_->BackingImageExists(base_name_));
}
TEST_F(NativeTest, GetMappedImageDevice) {
ASSERT_TRUE(manager_->CreateBackingImage(base_name_, kTestImageSize, false, nullptr));
std::string path1, path2;
ASSERT_TRUE(manager_->MapImageDevice(base_name_, 5s, &path1));
ASSERT_TRUE(manager_->GetMappedImageDevice(base_name_, &path2));
EXPECT_EQ(path1, path2);
ASSERT_TRUE(manager_->UnmapImageDevice(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,11 @@ class IImageManager {
virtual bool MapImageWithDeviceMapper(const IPartitionOpener& opener, const std::string& name,
std::string* dev) = 0;
// If an image was mapped, return the path to its device. Otherwise, return
// false. Errors are not reported in this case, calling IsImageMapped is
// not necessary.
virtual bool GetMappedImageDevice(const std::string& name, std::string* device) = 0;
// Mark an image as disabled. This is useful for marking an image as
// will-be-deleted in recovery, since recovery cannot mount /data.
//
@ -131,6 +136,7 @@ class ImageManager final : public IImageManager {
bool RemoveAllImages() override;
bool DisableImage(const std::string& name) override;
bool RemoveDisabledImages() override;
bool GetMappedImageDevice(const std::string& name, std::string* device) override;
std::vector<std::string> GetAllBackingImages();
// Same as CreateBackingImage, but provides a progress notification.