Merge "fs_mgr: Allow using major:minor device strings in CreateLogicalPartition."

This commit is contained in:
David Anderson 2019-08-20 20:42:24 +00:00 committed by Gerrit Code Review
commit 63fe0e9a36
4 changed files with 43 additions and 17 deletions

View file

@ -52,29 +52,36 @@ using DmTarget = android::dm::DmTarget;
using DmTargetZero = android::dm::DmTargetZero;
using DmTargetLinear = android::dm::DmTargetLinear;
static bool GetPhysicalPartitionDevicePath(const LpMetadata& metadata,
static bool GetPhysicalPartitionDevicePath(const IPartitionOpener& opener,
const LpMetadata& metadata,
const LpMetadataBlockDevice& block_device,
const std::string& super_device,
std::string* result) {
// Note: device-mapper will not accept symlinks, so we must use realpath
// here.
std::string name = GetBlockDevicePartitionName(block_device);
std::string path = "/dev/block/by-name/" + name;
const std::string& super_device, std::string* result) {
// If the super device is the source of this block device's metadata,
// make sure we use the correct super device (and not just "super",
// which might not exist.)
std::string name = GetBlockDevicePartitionName(block_device);
std::string dev_string = opener.GetDeviceString(name);
if (GetMetadataSuperBlockDevice(metadata) == &block_device) {
path = super_device;
dev_string = opener.GetDeviceString(super_device);
}
if (!android::base::Realpath(path, result)) {
PERROR << "realpath: " << path;
return false;
// Note: device-mapper will not accept symlinks, so we must use realpath
// here. If the device string is a major:minor sequence, we don't need to
// to call Realpath (it would not work anyway).
if (android::base::StartsWith(dev_string, "/")) {
if (!android::base::Realpath(dev_string, result)) {
PERROR << "realpath: " << dev_string;
return false;
}
} else {
*result = dev_string;
}
return true;
}
static bool CreateDmTable(const LpMetadata& metadata, const LpMetadataPartition& partition,
const std::string& super_device, DmTable* table) {
static bool CreateDmTable(const IPartitionOpener& opener, const LpMetadata& metadata,
const LpMetadataPartition& partition, const std::string& super_device,
DmTable* table) {
uint64_t sector = 0;
for (size_t i = 0; i < partition.num_extents; i++) {
const auto& extent = metadata.extents[partition.first_extent_index + i];
@ -85,12 +92,13 @@ static bool CreateDmTable(const LpMetadata& metadata, const LpMetadataPartition&
break;
case LP_TARGET_TYPE_LINEAR: {
const auto& block_device = metadata.block_devices[extent.target_source];
std::string path;
if (!GetPhysicalPartitionDevicePath(metadata, block_device, super_device, &path)) {
std::string dev_string;
if (!GetPhysicalPartitionDevicePath(opener, metadata, block_device, super_device,
&dev_string)) {
LOG(ERROR) << "Unable to complete device-mapper table, unknown block device";
return false;
}
target = std::make_unique<DmTargetLinear>(sector, extent.num_sectors, path,
target = std::make_unique<DmTargetLinear>(sector, extent.num_sectors, dev_string,
extent.target_data);
break;
}
@ -179,8 +187,12 @@ bool CreateLogicalPartition(const CreateLogicalPartitionParams& params, std::str
}
}
PartitionOpener default_opener;
const IPartitionOpener* opener =
params.partition_opener ? params.partition_opener : &default_opener;
DmTable table;
if (!CreateDmTable(*metadata, *partition, params.block_device, &table)) {
if (!CreateDmTable(*opener, *metadata, *partition, params.block_device, &table)) {
return false;
}
if (params.force_writable) {

View file

@ -73,6 +73,10 @@ struct CreateLogicalPartitionParams {
// If this is non-empty, it will override the device mapper name (by
// default the partition name will be used).
std::string device_name;
// If non-null, this will use the specified IPartitionOpener rather than
// the default one.
const IPartitionOpener* partition_opener = nullptr;
};
bool CreateLogicalPartition(const CreateLogicalPartitionParams& params, std::string* path);

View file

@ -62,6 +62,11 @@ class IPartitionOpener {
// Return block device information about the given named physical partition.
// The name can be an absolute path if the full path is already known.
virtual bool GetInfo(const std::string& partition_name, BlockDeviceInfo* info) const = 0;
// Return a path that can be used to pass the block device to device-mapper.
// This must either result in an absolute path, or a major:minor device
// sequence.
virtual std::string GetDeviceString(const std::string& partition_name) const = 0;
};
// Helper class to implement IPartitionOpener. If |partition_name| is not an
@ -71,6 +76,7 @@ class PartitionOpener : public IPartitionOpener {
virtual android::base::unique_fd Open(const std::string& partition_name,
int flags) const override;
virtual bool GetInfo(const std::string& partition_name, BlockDeviceInfo* info) const override;
virtual std::string GetDeviceString(const std::string& partition_name) const override;
};
} // namespace fs_mgr

View file

@ -100,5 +100,9 @@ bool PartitionOpener::GetInfo(const std::string& partition_name, BlockDeviceInfo
return GetBlockDeviceInfo(path, info);
}
std::string PartitionOpener::GetDeviceString(const std::string& partition_name) const {
return GetPartitionAbsolutePath(partition_name);
}
} // namespace fs_mgr
} // namespace android