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

Commit dbc4a788 authored by Kelvin Zhang's avatar Kelvin Zhang
Browse files

Report partition sizes to avb

This might allow avb to save some memory by only allocate as much memory
needed to hold the partition data, instead of allocating for maximum
possible partition size(64K).

Bug: 266757931

Change-Id: I82a4b1ba3544910072050e45a7cb91e0dcbc4d05
parent d34157e2
Loading
Loading
Loading
Loading
+39 −16
Original line number Original line Diff line number Diff line
@@ -26,8 +26,10 @@


#include <errno.h>
#include <errno.h>
#include <fcntl.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/stat.h>


#include <string>
#include <string>
@@ -96,13 +98,11 @@ static AvbIOResult no_op_get_unique_guid_for_partition(AvbOps* ops ATTRIBUTE_UNU
    return AVB_IO_RESULT_OK;
    return AVB_IO_RESULT_OK;
}
}


static AvbIOResult no_op_get_size_of_partition(AvbOps* ops ATTRIBUTE_UNUSED,
static AvbIOResult get_size_of_partition(AvbOps* ops ATTRIBUTE_UNUSED,
                                         const char* partition ATTRIBUTE_UNUSED,
                                         const char* partition ATTRIBUTE_UNUSED,
                                         uint64_t* out_size_num_byte) {
                                         uint64_t* out_size_num_byte) {
    // The function is for bootloader to load entire content of AVB HASH partitions.
    return FsManagerAvbOps::GetInstanceFromAvbOps(ops)->GetSizeOfPartition(partition,
    // In user-space, returns 0 as we only need to set up AVB HASHTHREE partitions.
                                                                           out_size_num_byte);
    *out_size_num_byte = 0;
    return AVB_IO_RESULT_OK;
}
}


// Converts a partition name (with ab_suffix) to the corresponding mount point.
// Converts a partition name (with ab_suffix) to the corresponding mount point.
@@ -131,7 +131,7 @@ FsManagerAvbOps::FsManagerAvbOps() {
    avb_ops_.validate_vbmeta_public_key = no_op_validate_vbmeta_public_key;
    avb_ops_.validate_vbmeta_public_key = no_op_validate_vbmeta_public_key;
    avb_ops_.read_is_device_unlocked = no_op_read_is_device_unlocked;
    avb_ops_.read_is_device_unlocked = no_op_read_is_device_unlocked;
    avb_ops_.get_unique_guid_for_partition = no_op_get_unique_guid_for_partition;
    avb_ops_.get_unique_guid_for_partition = no_op_get_unique_guid_for_partition;
    avb_ops_.get_size_of_partition = no_op_get_size_of_partition;
    avb_ops_.get_size_of_partition = get_size_of_partition;


    // Sets user_data for GetInstanceFromAvbOps() to convert it back to FsManagerAvbOps.
    // Sets user_data for GetInstanceFromAvbOps() to convert it back to FsManagerAvbOps.
    avb_ops_.user_data = this;
    avb_ops_.user_data = this;
@@ -167,13 +167,8 @@ std::string FsManagerAvbOps::GetLogicalPath(const std::string& partition_name) {


    return "";
    return "";
}
}

std::string FsManagerAvbOps::GetPartitionPath(const char* partition) {
AvbIOResult FsManagerAvbOps::ReadFromPartition(const char* partition, int64_t offset,
                                               size_t num_bytes, void* buffer,
                                               size_t* out_num_read) {
    std::string path = "/dev/block/by-name/"s + partition;
    std::string path = "/dev/block/by-name/"s + partition;

    // Ensures the device path (a symlink created by init) is ready to access.
    if (!WaitForFile(path, 1s)) {
    if (!WaitForFile(path, 1s)) {
        LERROR << "Device path not found: " << path;
        LERROR << "Device path not found: " << path;
        // Falls back to logical path if the physical path is not found.
        // Falls back to logical path if the physical path is not found.
@@ -182,8 +177,36 @@ AvbIOResult FsManagerAvbOps::ReadFromPartition(const char* partition, int64_t of
        // the bootloader failed to read a physical partition, it will failed to boot
        // the bootloader failed to read a physical partition, it will failed to boot
        // the HLOS and we won't reach the code here.
        // the HLOS and we won't reach the code here.
        path = GetLogicalPath(partition);
        path = GetLogicalPath(partition);
        if (path.empty() || !WaitForFile(path, 1s)) return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
        if (path.empty() || !WaitForFile(path, 1s)) return "";
        LINFO << "Fallback to use logical device path: " << path;
    }
    return path;
}

AvbIOResult FsManagerAvbOps::GetSizeOfPartition(const char* partition,
                                                uint64_t* out_size_num_byte) {
    const auto path = GetPartitionPath(partition);
    if (path.empty()) {
        return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
    }
    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
    if (fd < 0) {
        PERROR << "Failed to open " << path;
        return AVB_IO_RESULT_ERROR_IO;
    }
    int err = ioctl(fd, BLKGETSIZE64, out_size_num_byte);
    if (err) {
        out_size_num_byte = 0;
        return AVB_IO_RESULT_ERROR_IO;
    }
    return AVB_IO_RESULT_OK;
}

AvbIOResult FsManagerAvbOps::ReadFromPartition(const char* partition, int64_t offset,
                                               size_t num_bytes, void* buffer,
                                               size_t* out_num_read) {
    std::string path = GetPartitionPath(partition);
    if (path.empty()) {
        return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
    }
    }


    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
+2 −0
Original line number Original line Diff line number Diff line
@@ -56,12 +56,14 @@ class FsManagerAvbOps {


    AvbIOResult ReadFromPartition(const char* partition, int64_t offset, size_t num_bytes,
    AvbIOResult ReadFromPartition(const char* partition, int64_t offset, size_t num_bytes,
                                  void* buffer, size_t* out_num_read);
                                  void* buffer, size_t* out_num_read);
    AvbIOResult GetSizeOfPartition(const char* partition, uint64_t* out_size_num_byte);


    AvbSlotVerifyResult AvbSlotVerify(const std::string& ab_suffix, AvbSlotVerifyFlags flags,
    AvbSlotVerifyResult AvbSlotVerify(const std::string& ab_suffix, AvbSlotVerifyFlags flags,
                                      std::vector<VBMetaData>* out_vbmeta_images);
                                      std::vector<VBMetaData>* out_vbmeta_images);


  private:
  private:
    std::string GetLogicalPath(const std::string& partition_name);
    std::string GetLogicalPath(const std::string& partition_name);
    std::string GetPartitionPath(const char* partition_name);
    AvbOps avb_ops_;
    AvbOps avb_ops_;
    Fstab fstab_;
    Fstab fstab_;
};
};