Merge "liblp: CreateLogicalPartition with a given mapped name"
This commit is contained in:
commit
1d6d4507a4
4 changed files with 110 additions and 64 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
if (!partition) {
|
||||
LERROR << "Could not find any partition with name: " << params.partition_name;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
LERROR << "Could not find any partition with name: " << 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;
|
||||
}
|
||||
return CreateLogicalPartition(block_device, *metadata.get(), partition_name, force_writable,
|
||||
timeout_ms, path);
|
||||
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)) {
|
||||
return false;
|
||||
}
|
||||
LINFO << "Created logical partition " << device_name << " on device " << *path;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UnmapDevice(const std::string& name) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -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());
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -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);
|
||||
struct CreateLogicalPartitionParams {
|
||||
// Block device of the super partition.
|
||||
std::string block_device;
|
||||
|
||||
// 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);
|
||||
// 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…
Reference in a new issue