Merge "fs_mgr: Allow using major:minor device strings in CreateLogicalPartition."
This commit is contained in:
commit
63fe0e9a36
4 changed files with 43 additions and 17 deletions
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue