Merge changes from topic 'avb-early-mount' am: d7381375bb
am: 04989a7a4b
Change-Id: I45d89c806076842ee75a772b1a8bbba2157eb46c
This commit is contained in:
commit
0b2d83a64b
7 changed files with 289 additions and 187 deletions
|
@ -31,7 +31,10 @@
|
|||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <android-base/file.h>
|
||||
#include <android-base/properties.h>
|
||||
#include <android-base/stringprintf.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <cutils/android_reboot.h>
|
||||
|
@ -50,6 +53,7 @@
|
|||
#include "fs_mgr.h"
|
||||
#include "fs_mgr_avb.h"
|
||||
#include "fs_mgr_priv.h"
|
||||
#include "fs_mgr_priv_dm_ioctl.h"
|
||||
|
||||
#define KEY_LOC_PROP "ro.crypto.keyfile.userdata"
|
||||
#define KEY_IN_FOOTER "footer"
|
||||
|
@ -1258,3 +1262,97 @@ int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, char *real_blk_dev
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool fs_mgr_load_verity_state(int* mode) {
|
||||
/* return the default mode, unless any of the verified partitions are in
|
||||
* logging mode, in which case return that */
|
||||
*mode = VERITY_MODE_DEFAULT;
|
||||
|
||||
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
|
||||
fs_mgr_free_fstab);
|
||||
if (!fstab) {
|
||||
LERROR << "Failed to read default fstab";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < fstab->num_entries; i++) {
|
||||
if (fs_mgr_is_avb(&fstab->recs[i])) {
|
||||
*mode = VERITY_MODE_RESTART; // avb only supports restart mode.
|
||||
break;
|
||||
} else if (!fs_mgr_is_verified(&fstab->recs[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int current;
|
||||
if (load_verity_state(&fstab->recs[i], ¤t) < 0) {
|
||||
continue;
|
||||
}
|
||||
if (current != VERITY_MODE_DEFAULT) {
|
||||
*mode = current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback) {
|
||||
if (!callback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int mode;
|
||||
if (!fs_mgr_load_verity_state(&mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
android::base::unique_fd fd(TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC)));
|
||||
if (fd == -1) {
|
||||
PERROR << "Error opening device mapper";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
|
||||
fs_mgr_free_fstab);
|
||||
if (!fstab) {
|
||||
LERROR << "Failed to read default fstab";
|
||||
return false;
|
||||
}
|
||||
|
||||
alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
|
||||
struct dm_ioctl* io = (struct dm_ioctl*)buffer;
|
||||
bool system_root = android::base::GetProperty("ro.build.system_root_image", "") == "true";
|
||||
|
||||
for (int i = 0; i < fstab->num_entries; i++) {
|
||||
if (!fs_mgr_is_verified(&fstab->recs[i]) && !fs_mgr_is_avb(&fstab->recs[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string mount_point;
|
||||
if (system_root && !strcmp(fstab->recs[i].mount_point, "/")) {
|
||||
mount_point = "system";
|
||||
} else {
|
||||
mount_point = basename(fstab->recs[i].mount_point);
|
||||
}
|
||||
|
||||
fs_mgr_verity_ioctl_init(io, mount_point, 0);
|
||||
|
||||
const char* status;
|
||||
if (ioctl(fd, DM_TABLE_STATUS, io)) {
|
||||
if (fstab->recs[i].fs_mgr_flags & MF_VERIFYATBOOT) {
|
||||
status = "V";
|
||||
} else {
|
||||
PERROR << "Failed to query DM_TABLE_STATUS for " << mount_point.c_str();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
status = &buffer[io->data_start + sizeof(struct dm_target_spec)];
|
||||
|
||||
if (*status == 'C' || *status == 'V') {
|
||||
callback(&fstab->recs[i], mount_point.c_str(), mode, *status);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -115,5 +115,6 @@ int fs_mgr_test_access(const char *device);
|
|||
bool fs_mgr_update_for_slotselect(struct fstab *fstab);
|
||||
bool is_dt_compatible();
|
||||
bool is_device_secure();
|
||||
int load_verity_state(struct fstab_rec* fstab, int* mode);
|
||||
|
||||
#endif /* __CORE_FS_MGR_PRIV_H */
|
||||
|
|
|
@ -653,8 +653,7 @@ static int get_verity_state_offset(struct fstab_rec *fstab, off64_t *offset)
|
|||
offset);
|
||||
}
|
||||
|
||||
static int load_verity_state(struct fstab_rec *fstab, int *mode)
|
||||
{
|
||||
int load_verity_state(struct fstab_rec* fstab, int* mode) {
|
||||
int match = 0;
|
||||
off64_t offset = 0;
|
||||
|
||||
|
@ -690,129 +689,6 @@ static int load_verity_state(struct fstab_rec *fstab, int *mode)
|
|||
return read_verity_state(fstab->verity_loc, offset, mode);
|
||||
}
|
||||
|
||||
int fs_mgr_load_verity_state(int *mode)
|
||||
{
|
||||
int rc = -1;
|
||||
int i;
|
||||
int current;
|
||||
struct fstab *fstab = NULL;
|
||||
|
||||
/* return the default mode, unless any of the verified partitions are in
|
||||
* logging mode, in which case return that */
|
||||
*mode = VERITY_MODE_DEFAULT;
|
||||
|
||||
fstab = fs_mgr_read_fstab_default();
|
||||
if (!fstab) {
|
||||
LERROR << "Failed to read default fstab";
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < fstab->num_entries; i++) {
|
||||
if (!fs_mgr_is_verified(&fstab->recs[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = load_verity_state(&fstab->recs[i], ¤t);
|
||||
if (rc < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (current != VERITY_MODE_DEFAULT) {
|
||||
*mode = current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
if (fstab) {
|
||||
fs_mgr_free_fstab(fstab);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback)
|
||||
{
|
||||
alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
|
||||
bool system_root = false;
|
||||
std::string mount_point;
|
||||
char propbuf[PROPERTY_VALUE_MAX];
|
||||
const char *status;
|
||||
int fd = -1;
|
||||
int i;
|
||||
int mode;
|
||||
int rc = -1;
|
||||
struct dm_ioctl *io = (struct dm_ioctl *) buffer;
|
||||
struct fstab *fstab = NULL;
|
||||
|
||||
if (!callback) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fs_mgr_load_verity_state(&mode) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC));
|
||||
if (fd == -1) {
|
||||
PERROR << "Error opening device mapper";
|
||||
goto out;
|
||||
}
|
||||
|
||||
property_get("ro.build.system_root_image", propbuf, "");
|
||||
system_root = !strcmp(propbuf, "true");
|
||||
fstab = fs_mgr_read_fstab_default();
|
||||
if (!fstab) {
|
||||
LERROR << "Failed to read default fstab";
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < fstab->num_entries; i++) {
|
||||
if (!fs_mgr_is_verified(&fstab->recs[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (system_root && !strcmp(fstab->recs[i].mount_point, "/")) {
|
||||
mount_point = "system";
|
||||
} else {
|
||||
mount_point = basename(fstab->recs[i].mount_point);
|
||||
}
|
||||
|
||||
fs_mgr_verity_ioctl_init(io, mount_point, 0);
|
||||
|
||||
if (ioctl(fd, DM_TABLE_STATUS, io)) {
|
||||
if (fstab->recs[i].fs_mgr_flags & MF_VERIFYATBOOT) {
|
||||
status = "V";
|
||||
} else {
|
||||
PERROR << "Failed to query DM_TABLE_STATUS for "
|
||||
<< mount_point.c_str();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
status = &buffer[io->data_start + sizeof(struct dm_target_spec)];
|
||||
|
||||
if (*status == 'C' || *status == 'V') {
|
||||
callback(&fstab->recs[i], mount_point.c_str(), mode, *status);
|
||||
}
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
out:
|
||||
if (fstab) {
|
||||
fs_mgr_free_fstab(fstab);
|
||||
}
|
||||
|
||||
if (fd) {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void update_verity_table_blk_device(char *blk_device, char **table)
|
||||
{
|
||||
std::string result, word;
|
||||
|
|
|
@ -113,8 +113,8 @@ int fs_mgr_do_tmpfs_mount(const char *n_name);
|
|||
int fs_mgr_unmount_all(struct fstab *fstab);
|
||||
int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc,
|
||||
char *real_blk_device, int size);
|
||||
int fs_mgr_load_verity_state(int *mode);
|
||||
int fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback);
|
||||
bool fs_mgr_load_verity_state(int* mode);
|
||||
bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback);
|
||||
int fs_mgr_add_entry(struct fstab *fstab,
|
||||
const char *mount_point, const char *fs_type,
|
||||
const char *blk_device);
|
||||
|
|
|
@ -111,8 +111,8 @@ LOCAL_STATIC_LIBRARIES := \
|
|||
libfec_rs \
|
||||
libsquashfs_utils \
|
||||
liblogwrap \
|
||||
libcutils \
|
||||
libext4_utils \
|
||||
libcutils \
|
||||
libbase \
|
||||
libc \
|
||||
libselinux \
|
||||
|
|
|
@ -677,11 +677,11 @@ static int do_sysclktz(const std::vector<std::string>& args) {
|
|||
|
||||
static int do_verity_load_state(const std::vector<std::string>& args) {
|
||||
int mode = -1;
|
||||
int rc = fs_mgr_load_verity_state(&mode);
|
||||
if (rc == 0 && mode != VERITY_MODE_DEFAULT) {
|
||||
bool loaded = fs_mgr_load_verity_state(&mode);
|
||||
if (loaded && mode != VERITY_MODE_DEFAULT) {
|
||||
ActionManager::GetInstance().QueueEventTrigger("verity-logging");
|
||||
}
|
||||
return rc;
|
||||
return loaded ? 0 : 1;
|
||||
}
|
||||
|
||||
static void verity_update_property(fstab_rec *fstab, const char *mount_point,
|
||||
|
@ -691,7 +691,7 @@ static void verity_update_property(fstab_rec *fstab, const char *mount_point,
|
|||
}
|
||||
|
||||
static int do_verity_update_state(const std::vector<std::string>& args) {
|
||||
return fs_mgr_update_verity_state(verity_update_property);
|
||||
return fs_mgr_update_verity_state(verity_update_property) ? 0 : 1;
|
||||
}
|
||||
|
||||
static int do_write(const std::vector<std::string>& args) {
|
||||
|
|
237
init/init.cpp
237
init/init.cpp
|
@ -61,6 +61,7 @@
|
|||
#include "bootchart.h"
|
||||
#include "devices.h"
|
||||
#include "fs_mgr.h"
|
||||
#include "fs_mgr_avb.h"
|
||||
#include "import_parser.h"
|
||||
#include "init_parser.h"
|
||||
#include "keychords.h"
|
||||
|
@ -482,42 +483,73 @@ static void export_kernel_boot_props() {
|
|||
}
|
||||
}
|
||||
|
||||
static constexpr char android_dt_dir[] = "/proc/device-tree/firmware/android";
|
||||
|
||||
static bool is_dt_compatible() {
|
||||
std::string dt_value;
|
||||
std::string file_name = StringPrintf("%s/compatible", android_dt_dir);
|
||||
|
||||
if (android::base::ReadFileToString(file_name, &dt_value)) {
|
||||
// trim the trailing '\0' out, otherwise the comparison
|
||||
// will produce false-negatives.
|
||||
dt_value.resize(dt_value.size() - 1);
|
||||
if (dt_value == "android,firmware") {
|
||||
/* Reads the content of device tree file into dt_value.
|
||||
* Returns true if the read is success, false otherwise.
|
||||
*/
|
||||
static bool read_dt_file(const std::string& file_name, std::string* dt_value) {
|
||||
if (android::base::ReadFileToString(file_name, dt_value)) {
|
||||
if (!dt_value->empty()) {
|
||||
dt_value->pop_back(); // Trim the trailing '\0' out.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_dt_fstab_compatible() {
|
||||
std::string dt_value;
|
||||
std::string file_name = StringPrintf("%s/%s/compatible", android_dt_dir, "fstab");
|
||||
static const std::string kAndroidDtDir("/proc/device-tree/firmware/android/");
|
||||
|
||||
if (android::base::ReadFileToString(file_name, &dt_value)) {
|
||||
dt_value.resize(dt_value.size() - 1);
|
||||
if (dt_value == "android,fstab") {
|
||||
static bool is_dt_value_expected(const std::string& dt_file_suffix,
|
||||
const std::string& expected_value) {
|
||||
std::string dt_value;
|
||||
std::string file_name = kAndroidDtDir + dt_file_suffix;
|
||||
|
||||
if (read_dt_file(file_name, &dt_value)) {
|
||||
if (dt_value == expected_value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool is_dt_compatible() {
|
||||
return is_dt_value_expected("compatible", "android,firmware");
|
||||
}
|
||||
|
||||
static inline bool is_dt_fstab_compatible() {
|
||||
return is_dt_value_expected("fstab/compatible", "android,fstab");
|
||||
}
|
||||
|
||||
static inline bool is_dt_vbmeta_compatible() {
|
||||
return is_dt_value_expected("vbmeta/compatible", "android,vbmeta");
|
||||
}
|
||||
|
||||
// Gets the vbmeta config from device tree. Specifically, the 'parts' and 'by_name_prefix'.
|
||||
// /{
|
||||
// firmware {
|
||||
// android {
|
||||
// vbmeta {
|
||||
// compatible = "android,vbmeta";
|
||||
// parts = "vbmeta,boot,system,vendor"
|
||||
// by_name_prefix="/dev/block/platform/soc.0/f9824900.sdhci/by-name/"
|
||||
// };
|
||||
// };
|
||||
// };
|
||||
// }
|
||||
static bool get_vbmeta_config_from_dt(std::string* vbmeta_partitions,
|
||||
std::string* device_file_by_name_prefix) {
|
||||
std::string file_name = kAndroidDtDir + "vbmeta/parts";
|
||||
if (!read_dt_file(file_name, vbmeta_partitions)) return false;
|
||||
|
||||
file_name = kAndroidDtDir + "vbmeta/by_name_prefix";
|
||||
if (!read_dt_file(file_name, device_file_by_name_prefix)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void process_kernel_dt() {
|
||||
if (!is_dt_compatible()) return;
|
||||
|
||||
std::unique_ptr<DIR, int(*)(DIR*)>dir(opendir(android_dt_dir), closedir);
|
||||
std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(kAndroidDtDir.c_str()), closedir);
|
||||
if (!dir) return;
|
||||
|
||||
std::string dt_file;
|
||||
|
@ -527,7 +559,7 @@ static void process_kernel_dt() {
|
|||
continue;
|
||||
}
|
||||
|
||||
std::string file_name = StringPrintf("%s/%s", android_dt_dir, dp->d_name);
|
||||
std::string file_name = kAndroidDtDir + dp->d_name;
|
||||
|
||||
android::base::ReadFileToString(file_name, &dt_file);
|
||||
std::replace(dt_file.begin(), dt_file.end(), ',', '.');
|
||||
|
@ -920,38 +952,100 @@ static void set_usb_controller() {
|
|||
}
|
||||
}
|
||||
|
||||
static bool early_mount_one(struct fstab_rec* rec) {
|
||||
if (rec && fs_mgr_is_verified(rec)) {
|
||||
// setup verity and create the dm-XX block device
|
||||
// needed to mount this partition
|
||||
int ret = fs_mgr_setup_verity(rec, false);
|
||||
if (ret == FS_MGR_SETUP_VERITY_FAIL) {
|
||||
PLOG(ERROR) << "early_mount: Failed to setup verity for '" << rec->mount_point << "'";
|
||||
// Creates "/dev/block/dm-XX" for dm-verity by running coldboot on /sys/block/dm-XX.
|
||||
static void device_init_dm_device(const std::string& dm_device) {
|
||||
const std::string device_name(basename(dm_device.c_str()));
|
||||
const std::string syspath = "/sys/block/" + device_name;
|
||||
|
||||
device_init(syspath.c_str(), [&](uevent* uevent) -> coldboot_action_t {
|
||||
if (uevent->device_name && device_name == uevent->device_name) {
|
||||
LOG(VERBOSE) << "early_mount: creating dm-verity device : " << dm_device;
|
||||
return COLDBOOT_STOP;
|
||||
}
|
||||
return COLDBOOT_CONTINUE;
|
||||
});
|
||||
device_close();
|
||||
}
|
||||
|
||||
static bool vboot_1_0_mount_partitions(const std::vector<fstab_rec*>& fstab_recs) {
|
||||
if (fstab_recs.empty()) return false;
|
||||
|
||||
for (auto rec : fstab_recs) {
|
||||
bool need_create_dm_device = false;
|
||||
if (fs_mgr_is_verified(rec)) {
|
||||
// setup verity and create the dm-XX block device
|
||||
// needed to mount this partition
|
||||
int ret = fs_mgr_setup_verity(rec, false /* wait_for_verity_dev */);
|
||||
if (ret == FS_MGR_SETUP_VERITY_DISABLED) {
|
||||
LOG(INFO) << "verity disabled for '" << rec->mount_point << "'";
|
||||
} else if (ret == FS_MGR_SETUP_VERITY_SUCCESS) {
|
||||
need_create_dm_device = true;
|
||||
} else {
|
||||
PLOG(ERROR) << "early_mount: failed to setup verity for '" << rec->mount_point
|
||||
<< "'";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (need_create_dm_device) {
|
||||
// The exact block device name (rec->blk_device) is changed to "/dev/block/dm-XX".
|
||||
// Need to create it because ueventd isn't started during early mount.
|
||||
device_init_dm_device(rec->blk_device);
|
||||
}
|
||||
if (fs_mgr_do_mount_one(rec)) {
|
||||
PLOG(ERROR) << "early_mount: failed to mount '" << rec->mount_point << "'";
|
||||
return false;
|
||||
}
|
||||
|
||||
// The exact block device name is added as a mount source by
|
||||
// fs_mgr_setup_verity() in ->blk_device as "/dev/block/dm-XX"
|
||||
// We create that device by running coldboot on /sys/block/dm-XX
|
||||
std::string dm_device(basename(rec->blk_device));
|
||||
std::string syspath = StringPrintf("/sys/block/%s", dm_device.c_str());
|
||||
device_init(syspath.c_str(), [&](uevent* uevent) -> coldboot_action_t {
|
||||
if (uevent->device_name && !strcmp(dm_device.c_str(), uevent->device_name)) {
|
||||
LOG(VERBOSE) << "early_mount: creating dm-verity device : " << dm_device;
|
||||
return COLDBOOT_STOP;
|
||||
}
|
||||
return COLDBOOT_CONTINUE;
|
||||
});
|
||||
}
|
||||
|
||||
if (rec && fs_mgr_do_mount_one(rec)) {
|
||||
PLOG(ERROR) << "early_mount: Failed to mount '" << rec->mount_point << "'";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool vboot_2_0_mount_partitions(const std::vector<fstab_rec*>& fstab_recs,
|
||||
const std::string& device_file_by_name_prefix) {
|
||||
if (fstab_recs.empty()) return false;
|
||||
|
||||
FsManagerAvbUniquePtr avb_handle = FsManagerAvbHandle::Open(device_file_by_name_prefix);
|
||||
if (!avb_handle) {
|
||||
LOG(INFO) << "Failed to Open FsManagerAvbHandle";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto rec : fstab_recs) {
|
||||
bool need_create_dm_device = false;
|
||||
if (fs_mgr_is_avb(rec)) {
|
||||
if (avb_handle->AvbHashtreeDisabled()) {
|
||||
LOG(INFO) << "avb hashtree disabled for '" << rec->mount_point << "'";
|
||||
} else if (avb_handle->SetUpAvb(rec, false /* wait_for_verity_dev */)) {
|
||||
need_create_dm_device = true;
|
||||
} else {
|
||||
PLOG(ERROR) << "early_mount: failed to set up AVB on partition: '"
|
||||
<< rec->mount_point << "'";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (need_create_dm_device) {
|
||||
// The exact block device name (rec->blk_device) is changed to "/dev/block/dm-XX".
|
||||
// Need to create it because ueventd isn't started during early mount.
|
||||
device_init_dm_device(rec->blk_device);
|
||||
}
|
||||
if (fs_mgr_do_mount_one(rec)) {
|
||||
PLOG(ERROR) << "early_mount: failed to mount '" << rec->mount_point << "'";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mount_early_partitions(const std::vector<fstab_rec*>& fstab_recs,
|
||||
const std::string& device_file_by_name_prefix) {
|
||||
if (is_dt_vbmeta_compatible()) { // AVB (external/avb) is used to setup dm-verity.
|
||||
return vboot_2_0_mount_partitions(fstab_recs, device_file_by_name_prefix);
|
||||
} else {
|
||||
return vboot_1_0_mount_partitions(fstab_recs);
|
||||
}
|
||||
}
|
||||
|
||||
// Creates devices with uevent->partition_name matching one in the in/out
|
||||
// partition_names. Note that the partition_names MUST have A/B suffix
|
||||
// when A/B is used. Found partitions will then be removed from the
|
||||
|
@ -994,12 +1088,10 @@ static void early_device_init(std::set<std::string>* partition_names) {
|
|||
});
|
||||
}
|
||||
|
||||
static bool get_early_partitions(const std::vector<fstab_rec*>& early_fstab_recs,
|
||||
std::set<std::string>* out_partitions, bool* out_need_verity) {
|
||||
static bool vboot_1_0_early_partitions(const std::vector<fstab_rec*>& early_fstab_recs,
|
||||
std::set<std::string>* out_partitions,
|
||||
bool* out_need_verity) {
|
||||
std::string meta_partition;
|
||||
out_partitions->clear();
|
||||
*out_need_verity = false;
|
||||
|
||||
for (auto fstab_rec : early_fstab_recs) {
|
||||
// don't allow verifyatboot for early mounted partitions
|
||||
if (fs_mgr_is_verifyatboot(fstab_rec)) {
|
||||
|
@ -1038,6 +1130,40 @@ static bool get_early_partitions(const std::vector<fstab_rec*>& early_fstab_recs
|
|||
return true;
|
||||
}
|
||||
|
||||
// a.k.a. AVB (external/avb)
|
||||
static bool vboot_2_0_early_partitions(std::set<std::string>* out_partitions, bool* out_need_verity,
|
||||
std::string* out_device_file_by_name_prefix) {
|
||||
std::string vbmeta_partitions;
|
||||
if (!get_vbmeta_config_from_dt(&vbmeta_partitions, out_device_file_by_name_prefix)) {
|
||||
return false;
|
||||
}
|
||||
// libavb verifies AVB metadata on all verified partitions at once.
|
||||
// e.g., The vbmeta_partitions will be "vbmeta,boot,system,vendor"
|
||||
// for libavb to verify metadata, even if we only need to early mount /vendor.
|
||||
std::vector<std::string> partitions = android::base::Split(vbmeta_partitions, ",");
|
||||
std::string ab_suffix = fs_mgr_get_slot_suffix();
|
||||
for (const auto& partition : partitions) {
|
||||
out_partitions->emplace(partition + ab_suffix);
|
||||
}
|
||||
*out_need_verity = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool get_early_partitions(const std::vector<fstab_rec*>& early_fstab_recs,
|
||||
std::set<std::string>* out_partitions, bool* out_need_verity,
|
||||
std::string* out_device_file_by_name_prefix) {
|
||||
*out_need_verity = false;
|
||||
out_partitions->clear();
|
||||
out_device_file_by_name_prefix->clear();
|
||||
|
||||
if (is_dt_vbmeta_compatible()) { // AVB (external/avb) is used to setup dm-verity.
|
||||
return vboot_2_0_early_partitions(out_partitions, out_need_verity,
|
||||
out_device_file_by_name_prefix);
|
||||
} else {
|
||||
return vboot_1_0_early_partitions(early_fstab_recs, out_partitions, out_need_verity);
|
||||
}
|
||||
}
|
||||
|
||||
/* Early mount vendor and ODM partitions. The fstab is read from device-tree. */
|
||||
static bool early_mount() {
|
||||
// skip early mount if we're in recovery mode
|
||||
|
@ -1072,9 +1198,11 @@ static bool early_mount() {
|
|||
if (early_fstab_recs.empty()) return true;
|
||||
|
||||
bool need_verity;
|
||||
std::string device_file_by_name_prefix;
|
||||
std::set<std::string> partition_names;
|
||||
// partition_names MUST have A/B suffix when A/B is used
|
||||
if (!get_early_partitions(early_fstab_recs, &partition_names, &need_verity)) {
|
||||
if (!get_early_partitions(early_fstab_recs, &partition_names, &need_verity,
|
||||
&device_file_by_name_prefix)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1097,10 +1225,9 @@ static bool early_mount() {
|
|||
[&](uevent* uevent) -> coldboot_action_t { return COLDBOOT_STOP; });
|
||||
}
|
||||
|
||||
for (auto fstab_rec : early_fstab_recs) {
|
||||
if (!early_mount_one(fstab_rec)) goto done;
|
||||
if (mount_early_partitions(early_fstab_recs, device_file_by_name_prefix)) {
|
||||
success = true;
|
||||
}
|
||||
success = true;
|
||||
|
||||
done:
|
||||
device_close();
|
||||
|
|
Loading…
Reference in a new issue