Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 18a9324e authored by Tom Cherry's avatar Tom Cherry Committed by Gerrit Code Review
Browse files

Merge "Allow mapping of raw block devices to partition names"

parents 2a1603d0 96e5f9b5
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -86,9 +86,15 @@ ListenerAction BlockDevInitializer::HandleUevent(const Uevent& uevent,
    }

    auto iter = devices->find(name);
    if (iter == devices->end()) {
        auto partition_name = DeviceHandler::GetPartitionNameForDevice(uevent.device_name);
        if (!partition_name.empty()) {
            iter = devices->find(partition_name);
        }
        if (iter == devices->end()) {
            return ListenerAction::kContinue;
        }
    }

    LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << name;

+35 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ using android::base::Dirname;
using android::base::ReadFileToString;
using android::base::Readlink;
using android::base::Realpath;
using android::base::Split;
using android::base::StartsWith;
using android::base::StringPrintf;
using android::base::Trim;
@@ -187,6 +188,36 @@ void SysfsPermissions::SetPermissions(const std::string& path) const {
    }
}

std::string DeviceHandler::GetPartitionNameForDevice(const std::string& query_device) {
    static const auto partition_map = [] {
        std::vector<std::pair<std::string, std::string>> partition_map;
        auto parser = [&partition_map](const std::string& key, const std::string& value) {
            if (key != "androidboot.partition_map") {
                return;
            }
            for (const auto& map : Split(value, ";")) {
                auto map_pieces = Split(map, ",");
                if (map_pieces.size() != 2) {
                    LOG(ERROR) << "Expected a comma separated device,partition mapping, but found '"
                               << map << "'";
                    continue;
                }
                partition_map.emplace_back(map_pieces[0], map_pieces[1]);
            }
        };
        ImportKernelCmdline(parser);
        ImportBootconfig(parser);
        return partition_map;
    }();

    for (const auto& [device, partition] : partition_map) {
        if (query_device == device) {
            return partition;
        }
    }
    return {};
}

// Given a path that may start with a platform device, find the parent platform device by finding a
// parent directory with a 'subsystem' symlink that points to the platform bus.
// If it doesn't start with a platform device, return false
@@ -389,6 +420,10 @@ std::vector<std::string> DeviceHandler::GetBlockDeviceSymlinks(const Uevent& uev
        // If we don't have a partition name but we are a partition on a boot device, create a
        // symlink of /dev/block/by-name/<device_name> for symmetry.
        links.emplace_back("/dev/block/by-name/" + uevent.device_name);
        auto partition_name = GetPartitionNameForDevice(uevent.device_name);
        if (!partition_name.empty()) {
            links.emplace_back("/dev/block/by-name/" + partition_name);
        }
    }

    auto last_slash = uevent.path.rfind('/');
+6 −0
Original line number Diff line number Diff line
@@ -122,6 +122,12 @@ class DeviceHandler : public UeventHandler {

    std::vector<std::string> GetBlockDeviceSymlinks(const Uevent& uevent) const;

    // `androidboot.partition_map` allows associating a partition name for a raw block device
    // through a comma separated and semicolon deliminated list. For example,
    // `androidboot.partition_map=vdb,metadata;vdc,userdata` maps `vdb` to `metadata` and `vdc` to
    // `userdata`.
    static std::string GetPartitionNameForDevice(const std::string& device);

  private:
    bool FindPlatformDevice(std::string path, std::string* platform_device_path) const;
    std::tuple<mode_t, uid_t, gid_t> GetDevicePermissions(