Merge "libdm, libsnapshot: Add a virtual interface for DeviceMapper." am: 5cd741583f
Original change: https://android-review.googlesource.com/c/platform/system/core/+/1825107 Change-Id: I5b6aa6445809c808cf4d4cac8769f7d42cfe1bac
This commit is contained in:
commit
8005743be4
9 changed files with 93 additions and 86 deletions
|
@ -55,7 +55,33 @@ static constexpr uint64_t kSectorSize = 512;
|
|||
// that prefix.
|
||||
std::optional<std::string> ExtractBlockDeviceName(const std::string& path);
|
||||
|
||||
class DeviceMapper final {
|
||||
// This interface is for testing purposes. See DeviceMapper proper for what these methods do.
|
||||
class IDeviceMapper {
|
||||
public:
|
||||
virtual ~IDeviceMapper() {}
|
||||
|
||||
struct TargetInfo {
|
||||
struct dm_target_spec spec;
|
||||
std::string data;
|
||||
TargetInfo() {}
|
||||
TargetInfo(const struct dm_target_spec& spec, const std::string& data)
|
||||
: spec(spec), data(data) {}
|
||||
|
||||
bool IsOverflowSnapshot() const;
|
||||
};
|
||||
|
||||
virtual bool CreateDevice(const std::string& name, const DmTable& table, std::string* path,
|
||||
const std::chrono::milliseconds& timeout_ms) = 0;
|
||||
virtual DmDeviceState GetState(const std::string& name) const = 0;
|
||||
virtual bool LoadTableAndActivate(const std::string& name, const DmTable& table) = 0;
|
||||
virtual bool GetTableInfo(const std::string& name, std::vector<TargetInfo>* table) = 0;
|
||||
virtual bool GetTableStatus(const std::string& name, std::vector<TargetInfo>* table) = 0;
|
||||
virtual bool GetDmDevicePathByName(const std::string& name, std::string* path) = 0;
|
||||
virtual bool GetDeviceString(const std::string& name, std::string* dev) = 0;
|
||||
virtual bool DeleteDeviceIfExists(const std::string& name) = 0;
|
||||
};
|
||||
|
||||
class DeviceMapper final : public IDeviceMapper {
|
||||
public:
|
||||
class DmBlockDevice final {
|
||||
public:
|
||||
|
@ -95,7 +121,7 @@ class DeviceMapper final {
|
|||
// Removes a device mapper device with the given name.
|
||||
// Returns 'true' on success, false otherwise.
|
||||
bool DeleteDevice(const std::string& name);
|
||||
bool DeleteDeviceIfExists(const std::string& name);
|
||||
bool DeleteDeviceIfExists(const std::string& name) override;
|
||||
// Removes a device mapper device with the given name and waits for |timeout_ms| milliseconds
|
||||
// for the corresponding block device to be deleted.
|
||||
bool DeleteDevice(const std::string& name, const std::chrono::milliseconds& timeout_ms);
|
||||
|
@ -114,7 +140,7 @@ class DeviceMapper final {
|
|||
// Returns the current state of the underlying device mapper device
|
||||
// with given name.
|
||||
// One of INVALID, SUSPENDED or ACTIVE.
|
||||
DmDeviceState GetState(const std::string& name) const;
|
||||
DmDeviceState GetState(const std::string& name) const override;
|
||||
|
||||
// Puts the given device to the specified status, which must be either:
|
||||
// - SUSPENDED: suspend the device, or
|
||||
|
@ -158,7 +184,7 @@ class DeviceMapper final {
|
|||
// not |path| is available. It is the caller's responsibility to ensure
|
||||
// there are no races.
|
||||
bool CreateDevice(const std::string& name, const DmTable& table, std::string* path,
|
||||
const std::chrono::milliseconds& timeout_ms);
|
||||
const std::chrono::milliseconds& timeout_ms) override;
|
||||
|
||||
// Create a device and activate the given table, without waiting to acquire
|
||||
// a valid path. If the caller will use GetDmDevicePathByName(), it should
|
||||
|
@ -170,7 +196,7 @@ class DeviceMapper final {
|
|||
// process. A device with the given name must already exist.
|
||||
//
|
||||
// Returns 'true' on success, false otherwise.
|
||||
bool LoadTableAndActivate(const std::string& name, const DmTable& table);
|
||||
bool LoadTableAndActivate(const std::string& name, const DmTable& table) override;
|
||||
|
||||
// Returns true if a list of available device mapper targets registered in the kernel was
|
||||
// successfully read and stored in 'targets'. Returns 'false' otherwise.
|
||||
|
@ -216,7 +242,7 @@ class DeviceMapper final {
|
|||
|
||||
// Returns a major:minor string for the named device-mapper node, that can
|
||||
// be used as inputs to DmTargets that take a block device.
|
||||
bool GetDeviceString(const std::string& name, std::string* dev);
|
||||
bool GetDeviceString(const std::string& name, std::string* dev) override;
|
||||
|
||||
// The only way to create a DeviceMapper object.
|
||||
static DeviceMapper& Instance();
|
||||
|
@ -231,20 +257,11 @@ class DeviceMapper final {
|
|||
// contain one TargetInfo for each target in the table. If the device does
|
||||
// not exist, or there were too many targets, the call will fail and return
|
||||
// false.
|
||||
struct TargetInfo {
|
||||
struct dm_target_spec spec;
|
||||
std::string data;
|
||||
TargetInfo() {}
|
||||
TargetInfo(const struct dm_target_spec& spec, const std::string& data)
|
||||
: spec(spec), data(data) {}
|
||||
|
||||
bool IsOverflowSnapshot() const;
|
||||
};
|
||||
bool GetTableStatus(const std::string& name, std::vector<TargetInfo>* table);
|
||||
bool GetTableStatus(const std::string& name, std::vector<TargetInfo>* table) override;
|
||||
|
||||
// Identical to GetTableStatus, except also retrives the active table for the device
|
||||
// mapper device from the kernel.
|
||||
bool GetTableInfo(const std::string& name, std::vector<TargetInfo>* table);
|
||||
bool GetTableInfo(const std::string& name, std::vector<TargetInfo>* table) override;
|
||||
|
||||
static std::string GetTargetType(const struct dm_target_spec& spec);
|
||||
|
||||
|
|
|
@ -152,6 +152,7 @@ cc_test {
|
|||
static_libs: [
|
||||
"libavb",
|
||||
"libdm",
|
||||
"libext2_uuid",
|
||||
"libfs_avb",
|
||||
"libfstab",
|
||||
],
|
||||
|
|
|
@ -139,5 +139,9 @@ std::unique_ptr<android::fiemap::IImageManager> ISnapshotManager::IDeviceInfo::O
|
|||
}
|
||||
}
|
||||
|
||||
android::dm::IDeviceMapper& DeviceInfo::GetDeviceMapper() {
|
||||
return android::dm::DeviceMapper::Instance();
|
||||
}
|
||||
|
||||
} // namespace snapshot
|
||||
} // namespace android
|
||||
|
|
|
@ -40,6 +40,7 @@ class DeviceInfo final : public SnapshotManager::IDeviceInfo {
|
|||
bool IsRecovery() const override;
|
||||
std::unique_ptr<IImageManager> OpenImageManager() const override;
|
||||
bool IsFirstStageInit() const override;
|
||||
android::dm::IDeviceMapper& GetDeviceMapper() override;
|
||||
|
||||
void set_first_stage_init(bool value) { first_stage_init_ = value; }
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ class ISnapshotManager {
|
|||
virtual bool IsTestDevice() const { return false; }
|
||||
virtual bool IsFirstStageInit() const = 0;
|
||||
virtual std::unique_ptr<IImageManager> OpenImageManager() const = 0;
|
||||
virtual android::dm::IDeviceMapper& GetDeviceMapper() = 0;
|
||||
|
||||
// Helper method for implementing OpenImageManager.
|
||||
std::unique_ptr<IImageManager> OpenImageManager(const std::string& gsid_dir) const;
|
||||
|
@ -611,6 +612,14 @@ class SnapshotManager final : public ISnapshotManager {
|
|||
MergeFailureCode CheckMergeConsistency(LockedFile* lock, const std::string& name,
|
||||
const SnapshotStatus& update_status);
|
||||
|
||||
// Get status or table information about a device-mapper node with a single target.
|
||||
enum class TableQuery {
|
||||
Table,
|
||||
Status,
|
||||
};
|
||||
bool GetSingleTarget(const std::string& dm_name, TableQuery query,
|
||||
android::dm::DeviceMapper::TargetInfo* target);
|
||||
|
||||
// Interact with status files under /metadata/ota/snapshots.
|
||||
bool WriteSnapshotStatus(LockedFile* lock, const SnapshotStatus& status);
|
||||
bool ReadSnapshotStatus(LockedFile* lock, const std::string& name, SnapshotStatus* status);
|
||||
|
@ -773,9 +782,9 @@ class SnapshotManager final : public ISnapshotManager {
|
|||
bool DeleteDeviceIfExists(const std::string& name,
|
||||
const std::chrono::milliseconds& timeout_ms = {});
|
||||
|
||||
std::string gsid_dir_;
|
||||
std::string metadata_dir_;
|
||||
android::dm::IDeviceMapper& dm_;
|
||||
std::unique_ptr<IDeviceInfo> device_;
|
||||
std::string metadata_dir_;
|
||||
std::unique_ptr<IImageManager> images_;
|
||||
bool use_first_stage_snapuserd_ = false;
|
||||
bool in_factory_data_reset_ = false;
|
||||
|
|
|
@ -99,6 +99,9 @@ class TestDeviceInfo : public SnapshotManager::IDeviceInfo {
|
|||
std::unique_ptr<IImageManager> OpenImageManager() const override {
|
||||
return IDeviceInfo::OpenImageManager("ota/test");
|
||||
}
|
||||
android::dm::IDeviceMapper& GetDeviceMapper() override {
|
||||
return android::dm::DeviceMapper::Instance();
|
||||
}
|
||||
|
||||
bool IsSlotUnbootable(uint32_t slot) { return unbootable_slots_.count(slot) != 0; }
|
||||
|
||||
|
|
|
@ -114,9 +114,8 @@ std::unique_ptr<SnapshotManager> SnapshotManager::NewForFirstStageMount(IDeviceI
|
|||
return sm;
|
||||
}
|
||||
|
||||
SnapshotManager::SnapshotManager(IDeviceInfo* device) : device_(device) {
|
||||
metadata_dir_ = device_->GetMetadataDir();
|
||||
}
|
||||
SnapshotManager::SnapshotManager(IDeviceInfo* device)
|
||||
: dm_(device->GetDeviceMapper()), device_(device), metadata_dir_(device_->GetMetadataDir()) {}
|
||||
|
||||
static std::string GetCowName(const std::string& snapshot_name) {
|
||||
return snapshot_name + "-cow";
|
||||
|
@ -402,8 +401,6 @@ bool SnapshotManager::MapDmUserCow(LockedFile* lock, const std::string& name,
|
|||
const std::chrono::milliseconds& timeout_ms, std::string* path) {
|
||||
CHECK(lock);
|
||||
|
||||
auto& dm = DeviceMapper::Instance();
|
||||
|
||||
// Use an extra decoration for first-stage init, so we can transition
|
||||
// to a new table entry in second-stage.
|
||||
std::string misc_name = name;
|
||||
|
@ -423,7 +420,7 @@ bool SnapshotManager::MapDmUserCow(LockedFile* lock, const std::string& name,
|
|||
|
||||
DmTable table;
|
||||
table.Emplace<DmTargetUser>(0, base_sectors, misc_name);
|
||||
if (!dm.CreateDevice(name, table, path, timeout_ms)) {
|
||||
if (!dm_.CreateDevice(name, table, path, timeout_ms)) {
|
||||
return false;
|
||||
}
|
||||
if (!WaitForDevice(*path, timeout_ms)) {
|
||||
|
@ -490,8 +487,6 @@ bool SnapshotManager::MapSnapshot(LockedFile* lock, const std::string& name,
|
|||
|
||||
uint64_t snapshot_sectors = status.snapshot_size() / kSectorSize;
|
||||
|
||||
auto& dm = DeviceMapper::Instance();
|
||||
|
||||
// Note that merging is a global state. We do track whether individual devices
|
||||
// have completed merging, but the start of the merge process is considered
|
||||
// atomic.
|
||||
|
@ -528,7 +523,7 @@ bool SnapshotManager::MapSnapshot(LockedFile* lock, const std::string& name,
|
|||
DmTable table;
|
||||
table.Emplace<DmTargetSnapshot>(0, snapshot_sectors, base_device, cow_device, mode,
|
||||
kSnapshotChunkSize);
|
||||
if (!dm.CreateDevice(name, table, dev_path, timeout_ms)) {
|
||||
if (!dm_.CreateDevice(name, table, dev_path, timeout_ms)) {
|
||||
LOG(ERROR) << "Could not create snapshot device: " << name;
|
||||
return false;
|
||||
}
|
||||
|
@ -659,7 +654,6 @@ bool SnapshotManager::InitiateMerge() {
|
|||
|
||||
auto other_suffix = device_->GetOtherSlotSuffix();
|
||||
|
||||
auto& dm = DeviceMapper::Instance();
|
||||
for (const auto& snapshot : snapshots) {
|
||||
if (android::base::EndsWith(snapshot, other_suffix)) {
|
||||
// Allow the merge to continue, but log this unexpected case.
|
||||
|
@ -671,7 +665,7 @@ bool SnapshotManager::InitiateMerge() {
|
|||
// the same time. This is a fairly serious error. We could forcefully
|
||||
// map everything here, but it should have been mapped during first-
|
||||
// stage init.
|
||||
if (dm.GetState(snapshot) == DmDeviceState::INVALID) {
|
||||
if (dm_.GetState(snapshot) == DmDeviceState::INVALID) {
|
||||
LOG(ERROR) << "Cannot begin merge; device " << snapshot << " is not mapped.";
|
||||
return false;
|
||||
}
|
||||
|
@ -804,10 +798,8 @@ MergeFailureCode SnapshotManager::SwitchSnapshotToMerge(LockedFile* lock, const
|
|||
}
|
||||
|
||||
MergeFailureCode SnapshotManager::RewriteSnapshotDeviceTable(const std::string& name) {
|
||||
auto& dm = DeviceMapper::Instance();
|
||||
|
||||
std::vector<DeviceMapper::TargetInfo> old_targets;
|
||||
if (!dm.GetTableInfo(name, &old_targets)) {
|
||||
if (!dm_.GetTableInfo(name, &old_targets)) {
|
||||
LOG(ERROR) << "Could not read snapshot device table: " << name;
|
||||
return MergeFailureCode::GetTableInfo;
|
||||
}
|
||||
|
@ -825,7 +817,7 @@ MergeFailureCode SnapshotManager::RewriteSnapshotDeviceTable(const std::string&
|
|||
DmTable table;
|
||||
table.Emplace<DmTargetSnapshot>(0, old_targets[0].spec.length, base_device, cow_device,
|
||||
SnapshotStorageMode::Merge, kSnapshotChunkSize);
|
||||
if (!dm.LoadTableAndActivate(name, table)) {
|
||||
if (!dm_.LoadTableAndActivate(name, table)) {
|
||||
LOG(ERROR) << "Could not swap device-mapper tables on snapshot device " << name;
|
||||
return MergeFailureCode::ActivateNewTable;
|
||||
}
|
||||
|
@ -833,24 +825,18 @@ MergeFailureCode SnapshotManager::RewriteSnapshotDeviceTable(const std::string&
|
|||
return MergeFailureCode::Ok;
|
||||
}
|
||||
|
||||
enum class TableQuery {
|
||||
Table,
|
||||
Status,
|
||||
};
|
||||
|
||||
static bool GetSingleTarget(const std::string& dm_name, TableQuery query,
|
||||
DeviceMapper::TargetInfo* target) {
|
||||
auto& dm = DeviceMapper::Instance();
|
||||
if (dm.GetState(dm_name) == DmDeviceState::INVALID) {
|
||||
bool SnapshotManager::GetSingleTarget(const std::string& dm_name, TableQuery query,
|
||||
DeviceMapper::TargetInfo* target) {
|
||||
if (dm_.GetState(dm_name) == DmDeviceState::INVALID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<DeviceMapper::TargetInfo> targets;
|
||||
bool result;
|
||||
if (query == TableQuery::Status) {
|
||||
result = dm.GetTableStatus(dm_name, &targets);
|
||||
result = dm_.GetTableStatus(dm_name, &targets);
|
||||
} else {
|
||||
result = dm.GetTableInfo(dm_name, &targets);
|
||||
result = dm_.GetTableInfo(dm_name, &targets);
|
||||
}
|
||||
if (!result) {
|
||||
LOG(ERROR) << "Could not query device: " << dm_name;
|
||||
|
@ -1180,11 +1166,9 @@ MergeFailureCode SnapshotManager::CheckMergeConsistency(LockedFile* lock, const
|
|||
return MergeFailureCode::Ok;
|
||||
}
|
||||
|
||||
auto& dm = DeviceMapper::Instance();
|
||||
|
||||
std::string cow_image_name = GetMappedCowDeviceName(name, status);
|
||||
std::string cow_image_path;
|
||||
if (!dm.GetDmDevicePathByName(cow_image_name, &cow_image_path)) {
|
||||
if (!dm_.GetDmDevicePathByName(cow_image_name, &cow_image_path)) {
|
||||
LOG(ERROR) << "Failed to get path for cow device: " << cow_image_name;
|
||||
return MergeFailureCode::GetCowPathConsistencyCheck;
|
||||
}
|
||||
|
@ -1360,8 +1344,6 @@ bool SnapshotManager::OnSnapshotMergeComplete(LockedFile* lock, const std::strin
|
|||
|
||||
bool SnapshotManager::CollapseSnapshotDevice(const std::string& name,
|
||||
const SnapshotStatus& status) {
|
||||
auto& dm = DeviceMapper::Instance();
|
||||
|
||||
// Verify we have a snapshot-merge device.
|
||||
DeviceMapper::TargetInfo target;
|
||||
if (!GetSingleTarget(name, TableQuery::Table, &target)) {
|
||||
|
@ -1400,7 +1382,7 @@ bool SnapshotManager::CollapseSnapshotDevice(const std::string& name,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!dm.LoadTableAndActivate(name, table)) {
|
||||
if (!dm_.LoadTableAndActivate(name, table)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1473,8 +1455,6 @@ bool SnapshotManager::PerformInitTransition(InitTransition transition,
|
|||
}
|
||||
}
|
||||
|
||||
auto& dm = DeviceMapper::Instance();
|
||||
|
||||
auto lock = LockExclusive();
|
||||
if (!lock) return false;
|
||||
|
||||
|
@ -1488,7 +1468,7 @@ bool SnapshotManager::PerformInitTransition(InitTransition transition,
|
|||
size_t ok_cows = 0;
|
||||
for (const auto& snapshot : snapshots) {
|
||||
std::string user_cow_name = GetDmUserCowName(snapshot);
|
||||
if (dm.GetState(user_cow_name) == DmDeviceState::INVALID) {
|
||||
if (dm_.GetState(user_cow_name) == DmDeviceState::INVALID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1515,7 +1495,7 @@ bool SnapshotManager::PerformInitTransition(InitTransition transition,
|
|||
|
||||
DmTable table;
|
||||
table.Emplace<DmTargetUser>(0, target.spec.length, misc_name);
|
||||
if (!dm.LoadTableAndActivate(user_cow_name, table)) {
|
||||
if (!dm_.LoadTableAndActivate(user_cow_name, table)) {
|
||||
LOG(ERROR) << "Unable to swap tables for " << misc_name;
|
||||
continue;
|
||||
}
|
||||
|
@ -1528,7 +1508,7 @@ bool SnapshotManager::PerformInitTransition(InitTransition transition,
|
|||
}
|
||||
|
||||
std::string source_device;
|
||||
if (!dm.GetDmDevicePathByName(source_device_name, &source_device)) {
|
||||
if (!dm_.GetDmDevicePathByName(source_device_name, &source_device)) {
|
||||
LOG(ERROR) << "Could not get device path for " << GetSourceDeviceName(snapshot);
|
||||
continue;
|
||||
}
|
||||
|
@ -1536,7 +1516,7 @@ bool SnapshotManager::PerformInitTransition(InitTransition transition,
|
|||
std::string cow_image_name = GetMappedCowDeviceName(snapshot, snapshot_status);
|
||||
|
||||
std::string cow_image_device;
|
||||
if (!dm.GetDmDevicePathByName(cow_image_name, &cow_image_device)) {
|
||||
if (!dm_.GetDmDevicePathByName(cow_image_name, &cow_image_device)) {
|
||||
LOG(ERROR) << "Could not get device path for " << cow_image_name;
|
||||
continue;
|
||||
}
|
||||
|
@ -1711,8 +1691,7 @@ bool SnapshotManager::RemoveAllSnapshots(LockedFile* lock) {
|
|||
// snapshot, but it's on the wrong slot. We can't unmap an active
|
||||
// partition. If this is not really a snapshot, skip the unmap
|
||||
// step.
|
||||
auto& dm = DeviceMapper::Instance();
|
||||
if (dm.GetState(name) == DmDeviceState::INVALID || !IsSnapshotDevice(name)) {
|
||||
if (dm_.GetState(name) == DmDeviceState::INVALID || !IsSnapshotDevice(name)) {
|
||||
LOG(ERROR) << "Detected snapshot " << name << " on " << current_slot << " slot"
|
||||
<< " for source partition; removing without unmap.";
|
||||
should_unmap = false;
|
||||
|
@ -2049,14 +2028,13 @@ bool SnapshotManager::MapPartitionWithSnapshot(LockedFile* lock,
|
|||
// Create the base device for the snapshot, or if there is no snapshot, the
|
||||
// device itself. This device consists of the real blocks in the super
|
||||
// partition that this logical partition occupies.
|
||||
auto& dm = DeviceMapper::Instance();
|
||||
std::string base_path;
|
||||
if (!CreateLogicalPartition(params, &base_path)) {
|
||||
LOG(ERROR) << "Could not create logical partition " << params.GetPartitionName()
|
||||
<< " as device " << params.GetDeviceName();
|
||||
return false;
|
||||
}
|
||||
created_devices.EmplaceBack<AutoUnmapDevice>(&dm, params.GetDeviceName());
|
||||
created_devices.EmplaceBack<AutoUnmapDevice>(&dm_, params.GetDeviceName());
|
||||
|
||||
if (paths) {
|
||||
paths->target_device = base_path;
|
||||
|
@ -2070,7 +2048,7 @@ bool SnapshotManager::MapPartitionWithSnapshot(LockedFile* lock,
|
|||
// We don't have ueventd in first-stage init, so use device major:minor
|
||||
// strings instead.
|
||||
std::string base_device;
|
||||
if (!dm.GetDeviceString(params.GetDeviceName(), &base_device)) {
|
||||
if (!dm_.GetDeviceString(params.GetDeviceName(), &base_device)) {
|
||||
LOG(ERROR) << "Could not determine major/minor for: " << params.GetDeviceName();
|
||||
return false;
|
||||
}
|
||||
|
@ -2113,7 +2091,7 @@ bool SnapshotManager::MapPartitionWithSnapshot(LockedFile* lock,
|
|||
}
|
||||
|
||||
auto source_device = GetSourceDeviceName(params.GetPartitionName());
|
||||
created_devices.EmplaceBack<AutoUnmapDevice>(&dm, source_device);
|
||||
created_devices.EmplaceBack<AutoUnmapDevice>(&dm_, source_device);
|
||||
} else {
|
||||
source_device_path = base_path;
|
||||
}
|
||||
|
@ -2140,7 +2118,7 @@ bool SnapshotManager::MapPartitionWithSnapshot(LockedFile* lock,
|
|||
<< params.GetPartitionName();
|
||||
return false;
|
||||
}
|
||||
created_devices.EmplaceBack<AutoUnmapDevice>(&dm, name);
|
||||
created_devices.EmplaceBack<AutoUnmapDevice>(&dm_, name);
|
||||
|
||||
remaining_time = GetRemainingTime(params.timeout_ms, begin);
|
||||
if (remaining_time.count() < 0) return false;
|
||||
|
@ -2206,8 +2184,6 @@ bool SnapshotManager::MapCowDevices(LockedFile* lock, const CreateLogicalPartiti
|
|||
std::string cow_image_name = GetCowImageDeviceName(partition_name);
|
||||
*cow_name = GetCowName(partition_name);
|
||||
|
||||
auto& dm = DeviceMapper::Instance();
|
||||
|
||||
// Map COW image if necessary.
|
||||
if (snapshot_status.cow_file_size() > 0) {
|
||||
if (!EnsureImageManager()) return false;
|
||||
|
@ -2258,11 +2234,11 @@ bool SnapshotManager::MapCowDevices(LockedFile* lock, const CreateLogicalPartiti
|
|||
|
||||
// We have created the DmTable now. Map it.
|
||||
std::string cow_path;
|
||||
if (!dm.CreateDevice(*cow_name, table, &cow_path, remaining_time)) {
|
||||
if (!dm_.CreateDevice(*cow_name, table, &cow_path, remaining_time)) {
|
||||
LOG(ERROR) << "Could not create COW device: " << *cow_name;
|
||||
return false;
|
||||
}
|
||||
created_devices->EmplaceBack<AutoUnmapDevice>(&dm, *cow_name);
|
||||
created_devices->EmplaceBack<AutoUnmapDevice>(&dm_, *cow_name);
|
||||
LOG(INFO) << "Mapped COW device for " << params.GetPartitionName() << " at " << cow_path;
|
||||
return true;
|
||||
}
|
||||
|
@ -2289,10 +2265,8 @@ bool SnapshotManager::UnmapCowDevices(LockedFile* lock, const std::string& name)
|
|||
}
|
||||
|
||||
bool SnapshotManager::UnmapDmUserDevice(const std::string& snapshot_name) {
|
||||
auto& dm = DeviceMapper::Instance();
|
||||
|
||||
auto dm_user_name = GetDmUserCowName(snapshot_name);
|
||||
if (dm.GetState(dm_user_name) == DmDeviceState::INVALID) {
|
||||
if (dm_.GetState(dm_user_name) == DmDeviceState::INVALID) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3512,7 +3486,6 @@ bool SnapshotManager::EnsureNoOverflowSnapshot(LockedFile* lock) {
|
|||
return false;
|
||||
}
|
||||
|
||||
auto& dm = DeviceMapper::Instance();
|
||||
for (const auto& snapshot : snapshots) {
|
||||
SnapshotStatus status;
|
||||
if (!ReadSnapshotStatus(lock, snapshot, &status)) {
|
||||
|
@ -3523,7 +3496,7 @@ bool SnapshotManager::EnsureNoOverflowSnapshot(LockedFile* lock) {
|
|||
}
|
||||
|
||||
std::vector<DeviceMapper::TargetInfo> targets;
|
||||
if (!dm.GetTableStatus(snapshot, &targets)) {
|
||||
if (!dm_.GetTableStatus(snapshot, &targets)) {
|
||||
LOG(ERROR) << "Could not read snapshot device table: " << snapshot;
|
||||
return false;
|
||||
}
|
||||
|
@ -3616,11 +3589,9 @@ ISnapshotMergeStats* SnapshotManager::GetSnapshotMergeStatsInstance() {
|
|||
// isn't running yet.
|
||||
bool SnapshotManager::GetMappedImageDevicePath(const std::string& device_name,
|
||||
std::string* device_path) {
|
||||
auto& dm = DeviceMapper::Instance();
|
||||
|
||||
// Try getting the device string if it is a device mapper device.
|
||||
if (dm.GetState(device_name) != DmDeviceState::INVALID) {
|
||||
return dm.GetDmDevicePathByName(device_name, device_path);
|
||||
if (dm_.GetState(device_name) != DmDeviceState::INVALID) {
|
||||
return dm_.GetDmDevicePathByName(device_name, device_path);
|
||||
}
|
||||
|
||||
// Otherwise, get path from IImageManager.
|
||||
|
@ -3629,10 +3600,9 @@ bool SnapshotManager::GetMappedImageDevicePath(const std::string& device_name,
|
|||
|
||||
bool SnapshotManager::GetMappedImageDeviceStringOrPath(const std::string& device_name,
|
||||
std::string* device_string_or_mapped_path) {
|
||||
auto& dm = DeviceMapper::Instance();
|
||||
// Try getting the device string if it is a device mapper device.
|
||||
if (dm.GetState(device_name) != DmDeviceState::INVALID) {
|
||||
return dm.GetDeviceString(device_name, device_string_or_mapped_path);
|
||||
if (dm_.GetState(device_name) != DmDeviceState::INVALID) {
|
||||
return dm_.GetDeviceString(device_name, device_string_or_mapped_path);
|
||||
}
|
||||
|
||||
// Otherwise, get path from IImageManager.
|
||||
|
@ -3748,10 +3718,9 @@ void SnapshotManager::UpdateCowStats(ISnapshotMergeStats* stats) {
|
|||
|
||||
bool SnapshotManager::DeleteDeviceIfExists(const std::string& name,
|
||||
const std::chrono::milliseconds& timeout_ms) {
|
||||
auto& dm = DeviceMapper::Instance();
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
while (true) {
|
||||
if (dm.DeleteDeviceIfExists(name)) {
|
||||
if (dm_.DeleteDeviceIfExists(name)) {
|
||||
return true;
|
||||
}
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
|
@ -3764,7 +3733,7 @@ bool SnapshotManager::DeleteDeviceIfExists(const std::string& name,
|
|||
|
||||
// Try to diagnose why this failed. First get the actual device path.
|
||||
std::string full_path;
|
||||
if (!dm.GetDmDevicePathByName(name, &full_path)) {
|
||||
if (!dm_.GetDmDevicePathByName(name, &full_path)) {
|
||||
LOG(ERROR) << "Unable to diagnose DM_DEV_REMOVE failure.";
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -101,7 +101,8 @@ class SnapshotFuzzDeviceInfo : public ISnapshotManager::IDeviceInfo {
|
|||
: env_(env),
|
||||
data_(&data),
|
||||
partition_opener_(std::move(partition_opener)),
|
||||
metadata_dir_(metadata_dir) {}
|
||||
metadata_dir_(metadata_dir),
|
||||
dm_(android::dm::DeviceMapper::Instance()) {}
|
||||
|
||||
// Following APIs are mocked.
|
||||
std::string GetMetadataDir() const override { return metadata_dir_; }
|
||||
|
@ -125,6 +126,7 @@ class SnapshotFuzzDeviceInfo : public ISnapshotManager::IDeviceInfo {
|
|||
}
|
||||
bool IsRecovery() const override { return data_->is_recovery(); }
|
||||
bool IsFirstStageInit() const override { return false; }
|
||||
android::dm::IDeviceMapper& GetDeviceMapper() override { return dm_; }
|
||||
std::unique_ptr<IImageManager> OpenImageManager() const {
|
||||
return env_->CheckCreateFakeImageManager();
|
||||
}
|
||||
|
@ -137,6 +139,7 @@ class SnapshotFuzzDeviceInfo : public ISnapshotManager::IDeviceInfo {
|
|||
std::unique_ptr<TestPartitionOpener> partition_opener_;
|
||||
std::string metadata_dir_;
|
||||
bool switched_slot_ = false;
|
||||
android::dm::DeviceMapper& dm_;
|
||||
|
||||
bool CurrentSlotIsA() const { return data_->slot_suffix_is_a() != switched_slot_; }
|
||||
};
|
||||
|
|
|
@ -57,14 +57,14 @@ struct AutoDeviceList {
|
|||
// Automatically unmap a device upon deletion.
|
||||
struct AutoUnmapDevice : AutoDevice {
|
||||
// On destruct, delete |name| from device mapper.
|
||||
AutoUnmapDevice(android::dm::DeviceMapper* dm, const std::string& name)
|
||||
AutoUnmapDevice(android::dm::IDeviceMapper* dm, const std::string& name)
|
||||
: AutoDevice(name), dm_(dm) {}
|
||||
AutoUnmapDevice(AutoUnmapDevice&& other) = default;
|
||||
~AutoUnmapDevice();
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(AutoUnmapDevice);
|
||||
android::dm::DeviceMapper* dm_ = nullptr;
|
||||
android::dm::IDeviceMapper* dm_ = nullptr;
|
||||
};
|
||||
|
||||
// Automatically unmap an image upon deletion.
|
||||
|
|
Loading…
Reference in a new issue