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

Commit 41216e59 authored by Tom Cherry's avatar Tom Cherry Committed by Gerrit Code Review
Browse files

Merge "Allow specifying vbmeta/parts via fstab"

parents 8f3ed624 de545a4b
Loading
Loading
Loading
Loading
+5 −0
Original line number Original line Diff line number Diff line
@@ -53,6 +53,7 @@ struct fs_mgr_flag_values {
    int file_names_mode = 0;
    int file_names_mode = 0;
    off64_t erase_blk_size = 0;
    off64_t erase_blk_size = 0;
    off64_t logical_blk_size = 0;
    off64_t logical_blk_size = 0;
    std::string vbmeta_partition;
};
};


struct flag_list {
struct flag_list {
@@ -97,6 +98,7 @@ static struct flag_list fs_mgr_flags[] = {
        {"verifyatboot", MF_VERIFYATBOOT},
        {"verifyatboot", MF_VERIFYATBOOT},
        {"verify", MF_VERIFY},
        {"verify", MF_VERIFY},
        {"avb", MF_AVB},
        {"avb", MF_AVB},
        {"avb=", MF_AVB},
        {"noemulatedsd", MF_NOEMULATEDSD},
        {"noemulatedsd", MF_NOEMULATEDSD},
        {"notrim", MF_NOTRIM},
        {"notrim", MF_NOTRIM},
        {"formattable", MF_FORMATTABLE},
        {"formattable", MF_FORMATTABLE},
@@ -314,6 +316,8 @@ static int parse_flags(char *flags, struct flag_list *fl,
                    flag_vals->swap_prio = strtoll(arg, NULL, 0);
                    flag_vals->swap_prio = strtoll(arg, NULL, 0);
                } else if (flag == MF_MAX_COMP_STREAMS) {
                } else if (flag == MF_MAX_COMP_STREAMS) {
                    flag_vals->max_comp_streams = strtoll(arg, NULL, 0);
                    flag_vals->max_comp_streams = strtoll(arg, NULL, 0);
                } else if (flag == MF_AVB) {
                    flag_vals->vbmeta_partition = arg;
                } else if (flag == MF_ZRAMSIZE) {
                } else if (flag == MF_ZRAMSIZE) {
                    auto is_percent = !!strrchr(arg, '%');
                    auto is_percent = !!strrchr(arg, '%');
                    auto val = strtoll(arg, NULL, 0);
                    auto val = strtoll(arg, NULL, 0);
@@ -583,6 +587,7 @@ static bool fs_mgr_read_fstab_file(FILE* fstab_file, bool proc_mounts, Fstab* fs
        entry.erase_blk_size = flag_vals.erase_blk_size;
        entry.erase_blk_size = flag_vals.erase_blk_size;
        entry.logical_blk_size = flag_vals.logical_blk_size;
        entry.logical_blk_size = flag_vals.logical_blk_size;
        entry.sysfs_path = std::move(flag_vals.sysfs_path);
        entry.sysfs_path = std::move(flag_vals.sysfs_path);
        entry.vbmeta_partition = std::move(flag_vals.vbmeta_partition);
        if (entry.fs_mgr_flags.logical) {
        if (entry.fs_mgr_flags.logical) {
            entry.logical_partition_name = entry.blk_device;
            entry.logical_partition_name = entry.blk_device;
        }
        }
+1 −0
Original line number Original line Diff line number Diff line
@@ -118,6 +118,7 @@ struct FstabEntry {
    off64_t erase_blk_size = 0;
    off64_t erase_blk_size = 0;
    off64_t logical_blk_size = 0;
    off64_t logical_blk_size = 0;
    std::string sysfs_path;
    std::string sysfs_path;
    std::string vbmeta_partition;


    // TODO: Remove this union once fstab_rec is deprecated. It only serves as a
    // TODO: Remove this union once fstab_rec is deprecated. It only serves as a
    // convenient way to convert between fstab_rec::fs_mgr_flags and these bools.
    // convenient way to convert between fstab_rec::fs_mgr_flags and these bools.
+59 −44
Original line number Original line Diff line number Diff line
@@ -42,6 +42,7 @@
#include "uevent_listener.h"
#include "uevent_listener.h"
#include "util.h"
#include "util.h"


using android::base::Split;
using android::base::Timer;
using android::base::Timer;
using android::fs_mgr::AvbHandle;
using android::fs_mgr::AvbHandle;
using android::fs_mgr::AvbHashtreeResult;
using android::fs_mgr::AvbHashtreeResult;
@@ -56,7 +57,7 @@ namespace init {
// ------------------
// ------------------
class FirstStageMount {
class FirstStageMount {
  public:
  public:
    FirstStageMount();
    FirstStageMount(Fstab fstab);
    virtual ~FirstStageMount() = default;
    virtual ~FirstStageMount() = default;


    // The factory method to create either FirstStageMountVBootV1 or FirstStageMountVBootV2
    // The factory method to create either FirstStageMountVBootV1 or FirstStageMountVBootV2
@@ -94,7 +95,7 @@ class FirstStageMount {


class FirstStageMountVBootV1 : public FirstStageMount {
class FirstStageMountVBootV1 : public FirstStageMount {
  public:
  public:
    FirstStageMountVBootV1() = default;
    FirstStageMountVBootV1(Fstab fstab) : FirstStageMount(std::move(fstab)) {}
    ~FirstStageMountVBootV1() override = default;
    ~FirstStageMountVBootV1() override = default;


  protected:
  protected:
@@ -106,7 +107,7 @@ class FirstStageMountVBootV2 : public FirstStageMount {
  public:
  public:
    friend void SetInitAvbVersionInRecovery();
    friend void SetInitAvbVersionInRecovery();


    FirstStageMountVBootV2();
    FirstStageMountVBootV2(Fstab fstab);
    ~FirstStageMountVBootV2() override = default;
    ~FirstStageMountVBootV2() override = default;


  protected:
  protected:
@@ -114,13 +115,17 @@ class FirstStageMountVBootV2 : public FirstStageMount {
    bool SetUpDmVerity(FstabEntry* fstab_entry) override;
    bool SetUpDmVerity(FstabEntry* fstab_entry) override;
    bool InitAvbHandle();
    bool InitAvbHandle();


    std::string device_tree_vbmeta_parts_;
    std::vector<std::string> vbmeta_partitions_;
    AvbUniquePtr avb_handle_;
    AvbUniquePtr avb_handle_;
};
};


// Static Functions
// Static Functions
// ----------------
// ----------------
static inline bool IsDtVbmetaCompatible() {
static inline bool IsDtVbmetaCompatible(const Fstab& fstab) {
    if (std::any_of(fstab.begin(), fstab.end(),
                    [](const auto& entry) { return entry.fs_mgr_flags.avb; })) {
        return true;
    }
    return is_android_dt_value_expected("vbmeta/compatible", "android,vbmeta");
    return is_android_dt_value_expected("vbmeta/compatible", "android,vbmeta");
}
}


@@ -128,21 +133,26 @@ static bool IsRecoveryMode() {
    return access("/system/bin/recovery", F_OK) == 0;
    return access("/system/bin/recovery", F_OK) == 0;
}
}


// Class Definitions
static Fstab ReadFirstStageFstab() {
// -----------------
    Fstab fstab;
FirstStageMount::FirstStageMount() : need_dm_verity_(false), uevent_listener_(16 * 1024 * 1024) {
    if (!ReadFstabFromDt(&fstab)) {
    if (!ReadFstabFromDt(&fstab_)) {
        if (ReadDefaultFstab(&fstab)) {
        if (ReadDefaultFstab(&fstab_)) {
            fstab.erase(std::remove_if(fstab.begin(), fstab.end(),
            fstab_.erase(std::remove_if(fstab_.begin(), fstab_.end(),
                                       [](const auto& entry) {
                                       [](const auto& entry) {
                                           return !entry.fs_mgr_flags.first_stage_mount;
                                           return !entry.fs_mgr_flags.first_stage_mount;
                                       }),
                                       }),
                         fstab_.end());
                        fstab.end());
        } else {
        } else {
            LOG(INFO) << "Failed to fstab for first stage mount";
            LOG(INFO) << "Failed to fstab for first stage mount";
        }
        }
    }
    }
    return fstab;
}


// Class Definitions
// -----------------
FirstStageMount::FirstStageMount(Fstab fstab)
    : need_dm_verity_(false), fstab_(std::move(fstab)), uevent_listener_(16 * 1024 * 1024) {
    auto boot_devices = fs_mgr_get_boot_devices();
    auto boot_devices = fs_mgr_get_boot_devices();
    device_handler_ = std::make_unique<DeviceHandler>(
    device_handler_ = std::make_unique<DeviceHandler>(
            std::vector<Permissions>{}, std::vector<SysfsPermissions>{}, std::vector<Subsystem>{},
            std::vector<Permissions>{}, std::vector<SysfsPermissions>{}, std::vector<Subsystem>{},
@@ -152,10 +162,11 @@ FirstStageMount::FirstStageMount() : need_dm_verity_(false), uevent_listener_(16
}
}


std::unique_ptr<FirstStageMount> FirstStageMount::Create() {
std::unique_ptr<FirstStageMount> FirstStageMount::Create() {
    if (IsDtVbmetaCompatible()) {
    auto fstab = ReadFirstStageFstab();
        return std::make_unique<FirstStageMountVBootV2>();
    if (IsDtVbmetaCompatible(fstab)) {
        return std::make_unique<FirstStageMountVBootV2>(std::move(fstab));
    } else {
    } else {
        return std::make_unique<FirstStageMountVBootV1>();
        return std::make_unique<FirstStageMountVBootV1>(std::move(fstab));
    }
    }
}
}


@@ -492,22 +503,27 @@ bool FirstStageMountVBootV1::SetUpDmVerity(FstabEntry* fstab_entry) {
    return true;  // Returns true to mount the partition.
    return true;  // Returns true to mount the partition.
}
}


// FirstStageMountVBootV2 constructor.
// First retrieve any vbmeta partitions from device tree (legacy) then read through the fstab
// Gets the vbmeta partitions from device tree.
// for any further vbmeta partitions.
// /{
FirstStageMountVBootV2::FirstStageMountVBootV2(Fstab fstab)
//     firmware {
    : FirstStageMount(std::move(fstab)), avb_handle_(nullptr) {
//         android {
    std::string device_tree_vbmeta_parts;
//             vbmeta {
    read_android_dt_file("vbmeta/parts", &device_tree_vbmeta_parts);
//                 compatible = "android,vbmeta";

//                 parts = "vbmeta,boot,system,vendor"
    for (auto&& partition : Split(device_tree_vbmeta_parts, ",")) {
//             };
        if (!partition.empty()) {
//         };
            vbmeta_partitions_.emplace_back(std::move(partition));
//     };
        }
//  }
    }
FirstStageMountVBootV2::FirstStageMountVBootV2() : avb_handle_(nullptr) {

    if (!read_android_dt_file("vbmeta/parts", &device_tree_vbmeta_parts_)) {
    for (const auto& entry : fstab_) {
        PLOG(ERROR) << "Failed to read vbmeta/parts from device tree";
        if (!entry.vbmeta_partition.empty()) {
        return;
            vbmeta_partitions_.emplace_back(entry.vbmeta_partition);
        }
    }

    if (vbmeta_partitions_.empty()) {
        LOG(ERROR) << "Failed to read vbmeta partitions.";
    }
    }
}
}


@@ -529,18 +545,15 @@ bool FirstStageMountVBootV2::GetDmVerityDevices() {
        }
        }
    }
    }


    // libavb verifies AVB metadata on all verified partitions at once.
    // Any partitions needed for verifying the partitions used in first stage mount, e.g. vbmeta
    // e.g., The device_tree_vbmeta_parts_ will be "vbmeta,boot,system,vendor"
    // must be provided as vbmeta_partitions.
    // for libavb to verify metadata, even if there is only /vendor in the
    // above mount_fstab_recs_.
    if (need_dm_verity_) {
    if (need_dm_verity_) {
        if (device_tree_vbmeta_parts_.empty()) {
        if (vbmeta_partitions_.empty()) {
            LOG(ERROR) << "Missing vbmeta parts in device tree";
            LOG(ERROR) << "Missing vbmeta partitions";
            return false;
            return false;
        }
        }
        std::vector<std::string> partitions = android::base::Split(device_tree_vbmeta_parts_, ",");
        std::string ab_suffix = fs_mgr_get_slot_suffix();
        std::string ab_suffix = fs_mgr_get_slot_suffix();
        for (const auto& partition : partitions) {
        for (const auto& partition : vbmeta_partitions_) {
            std::string partition_name = partition + ab_suffix;
            std::string partition_name = partition + ab_suffix;
            if (logical_partitions.count(partition_name)) {
            if (logical_partitions.count(partition_name)) {
                continue;
                continue;
@@ -613,7 +626,9 @@ void SetInitAvbVersionInRecovery() {
        return;
        return;
    }
    }


    if (!IsDtVbmetaCompatible()) {
    auto fstab = ReadFirstStageFstab();

    if (!IsDtVbmetaCompatible(fstab)) {
        LOG(INFO) << "Skipped setting INIT_AVB_VERSION (not vbmeta compatible)";
        LOG(INFO) << "Skipped setting INIT_AVB_VERSION (not vbmeta compatible)";
        return;
        return;
    }
    }
@@ -623,7 +638,7 @@ void SetInitAvbVersionInRecovery() {
    // We only set INIT_AVB_VERSION when the AVB verification succeeds, i.e., the
    // We only set INIT_AVB_VERSION when the AVB verification succeeds, i.e., the
    // Open() function returns a valid handle.
    // Open() function returns a valid handle.
    // We don't need to mount partitions here in recovery mode.
    // We don't need to mount partitions here in recovery mode.
    FirstStageMountVBootV2 avb_first_mount;
    FirstStageMountVBootV2 avb_first_mount(std::move(fstab));
    if (!avb_first_mount.InitDevices()) {
    if (!avb_first_mount.InitDevices()) {
        LOG(ERROR) << "Failed to init devices for INIT_AVB_VERSION";
        LOG(ERROR) << "Failed to init devices for INIT_AVB_VERSION";
        return;
        return;