fstab: allow mounting other slot

Adding a new fs_mgr flag 'slotselect_other' to mount _b when _a is
active, or vice versa.

Bug: 113182233
Bug: 112103720
Test: `mount_all fstab.test` with one line using `slotselect_other`.

Change-Id: I96c63141df7722dc30ca9817b0b154e493b9eef9
This commit is contained in:
Bowgo Tsai 2018-12-12 23:21:13 +08:00
parent 42c9e7e393
commit 4c80edf9cd
4 changed files with 37 additions and 11 deletions

View file

@ -59,7 +59,7 @@ struct fs_mgr_flag_values {
struct flag_list {
const char *name;
unsigned int flag;
uint64_t flag;
};
static struct flag_list mount_flags[] = {
@ -116,6 +116,7 @@ static struct flag_list fs_mgr_flags[] = {
{"logical", MF_LOGICAL},
{"checkpoint=block", MF_CHECKPOINT_BLK},
{"checkpoint=fs", MF_CHECKPOINT_FS},
{"slotselect_other", MF_SLOTSELECT_OTHER},
{0, 0},
};
@ -207,11 +208,9 @@ static bool read_dt_file(const std::string& file_name, std::string* dt_value)
return false;
}
static int parse_flags(char *flags, struct flag_list *fl,
struct fs_mgr_flag_values *flag_vals,
char *fs_options, int fs_options_len)
{
int f = 0;
static uint64_t parse_flags(char* flags, struct flag_list* fl, struct fs_mgr_flag_values* flag_vals,
char* fs_options, int fs_options_len) {
uint64_t f = 0;
int i;
char *p;
char *savep;

View file

@ -120,6 +120,8 @@
#define MF_CHECKPOINT_FS 0x40000000
#define MF_FIRST_STAGE_MOUNT \
0x80000000
#define MF_SLOTSELECT_OTHER \
0x100000000
// clang-format on
#define DM_BUF_SIZE 4096

View file

@ -21,6 +21,19 @@
#include "fs_mgr.h"
#include "fs_mgr_priv.h"
// https://source.android.com/devices/tech/ota/ab/ab_implement#partitions
// All partitions that are A/B-ed should be named as follows (slots are always
// named a, b, etc.): boot_a, boot_b, system_a, system_b, vendor_a, vendor_b.
static std::string other_suffix(const std::string& slot_suffix) {
if (slot_suffix == "_a") {
return "_b";
}
if (slot_suffix == "_b") {
return "_a";
}
return "";
}
// Returns "_a" or "_b" based on androidboot.slot_suffix in kernel cmdline, or an empty string
// if that parameter does not exist.
std::string fs_mgr_get_slot_suffix() {
@ -35,7 +48,7 @@ bool fs_mgr_update_for_slotselect(Fstab* fstab) {
std::string ab_suffix;
for (auto& entry : *fstab) {
if (!entry.fs_mgr_flags.slot_select) {
if (!entry.fs_mgr_flags.slot_select && !entry.fs_mgr_flags.slot_select_other) {
continue;
}
@ -45,8 +58,10 @@ bool fs_mgr_update_for_slotselect(Fstab* fstab) {
if (ab_suffix.empty()) return false;
}
entry.blk_device = entry.blk_device + ab_suffix;
entry.logical_partition_name = entry.logical_partition_name + ab_suffix;
const auto& update_suffix =
entry.fs_mgr_flags.slot_select ? ab_suffix : other_suffix(ab_suffix);
entry.blk_device = entry.blk_device + update_suffix;
entry.logical_partition_name = entry.logical_partition_name + update_suffix;
}
return true;
}

View file

@ -43,7 +43,7 @@ struct fstab_rec {
char* fs_type;
unsigned long flags;
char* fs_options;
int fs_mgr_flags;
uint64_t fs_mgr_flags;
char* key_loc;
char* key_dir;
char* verity_loc;
@ -123,8 +123,9 @@ struct FstabEntry {
// 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.
union {
int val;
uint64_t val;
struct {
// bit 0
bool wait : 1;
bool check : 1;
bool crypt : 1;
@ -133,6 +134,8 @@ struct FstabEntry {
bool length : 1;
bool recovery_only : 1;
bool swap_prio : 1;
// bit 8
bool zram_size : 1;
bool verify : 1;
bool force_crypt : 1;
@ -142,6 +145,8 @@ struct FstabEntry {
bool file_encryption : 1;
bool formattable : 1;
bool slot_select : 1;
// bit 16
bool force_fde_or_fbe : 1;
bool late_mount : 1;
bool no_fail : 1;
@ -150,6 +155,8 @@ struct FstabEntry {
bool reserved_size : 1;
bool quota : 1;
bool erase_blk_size : 1;
// bit 24
bool logical_blk_size : 1;
bool avb : 1;
bool key_directory : 1;
@ -158,6 +165,9 @@ struct FstabEntry {
bool checkpoint_blk : 1;
bool checkpoint_fs : 1;
bool first_stage_mount : 1;
// bit 32
bool slot_select_other : 1;
};
} fs_mgr_flags;