Merge "Allow specifying vbmeta/parts via fstab"
This commit is contained in:
commit
41216e591b
3 changed files with 65 additions and 44 deletions
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue