From 1ada55e42ac587a037336c29f628b795b940f366 Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Fri, 16 Aug 2019 15:31:12 -0700 Subject: [PATCH] fs_mgr: Allow to set defaults for CreateLogicalPartitionParams Test: boots Change-Id: I6a969a19b9d29e682f50872bd3e9027eaca41512 --- fs_mgr/fs_mgr_dm_linear.cpp | 70 +++++++++++++++++++------------ fs_mgr/include/fs_mgr_dm_linear.h | 17 +++++++- 2 files changed, 59 insertions(+), 28 deletions(-) diff --git a/fs_mgr/fs_mgr_dm_linear.cpp b/fs_mgr/fs_mgr_dm_linear.cpp index fa756a06e..aa514bb63 100644 --- a/fs_mgr/fs_mgr_dm_linear.cpp +++ b/fs_mgr/fs_mgr_dm_linear.cpp @@ -154,61 +154,77 @@ bool CreateLogicalPartitions(const LpMetadata& metadata, const std::string& supe return true; } -bool CreateLogicalPartition(const CreateLogicalPartitionParams& params, std::string* path) { - const LpMetadata* metadata = params.metadata; +bool CreateLogicalPartitionParams::InitDefaults(CreateLogicalPartitionParams::OwnedData* owned) { + if (block_device.empty()) { + LOG(ERROR) << "block_device is required for CreateLogicalPartition"; + return false; + } // Read metadata if needed. - std::unique_ptr local_metadata; if (!metadata) { - if (!params.metadata_slot) { + if (!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; + auto slot = *metadata_slot; + if (owned->metadata = ReadMetadata(block_device, slot); !owned->metadata) { + LOG(ERROR) << "Could not read partition table for: " << block_device; return false; } - metadata = local_metadata.get(); + metadata = owned->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; + for (const auto& metadata_partition : metadata->partitions) { + if (android::fs_mgr::GetPartitionName(metadata_partition) == partition_name) { + partition = &metadata_partition; break; } } - if (!partition) { - LERROR << "Could not find any partition with name: " << params.partition_name; - return false; - } + } + if (!partition) { + LERROR << "Could not find any partition with name: " << partition_name; + return false; + } + if (partition_name.empty()) { + partition_name = android::fs_mgr::GetPartitionName(*partition); + } else if (partition_name != android::fs_mgr::GetPartitionName(*partition)) { + LERROR << "Inconsistent partition_name " << partition_name << " with partition " + << android::fs_mgr::GetPartitionName(*partition); + return false; } - PartitionOpener default_opener; - const IPartitionOpener* opener = - params.partition_opener ? params.partition_opener : &default_opener; + if (!partition_opener) { + owned->partition_opener = std::make_unique(); + partition_opener = owned->partition_opener.get(); + } + + if (device_name.empty()) { + device_name = partition_name; + } + + return true; +} + +bool CreateLogicalPartition(CreateLogicalPartitionParams params, std::string* path) { + CreateLogicalPartitionParams::OwnedData owned_data; + if (!params.InitDefaults(&owned_data)) return false; DmTable table; - if (!CreateDmTable(*opener, *metadata, *partition, params.block_device, &table)) { + if (!CreateDmTable(*params.partition_opener, *params.metadata, *params.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); - } - DeviceMapper& dm = DeviceMapper::Instance(); - if (!dm.CreateDevice(device_name, table, path, params.timeout_ms)) { + if (!dm.CreateDevice(params.device_name, table, path, params.timeout_ms)) { return false; } - LINFO << "Created logical partition " << device_name << " on device " << *path; + LINFO << "Created logical partition " << params.device_name << " on device " << *path; return true; } diff --git a/fs_mgr/include/fs_mgr_dm_linear.h b/fs_mgr/include/fs_mgr_dm_linear.h index 2054fa183..ebeae327e 100644 --- a/fs_mgr/include/fs_mgr_dm_linear.h +++ b/fs_mgr/include/fs_mgr_dm_linear.h @@ -81,9 +81,24 @@ struct CreateLogicalPartitionParams { // Helpers for determining the effective partition and device name. std::string GetPartitionName() const; std::string GetDeviceName() const; + + // Specify ownership of fields. The ownership of these fields are managed + // by the caller of InitDefaults(). + // These are not declared in CreateLogicalPartitionParams so that the + // copy constructor is not deleted. + struct OwnedData { + std::unique_ptr metadata; + std::unique_ptr partition_opener; + }; + + // Fill in default values for |params| that CreateLogicalPartition assumes. Caller does + // not need to call this before calling CreateLogicalPartition; CreateLogicalPartition sets + // values when they are missing. + // Caller is responsible for destroying owned_data when |this| is not used. + bool InitDefaults(OwnedData* owned); }; -bool CreateLogicalPartition(const CreateLogicalPartitionParams& params, std::string* path); +bool CreateLogicalPartition(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.