Loading fastboot/device/utility.cpp +9 −1 Original line number Diff line number Diff line Loading @@ -56,8 +56,16 @@ bool OpenLogicalPartition(FastbootDevice* device, const std::string& partition_n if (!path) { return false; } CreateLogicalPartitionParams params = { .block_device = *path, .metadata_slot = slot_number, .partition_name = partition_name, .force_writable = true, .timeout_ms = 5s, }; std::string dm_path; if (!CreateLogicalPartition(path->c_str(), slot_number, partition_name, true, 5s, &dm_path)) { if (!CreateLogicalPartition(params, &dm_path)) { LOG(ERROR) << "Could not map partition: " << partition_name; return false; } Loading fs_mgr/fs_mgr_dm_linear.cpp +57 −41 Original line number Diff line number Diff line Loading @@ -109,26 +109,6 @@ static bool CreateDmTable(const LpMetadata& metadata, const LpMetadataPartition& return true; } static bool CreateLogicalPartition(const LpMetadata& metadata, const LpMetadataPartition& partition, bool force_writable, const std::chrono::milliseconds& timeout_ms, const std::string& super_device, std::string* path) { DeviceMapper& dm = DeviceMapper::Instance(); DmTable table; if (!CreateDmTable(metadata, partition, super_device, &table)) { return false; } if (force_writable) { table.set_readonly(false); } std::string name = GetPartitionName(partition); if (!dm.CreateDevice(name, table, path, timeout_ms)) { return false; } LINFO << "Created logical partition " << name << " on device " << *path; return true; } bool CreateLogicalPartitions(const std::string& block_device) { uint32_t slot = SlotNumberForSlotSuffix(fs_mgr_get_slot_suffix()); auto metadata = ReadMetadata(block_device.c_str(), slot); Loading @@ -145,13 +125,20 @@ std::unique_ptr<LpMetadata> ReadCurrentMetadata(const std::string& block_device) } bool CreateLogicalPartitions(const LpMetadata& metadata, const std::string& super_device) { CreateLogicalPartitionParams params = { .block_device = super_device, .metadata = &metadata, }; for (const auto& partition : metadata.partitions) { if (!partition.num_extents) { LINFO << "Skipping zero-length logical partition: " << GetPartitionName(partition); continue; } std::string path; if (!CreateLogicalPartition(metadata, partition, false, {}, super_device, &path)) { params.partition = &partition; std::string ignore_path; if (!CreateLogicalPartition(params, &ignore_path)) { LERROR << "Could not create logical partition: " << GetPartitionName(partition); return false; } Loading @@ -159,29 +146,58 @@ bool CreateLogicalPartitions(const LpMetadata& metadata, const std::string& supe return true; } bool CreateLogicalPartition(const std::string& block_device, const LpMetadata& metadata, const std::string& partition_name, bool force_writable, const std::chrono::milliseconds& timeout_ms, std::string* path) { for (const auto& partition : metadata.partitions) { if (GetPartitionName(partition) == partition_name) { return CreateLogicalPartition(metadata, partition, force_writable, timeout_ms, block_device, path); bool CreateLogicalPartition(const CreateLogicalPartitionParams& params, std::string* path) { const LpMetadata* metadata = params.metadata; // Read metadata if needed. std::unique_ptr<LpMetadata> local_metadata; if (!metadata) { if (!params.metadata_slot) { LOG(ERROR) << "Either metadata or a metadata slot must be specified."; return false; } auto slot = *params.metadata_slot; if (local_metadata = ReadMetadata(params.block_device, slot); !local_metadata) { LOG(ERROR) << "Could not read partition table for: " << params.block_device; return false; } metadata = local_metadata.get(); } // Find the partition by name if needed. const LpMetadataPartition* partition = params.partition; if (!partition) { for (const auto& iter : metadata->partitions) { if (GetPartitionName(iter) == params.partition_name) { partition = &iter; break; } } LERROR << "Could not find any partition with name: " << partition_name; if (!partition) { LERROR << "Could not find any partition with name: " << params.partition_name; return false; } } bool CreateLogicalPartition(const std::string& block_device, uint32_t metadata_slot, const std::string& partition_name, bool force_writable, const std::chrono::milliseconds& timeout_ms, std::string* path) { auto metadata = ReadMetadata(block_device.c_str(), metadata_slot); if (!metadata) { LOG(ERROR) << "Could not read partition table."; return true; DmTable table; if (!CreateDmTable(*metadata, *partition, params.block_device, &table)) { return false; } if (params.force_writable) { table.set_readonly(false); } std::string device_name = params.device_name; if (device_name.empty()) { device_name = GetPartitionName(*partition); } return CreateLogicalPartition(block_device, *metadata.get(), partition_name, force_writable, timeout_ms, path); DeviceMapper& dm = DeviceMapper::Instance(); if (!dm.CreateDevice(device_name, table, path, params.timeout_ms)) { return false; } LINFO << "Created logical partition " << device_name << " on device " << *path; return true; } bool UnmapDevice(const std::string& name) { Loading fs_mgr/fs_mgr_overlayfs.cpp +18 −7 Original line number Diff line number Diff line Loading @@ -959,9 +959,16 @@ bool fs_mgr_overlayfs_create_scratch(const Fstab& fstab, std::string* scratch_de } if (changed || partition_create) { if (!CreateLogicalPartition(super_device, slot_number, partition_name, true, 10s, scratch_device)) CreateLogicalPartitionParams params = { .block_device = super_device, .metadata_slot = slot_number, .partition_name = partition_name, .force_writable = true, .timeout_ms = 10s, }; if (!CreateLogicalPartition(params, scratch_device)) { return false; } if (change) *change = true; } Loading Loading @@ -1182,11 +1189,15 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) { if ((mount_point != nullptr) && !fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) { auto scratch_device = fs_mgr_overlayfs_scratch_device(); if (scratch_device.empty()) { auto slot_number = fs_mgr_overlayfs_slot_number(); auto super_device = fs_mgr_overlayfs_super_device(slot_number); const auto partition_name = android::base::Basename(kScratchMountPoint); CreateLogicalPartition(super_device, slot_number, partition_name, true, 10s, &scratch_device); auto metadata_slot = fs_mgr_overlayfs_slot_number(); CreateLogicalPartitionParams params = { .block_device = fs_mgr_overlayfs_super_device(metadata_slot), .metadata_slot = metadata_slot, .partition_name = android::base::Basename(kScratchMountPoint), .force_writable = true, .timeout_ms = 10s, }; CreateLogicalPartition(params, &scratch_device); } mount_scratch = fs_mgr_overlayfs_mount_scratch(scratch_device, fs_mgr_overlayfs_scratch_mount_type()); Loading fs_mgr/include/fs_mgr_dm_linear.h +27 −16 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <chrono> #include <memory> #include <optional> #include <string> #include <vector> Loading @@ -49,22 +50,32 @@ bool CreateLogicalPartitions(const LpMetadata& metadata, const std::string& bloc // method for ReadMetadata and CreateLogicalPartitions. bool CreateLogicalPartitions(const std::string& block_device); // Create a block device for a single logical partition, given metadata and // the partition name. On success, a path to the partition's block device is // returned. If |force_writable| is true, the "readonly" flag will be ignored // so the partition can be flashed. // // If |timeout_ms| is non-zero, then CreateLogicalPartition will block for the // given amount of time until the path returned in |path| is available. bool CreateLogicalPartition(const std::string& block_device, uint32_t metadata_slot, const std::string& partition_name, bool force_writable, const std::chrono::milliseconds& timeout_ms, std::string* path); // Same as above, but with a given metadata object. Care should be taken that // the metadata represents a valid partition layout. bool CreateLogicalPartition(const std::string& block_device, const LpMetadata& metadata, const std::string& partition_name, bool force_writable, const std::chrono::milliseconds& timeout_ms, std::string* path); struct CreateLogicalPartitionParams { // Block device of the super partition. std::string block_device; // If |metadata| is null, the slot will be read using |metadata_slot|. const LpMetadata* metadata = nullptr; std::optional<uint32_t> metadata_slot; // If |partition| is not set, it will be found via |partition_name|. const LpMetadataPartition* partition = nullptr; std::string partition_name; // Force the device to be read-write even if it was specified as readonly // in the metadata. bool force_writable = false; // If |timeout_ms| is non-zero, then CreateLogicalPartition will block for // the given amount of time until the path returned in |path| is available. std::chrono::milliseconds timeout_ms = {}; // If this is non-empty, it will override the device mapper name (by // default the partition name will be used). std::string device_name; }; bool CreateLogicalPartition(const CreateLogicalPartitionParams& params, std::string* path); // Destroy the block device for a logical partition, by name. If |timeout_ms| // is non-zero, then this will block until the device path has been unlinked. Loading Loading
fastboot/device/utility.cpp +9 −1 Original line number Diff line number Diff line Loading @@ -56,8 +56,16 @@ bool OpenLogicalPartition(FastbootDevice* device, const std::string& partition_n if (!path) { return false; } CreateLogicalPartitionParams params = { .block_device = *path, .metadata_slot = slot_number, .partition_name = partition_name, .force_writable = true, .timeout_ms = 5s, }; std::string dm_path; if (!CreateLogicalPartition(path->c_str(), slot_number, partition_name, true, 5s, &dm_path)) { if (!CreateLogicalPartition(params, &dm_path)) { LOG(ERROR) << "Could not map partition: " << partition_name; return false; } Loading
fs_mgr/fs_mgr_dm_linear.cpp +57 −41 Original line number Diff line number Diff line Loading @@ -109,26 +109,6 @@ static bool CreateDmTable(const LpMetadata& metadata, const LpMetadataPartition& return true; } static bool CreateLogicalPartition(const LpMetadata& metadata, const LpMetadataPartition& partition, bool force_writable, const std::chrono::milliseconds& timeout_ms, const std::string& super_device, std::string* path) { DeviceMapper& dm = DeviceMapper::Instance(); DmTable table; if (!CreateDmTable(metadata, partition, super_device, &table)) { return false; } if (force_writable) { table.set_readonly(false); } std::string name = GetPartitionName(partition); if (!dm.CreateDevice(name, table, path, timeout_ms)) { return false; } LINFO << "Created logical partition " << name << " on device " << *path; return true; } bool CreateLogicalPartitions(const std::string& block_device) { uint32_t slot = SlotNumberForSlotSuffix(fs_mgr_get_slot_suffix()); auto metadata = ReadMetadata(block_device.c_str(), slot); Loading @@ -145,13 +125,20 @@ std::unique_ptr<LpMetadata> ReadCurrentMetadata(const std::string& block_device) } bool CreateLogicalPartitions(const LpMetadata& metadata, const std::string& super_device) { CreateLogicalPartitionParams params = { .block_device = super_device, .metadata = &metadata, }; for (const auto& partition : metadata.partitions) { if (!partition.num_extents) { LINFO << "Skipping zero-length logical partition: " << GetPartitionName(partition); continue; } std::string path; if (!CreateLogicalPartition(metadata, partition, false, {}, super_device, &path)) { params.partition = &partition; std::string ignore_path; if (!CreateLogicalPartition(params, &ignore_path)) { LERROR << "Could not create logical partition: " << GetPartitionName(partition); return false; } Loading @@ -159,29 +146,58 @@ bool CreateLogicalPartitions(const LpMetadata& metadata, const std::string& supe return true; } bool CreateLogicalPartition(const std::string& block_device, const LpMetadata& metadata, const std::string& partition_name, bool force_writable, const std::chrono::milliseconds& timeout_ms, std::string* path) { for (const auto& partition : metadata.partitions) { if (GetPartitionName(partition) == partition_name) { return CreateLogicalPartition(metadata, partition, force_writable, timeout_ms, block_device, path); bool CreateLogicalPartition(const CreateLogicalPartitionParams& params, std::string* path) { const LpMetadata* metadata = params.metadata; // Read metadata if needed. std::unique_ptr<LpMetadata> local_metadata; if (!metadata) { if (!params.metadata_slot) { LOG(ERROR) << "Either metadata or a metadata slot must be specified."; return false; } auto slot = *params.metadata_slot; if (local_metadata = ReadMetadata(params.block_device, slot); !local_metadata) { LOG(ERROR) << "Could not read partition table for: " << params.block_device; return false; } metadata = local_metadata.get(); } // Find the partition by name if needed. const LpMetadataPartition* partition = params.partition; if (!partition) { for (const auto& iter : metadata->partitions) { if (GetPartitionName(iter) == params.partition_name) { partition = &iter; break; } } LERROR << "Could not find any partition with name: " << partition_name; if (!partition) { LERROR << "Could not find any partition with name: " << params.partition_name; return false; } } bool CreateLogicalPartition(const std::string& block_device, uint32_t metadata_slot, const std::string& partition_name, bool force_writable, const std::chrono::milliseconds& timeout_ms, std::string* path) { auto metadata = ReadMetadata(block_device.c_str(), metadata_slot); if (!metadata) { LOG(ERROR) << "Could not read partition table."; return true; DmTable table; if (!CreateDmTable(*metadata, *partition, params.block_device, &table)) { return false; } if (params.force_writable) { table.set_readonly(false); } std::string device_name = params.device_name; if (device_name.empty()) { device_name = GetPartitionName(*partition); } return CreateLogicalPartition(block_device, *metadata.get(), partition_name, force_writable, timeout_ms, path); DeviceMapper& dm = DeviceMapper::Instance(); if (!dm.CreateDevice(device_name, table, path, params.timeout_ms)) { return false; } LINFO << "Created logical partition " << device_name << " on device " << *path; return true; } bool UnmapDevice(const std::string& name) { Loading
fs_mgr/fs_mgr_overlayfs.cpp +18 −7 Original line number Diff line number Diff line Loading @@ -959,9 +959,16 @@ bool fs_mgr_overlayfs_create_scratch(const Fstab& fstab, std::string* scratch_de } if (changed || partition_create) { if (!CreateLogicalPartition(super_device, slot_number, partition_name, true, 10s, scratch_device)) CreateLogicalPartitionParams params = { .block_device = super_device, .metadata_slot = slot_number, .partition_name = partition_name, .force_writable = true, .timeout_ms = 10s, }; if (!CreateLogicalPartition(params, scratch_device)) { return false; } if (change) *change = true; } Loading Loading @@ -1182,11 +1189,15 @@ bool fs_mgr_overlayfs_teardown(const char* mount_point, bool* change) { if ((mount_point != nullptr) && !fs_mgr_overlayfs_already_mounted(kScratchMountPoint, false)) { auto scratch_device = fs_mgr_overlayfs_scratch_device(); if (scratch_device.empty()) { auto slot_number = fs_mgr_overlayfs_slot_number(); auto super_device = fs_mgr_overlayfs_super_device(slot_number); const auto partition_name = android::base::Basename(kScratchMountPoint); CreateLogicalPartition(super_device, slot_number, partition_name, true, 10s, &scratch_device); auto metadata_slot = fs_mgr_overlayfs_slot_number(); CreateLogicalPartitionParams params = { .block_device = fs_mgr_overlayfs_super_device(metadata_slot), .metadata_slot = metadata_slot, .partition_name = android::base::Basename(kScratchMountPoint), .force_writable = true, .timeout_ms = 10s, }; CreateLogicalPartition(params, &scratch_device); } mount_scratch = fs_mgr_overlayfs_mount_scratch(scratch_device, fs_mgr_overlayfs_scratch_mount_type()); Loading
fs_mgr/include/fs_mgr_dm_linear.h +27 −16 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <chrono> #include <memory> #include <optional> #include <string> #include <vector> Loading @@ -49,22 +50,32 @@ bool CreateLogicalPartitions(const LpMetadata& metadata, const std::string& bloc // method for ReadMetadata and CreateLogicalPartitions. bool CreateLogicalPartitions(const std::string& block_device); // Create a block device for a single logical partition, given metadata and // the partition name. On success, a path to the partition's block device is // returned. If |force_writable| is true, the "readonly" flag will be ignored // so the partition can be flashed. // // If |timeout_ms| is non-zero, then CreateLogicalPartition will block for the // given amount of time until the path returned in |path| is available. bool CreateLogicalPartition(const std::string& block_device, uint32_t metadata_slot, const std::string& partition_name, bool force_writable, const std::chrono::milliseconds& timeout_ms, std::string* path); // Same as above, but with a given metadata object. Care should be taken that // the metadata represents a valid partition layout. bool CreateLogicalPartition(const std::string& block_device, const LpMetadata& metadata, const std::string& partition_name, bool force_writable, const std::chrono::milliseconds& timeout_ms, std::string* path); struct CreateLogicalPartitionParams { // Block device of the super partition. std::string block_device; // If |metadata| is null, the slot will be read using |metadata_slot|. const LpMetadata* metadata = nullptr; std::optional<uint32_t> metadata_slot; // If |partition| is not set, it will be found via |partition_name|. const LpMetadataPartition* partition = nullptr; std::string partition_name; // Force the device to be read-write even if it was specified as readonly // in the metadata. bool force_writable = false; // If |timeout_ms| is non-zero, then CreateLogicalPartition will block for // the given amount of time until the path returned in |path| is available. std::chrono::milliseconds timeout_ms = {}; // If this is non-empty, it will override the device mapper name (by // default the partition name will be used). std::string device_name; }; bool CreateLogicalPartition(const CreateLogicalPartitionParams& params, std::string* path); // Destroy the block device for a logical partition, by name. If |timeout_ms| // is non-zero, then this will block until the device path has been unlinked. Loading