Loading fs_mgr/fs_mgr_fstab.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ struct fs_mgr_flag_values { int file_names_mode = 0; off64_t erase_blk_size = 0; off64_t logical_blk_size = 0; std::string vbmeta_partition; }; struct flag_list { Loading Loading @@ -97,6 +98,7 @@ static struct flag_list fs_mgr_flags[] = { {"verifyatboot", MF_VERIFYATBOOT}, {"verify", MF_VERIFY}, {"avb", MF_AVB}, {"avb=", MF_AVB}, {"noemulatedsd", MF_NOEMULATEDSD}, {"notrim", MF_NOTRIM}, {"formattable", MF_FORMATTABLE}, Loading Loading @@ -314,6 +316,8 @@ static int parse_flags(char *flags, struct flag_list *fl, flag_vals->swap_prio = strtoll(arg, NULL, 0); } else if (flag == MF_MAX_COMP_STREAMS) { flag_vals->max_comp_streams = strtoll(arg, NULL, 0); } else if (flag == MF_AVB) { flag_vals->vbmeta_partition = arg; } else if (flag == MF_ZRAMSIZE) { auto is_percent = !!strrchr(arg, '%'); auto val = strtoll(arg, NULL, 0); Loading Loading @@ -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.logical_blk_size = flag_vals.logical_blk_size; entry.sysfs_path = std::move(flag_vals.sysfs_path); entry.vbmeta_partition = std::move(flag_vals.vbmeta_partition); if (entry.fs_mgr_flags.logical) { entry.logical_partition_name = entry.blk_device; } Loading fs_mgr/include_fstab/fstab/fstab.h +1 −0 Original line number Diff line number Diff line Loading @@ -118,6 +118,7 @@ struct FstabEntry { off64_t erase_blk_size = 0; off64_t logical_blk_size = 0; std::string sysfs_path; std::string vbmeta_partition; // 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. Loading init/first_stage_mount.cpp +59 −44 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #include "uevent_listener.h" #include "util.h" using android::base::Split; using android::base::Timer; using android::fs_mgr::AvbHandle; using android::fs_mgr::AvbHashtreeResult; Loading @@ -56,7 +57,7 @@ namespace init { // ------------------ class FirstStageMount { public: FirstStageMount(); FirstStageMount(Fstab fstab); virtual ~FirstStageMount() = default; // The factory method to create either FirstStageMountVBootV1 or FirstStageMountVBootV2 Loading Loading @@ -94,7 +95,7 @@ class FirstStageMount { class FirstStageMountVBootV1 : public FirstStageMount { public: FirstStageMountVBootV1() = default; FirstStageMountVBootV1(Fstab fstab) : FirstStageMount(std::move(fstab)) {} ~FirstStageMountVBootV1() override = default; protected: Loading @@ -106,7 +107,7 @@ class FirstStageMountVBootV2 : public FirstStageMount { public: friend void SetInitAvbVersionInRecovery(); FirstStageMountVBootV2(); FirstStageMountVBootV2(Fstab fstab); ~FirstStageMountVBootV2() override = default; protected: Loading @@ -114,13 +115,17 @@ class FirstStageMountVBootV2 : public FirstStageMount { bool SetUpDmVerity(FstabEntry* fstab_entry) override; bool InitAvbHandle(); std::string device_tree_vbmeta_parts_; std::vector<std::string> vbmeta_partitions_; AvbUniquePtr avb_handle_; }; // 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"); } Loading @@ -128,21 +133,26 @@ static bool IsRecoveryMode() { return access("/system/bin/recovery", F_OK) == 0; } // Class Definitions // ----------------- FirstStageMount::FirstStageMount() : need_dm_verity_(false), uevent_listener_(16 * 1024 * 1024) { if (!ReadFstabFromDt(&fstab_)) { if (ReadDefaultFstab(&fstab_)) { fstab_.erase(std::remove_if(fstab_.begin(), fstab_.end(), static Fstab ReadFirstStageFstab() { Fstab fstab; if (!ReadFstabFromDt(&fstab)) { if (ReadDefaultFstab(&fstab)) { fstab.erase(std::remove_if(fstab.begin(), fstab.end(), [](const auto& entry) { return !entry.fs_mgr_flags.first_stage_mount; }), fstab_.end()); fstab.end()); } else { 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(); device_handler_ = std::make_unique<DeviceHandler>( std::vector<Permissions>{}, std::vector<SysfsPermissions>{}, std::vector<Subsystem>{}, Loading @@ -152,10 +162,11 @@ FirstStageMount::FirstStageMount() : need_dm_verity_(false), uevent_listener_(16 } std::unique_ptr<FirstStageMount> FirstStageMount::Create() { if (IsDtVbmetaCompatible()) { return std::make_unique<FirstStageMountVBootV2>(); auto fstab = ReadFirstStageFstab(); if (IsDtVbmetaCompatible(fstab)) { return std::make_unique<FirstStageMountVBootV2>(std::move(fstab)); } else { return std::make_unique<FirstStageMountVBootV1>(); return std::make_unique<FirstStageMountVBootV1>(std::move(fstab)); } } Loading Loading @@ -492,22 +503,27 @@ bool FirstStageMountVBootV1::SetUpDmVerity(FstabEntry* fstab_entry) { return true; // Returns true to mount the partition. } // FirstStageMountVBootV2 constructor. // Gets the vbmeta partitions from device tree. // /{ // firmware { // android { // vbmeta { // compatible = "android,vbmeta"; // parts = "vbmeta,boot,system,vendor" // }; // }; // }; // } FirstStageMountVBootV2::FirstStageMountVBootV2() : avb_handle_(nullptr) { if (!read_android_dt_file("vbmeta/parts", &device_tree_vbmeta_parts_)) { PLOG(ERROR) << "Failed to read vbmeta/parts from device tree"; return; // First retrieve any vbmeta partitions from device tree (legacy) then read through the fstab // for any further vbmeta partitions. FirstStageMountVBootV2::FirstStageMountVBootV2(Fstab fstab) : FirstStageMount(std::move(fstab)), avb_handle_(nullptr) { std::string device_tree_vbmeta_parts; read_android_dt_file("vbmeta/parts", &device_tree_vbmeta_parts); for (auto&& partition : Split(device_tree_vbmeta_parts, ",")) { if (!partition.empty()) { vbmeta_partitions_.emplace_back(std::move(partition)); } } for (const auto& entry : fstab_) { if (!entry.vbmeta_partition.empty()) { vbmeta_partitions_.emplace_back(entry.vbmeta_partition); } } if (vbmeta_partitions_.empty()) { LOG(ERROR) << "Failed to read vbmeta partitions."; } } Loading @@ -529,18 +545,15 @@ bool FirstStageMountVBootV2::GetDmVerityDevices() { } } // libavb verifies AVB metadata on all verified partitions at once. // e.g., The device_tree_vbmeta_parts_ will be "vbmeta,boot,system,vendor" // for libavb to verify metadata, even if there is only /vendor in the // above mount_fstab_recs_. // Any partitions needed for verifying the partitions used in first stage mount, e.g. vbmeta // must be provided as vbmeta_partitions. if (need_dm_verity_) { if (device_tree_vbmeta_parts_.empty()) { LOG(ERROR) << "Missing vbmeta parts in device tree"; if (vbmeta_partitions_.empty()) { LOG(ERROR) << "Missing vbmeta partitions"; return false; } std::vector<std::string> partitions = android::base::Split(device_tree_vbmeta_parts_, ","); 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; if (logical_partitions.count(partition_name)) { continue; Loading Loading @@ -613,7 +626,9 @@ void SetInitAvbVersionInRecovery() { return; } if (!IsDtVbmetaCompatible()) { auto fstab = ReadFirstStageFstab(); if (!IsDtVbmetaCompatible(fstab)) { LOG(INFO) << "Skipped setting INIT_AVB_VERSION (not vbmeta compatible)"; return; } Loading @@ -623,7 +638,7 @@ void SetInitAvbVersionInRecovery() { // We only set INIT_AVB_VERSION when the AVB verification succeeds, i.e., the // Open() function returns a valid handle. // 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()) { LOG(ERROR) << "Failed to init devices for INIT_AVB_VERSION"; return; Loading Loading
fs_mgr/fs_mgr_fstab.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ struct fs_mgr_flag_values { int file_names_mode = 0; off64_t erase_blk_size = 0; off64_t logical_blk_size = 0; std::string vbmeta_partition; }; struct flag_list { Loading Loading @@ -97,6 +98,7 @@ static struct flag_list fs_mgr_flags[] = { {"verifyatboot", MF_VERIFYATBOOT}, {"verify", MF_VERIFY}, {"avb", MF_AVB}, {"avb=", MF_AVB}, {"noemulatedsd", MF_NOEMULATEDSD}, {"notrim", MF_NOTRIM}, {"formattable", MF_FORMATTABLE}, Loading Loading @@ -314,6 +316,8 @@ static int parse_flags(char *flags, struct flag_list *fl, flag_vals->swap_prio = strtoll(arg, NULL, 0); } else if (flag == MF_MAX_COMP_STREAMS) { flag_vals->max_comp_streams = strtoll(arg, NULL, 0); } else if (flag == MF_AVB) { flag_vals->vbmeta_partition = arg; } else if (flag == MF_ZRAMSIZE) { auto is_percent = !!strrchr(arg, '%'); auto val = strtoll(arg, NULL, 0); Loading Loading @@ -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.logical_blk_size = flag_vals.logical_blk_size; entry.sysfs_path = std::move(flag_vals.sysfs_path); entry.vbmeta_partition = std::move(flag_vals.vbmeta_partition); if (entry.fs_mgr_flags.logical) { entry.logical_partition_name = entry.blk_device; } Loading
fs_mgr/include_fstab/fstab/fstab.h +1 −0 Original line number Diff line number Diff line Loading @@ -118,6 +118,7 @@ struct FstabEntry { off64_t erase_blk_size = 0; off64_t logical_blk_size = 0; std::string sysfs_path; std::string vbmeta_partition; // 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. Loading
init/first_stage_mount.cpp +59 −44 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ #include "uevent_listener.h" #include "util.h" using android::base::Split; using android::base::Timer; using android::fs_mgr::AvbHandle; using android::fs_mgr::AvbHashtreeResult; Loading @@ -56,7 +57,7 @@ namespace init { // ------------------ class FirstStageMount { public: FirstStageMount(); FirstStageMount(Fstab fstab); virtual ~FirstStageMount() = default; // The factory method to create either FirstStageMountVBootV1 or FirstStageMountVBootV2 Loading Loading @@ -94,7 +95,7 @@ class FirstStageMount { class FirstStageMountVBootV1 : public FirstStageMount { public: FirstStageMountVBootV1() = default; FirstStageMountVBootV1(Fstab fstab) : FirstStageMount(std::move(fstab)) {} ~FirstStageMountVBootV1() override = default; protected: Loading @@ -106,7 +107,7 @@ class FirstStageMountVBootV2 : public FirstStageMount { public: friend void SetInitAvbVersionInRecovery(); FirstStageMountVBootV2(); FirstStageMountVBootV2(Fstab fstab); ~FirstStageMountVBootV2() override = default; protected: Loading @@ -114,13 +115,17 @@ class FirstStageMountVBootV2 : public FirstStageMount { bool SetUpDmVerity(FstabEntry* fstab_entry) override; bool InitAvbHandle(); std::string device_tree_vbmeta_parts_; std::vector<std::string> vbmeta_partitions_; AvbUniquePtr avb_handle_; }; // 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"); } Loading @@ -128,21 +133,26 @@ static bool IsRecoveryMode() { return access("/system/bin/recovery", F_OK) == 0; } // Class Definitions // ----------------- FirstStageMount::FirstStageMount() : need_dm_verity_(false), uevent_listener_(16 * 1024 * 1024) { if (!ReadFstabFromDt(&fstab_)) { if (ReadDefaultFstab(&fstab_)) { fstab_.erase(std::remove_if(fstab_.begin(), fstab_.end(), static Fstab ReadFirstStageFstab() { Fstab fstab; if (!ReadFstabFromDt(&fstab)) { if (ReadDefaultFstab(&fstab)) { fstab.erase(std::remove_if(fstab.begin(), fstab.end(), [](const auto& entry) { return !entry.fs_mgr_flags.first_stage_mount; }), fstab_.end()); fstab.end()); } else { 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(); device_handler_ = std::make_unique<DeviceHandler>( std::vector<Permissions>{}, std::vector<SysfsPermissions>{}, std::vector<Subsystem>{}, Loading @@ -152,10 +162,11 @@ FirstStageMount::FirstStageMount() : need_dm_verity_(false), uevent_listener_(16 } std::unique_ptr<FirstStageMount> FirstStageMount::Create() { if (IsDtVbmetaCompatible()) { return std::make_unique<FirstStageMountVBootV2>(); auto fstab = ReadFirstStageFstab(); if (IsDtVbmetaCompatible(fstab)) { return std::make_unique<FirstStageMountVBootV2>(std::move(fstab)); } else { return std::make_unique<FirstStageMountVBootV1>(); return std::make_unique<FirstStageMountVBootV1>(std::move(fstab)); } } Loading Loading @@ -492,22 +503,27 @@ bool FirstStageMountVBootV1::SetUpDmVerity(FstabEntry* fstab_entry) { return true; // Returns true to mount the partition. } // FirstStageMountVBootV2 constructor. // Gets the vbmeta partitions from device tree. // /{ // firmware { // android { // vbmeta { // compatible = "android,vbmeta"; // parts = "vbmeta,boot,system,vendor" // }; // }; // }; // } FirstStageMountVBootV2::FirstStageMountVBootV2() : avb_handle_(nullptr) { if (!read_android_dt_file("vbmeta/parts", &device_tree_vbmeta_parts_)) { PLOG(ERROR) << "Failed to read vbmeta/parts from device tree"; return; // First retrieve any vbmeta partitions from device tree (legacy) then read through the fstab // for any further vbmeta partitions. FirstStageMountVBootV2::FirstStageMountVBootV2(Fstab fstab) : FirstStageMount(std::move(fstab)), avb_handle_(nullptr) { std::string device_tree_vbmeta_parts; read_android_dt_file("vbmeta/parts", &device_tree_vbmeta_parts); for (auto&& partition : Split(device_tree_vbmeta_parts, ",")) { if (!partition.empty()) { vbmeta_partitions_.emplace_back(std::move(partition)); } } for (const auto& entry : fstab_) { if (!entry.vbmeta_partition.empty()) { vbmeta_partitions_.emplace_back(entry.vbmeta_partition); } } if (vbmeta_partitions_.empty()) { LOG(ERROR) << "Failed to read vbmeta partitions."; } } Loading @@ -529,18 +545,15 @@ bool FirstStageMountVBootV2::GetDmVerityDevices() { } } // libavb verifies AVB metadata on all verified partitions at once. // e.g., The device_tree_vbmeta_parts_ will be "vbmeta,boot,system,vendor" // for libavb to verify metadata, even if there is only /vendor in the // above mount_fstab_recs_. // Any partitions needed for verifying the partitions used in first stage mount, e.g. vbmeta // must be provided as vbmeta_partitions. if (need_dm_verity_) { if (device_tree_vbmeta_parts_.empty()) { LOG(ERROR) << "Missing vbmeta parts in device tree"; if (vbmeta_partitions_.empty()) { LOG(ERROR) << "Missing vbmeta partitions"; return false; } std::vector<std::string> partitions = android::base::Split(device_tree_vbmeta_parts_, ","); 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; if (logical_partitions.count(partition_name)) { continue; Loading Loading @@ -613,7 +626,9 @@ void SetInitAvbVersionInRecovery() { return; } if (!IsDtVbmetaCompatible()) { auto fstab = ReadFirstStageFstab(); if (!IsDtVbmetaCompatible(fstab)) { LOG(INFO) << "Skipped setting INIT_AVB_VERSION (not vbmeta compatible)"; return; } Loading @@ -623,7 +638,7 @@ void SetInitAvbVersionInRecovery() { // We only set INIT_AVB_VERSION when the AVB verification succeeds, i.e., the // Open() function returns a valid handle. // 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()) { LOG(ERROR) << "Failed to init devices for INIT_AVB_VERSION"; return; Loading