Merge "Allow specifying vbmeta/parts via fstab"
am: 41216e591b
Change-Id: I7459b96ff84e9cbff0ef76a2d10882aea4532c38
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index f00983a..e761e56 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -53,6 +53,7 @@
int file_names_mode = 0;
off64_t erase_blk_size = 0;
off64_t logical_blk_size = 0;
+ std::string vbmeta_partition;
};
struct flag_list {
@@ -97,6 +98,7 @@
{"verifyatboot", MF_VERIFYATBOOT},
{"verify", MF_VERIFY},
{"avb", MF_AVB},
+ {"avb=", MF_AVB},
{"noemulatedsd", MF_NOEMULATEDSD},
{"notrim", MF_NOTRIM},
{"formattable", MF_FORMATTABLE},
@@ -314,6 +316,8 @@
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);
@@ -583,6 +587,7 @@
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;
}
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
index 26a1e5c..d9a5e0a 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -118,6 +118,7 @@
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.
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index f5b291e..c96c381 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -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;
@@ -56,7 +57,7 @@
// ------------------
class FirstStageMount {
public:
- FirstStageMount();
+ FirstStageMount(Fstab fstab);
virtual ~FirstStageMount() = default;
// The factory method to create either FirstStageMountVBootV1 or FirstStageMountVBootV2
@@ -94,7 +95,7 @@
class FirstStageMountVBootV1 : public FirstStageMount {
public:
- FirstStageMountVBootV1() = default;
+ FirstStageMountVBootV1(Fstab fstab) : FirstStageMount(std::move(fstab)) {}
~FirstStageMountVBootV1() override = default;
protected:
@@ -106,7 +107,7 @@
public:
friend void SetInitAvbVersionInRecovery();
- FirstStageMountVBootV2();
+ FirstStageMountVBootV2(Fstab fstab);
~FirstStageMountVBootV2() override = default;
protected:
@@ -114,13 +115,17 @@
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");
}
@@ -128,21 +133,26 @@
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(),
- [](const auto& entry) {
- return !entry.fs_mgr_flags.first_stage_mount;
- }),
- 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());
} 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>{},
@@ -152,10 +162,11 @@
}
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));
}
}
@@ -492,22 +503,27 @@
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.";
}
}
@@ -529,18 +545,15 @@
}
}
- // 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;
@@ -613,7 +626,9 @@
return;
}
- if (!IsDtVbmetaCompatible()) {
+ auto fstab = ReadFirstStageFstab();
+
+ if (!IsDtVbmetaCompatible(fstab)) {
LOG(INFO) << "Skipped setting INIT_AVB_VERSION (not vbmeta compatible)";
return;
}
@@ -623,7 +638,7 @@
// 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;