If dt fstab contains error, fallback to default fstab

See https://cs.android.com/android/platform/superproject/+/master:system/core/init/first_stage_mount.cpp;drc=master;l=155

From the source of `FirstStageMount`, dt fstab can fail gracefully and
if any error occurs it will fall back to default fstab. Magisk now
replaces the default fstab and dt fstab unconditionally, bringing potential
errors to the default fstab and causing init fails to load partitions.
This commit is contained in:
LoveSy 2021-12-29 07:16:20 +08:00 committed by John Wu
parent afcc60066e
commit 19182ffddf

View File

@ -27,7 +27,11 @@ void fstab_entry::to_file(FILE *fp) {
line[val##1] = '\0'; \ line[val##1] = '\0'; \
entry.val = &line[val##0]; entry.val = &line[val##0];
static void read_fstab_file(const char *fstab_file, vector<fstab_entry> &fstab) { static bool read_fstab_file(const char *fstab_file, vector<fstab_entry> &fstab) {
if (!fstab_file || fstab_file[0] == '\0') {
LOGE("fstab file is empty");
return false;
}
file_readline(fstab_file, [&](string_view l) -> bool { file_readline(fstab_file, [&](string_view l) -> bool {
if (l[0] == '#' || l.length() == 1) if (l[0] == '#' || l.length() == 1)
return true; return true;
@ -51,6 +55,7 @@ static void read_fstab_file(const char *fstab_file, vector<fstab_entry> &fstab)
fstab.emplace_back(move(entry)); fstab.emplace_back(move(entry));
return true; return true;
}); });
return true;
} }
#define FSR "/first_stage_ramdisk" #define FSR "/first_stage_ramdisk"
@ -101,6 +106,7 @@ exit_loop:
if (!fstab.empty()) { if (!fstab.empty()) {
// Dump dt fstab to fstab file in rootfs and force init to use it instead // Dump dt fstab to fstab file in rootfs and force init to use it instead
bool should_skip = false; // If there's any error in dt fstab and if so, skip loading it
// All dt fstab entries should be first_stage_mount // All dt fstab entries should be first_stage_mount
for (auto &entry : fstab) { for (auto &entry : fstab) {
@ -109,6 +115,10 @@ exit_loop:
entry.fsmgr_flags += ','; entry.fsmgr_flags += ',';
entry.fsmgr_flags += "first_stage_mount"; entry.fsmgr_flags += "first_stage_mount";
} }
// If the entry contains slotselect but the current slot is empty, error occurs
if (config->slot[0] == '\0' && str_contains(entry.fsmgr_flags, "slotselect")) {
should_skip = true;
} // TODO: else if expected_field checks and fs_mgr_flags checks
} }
if (fstab_file[0] == '\0') { if (fstab_file[0] == '\0') {
@ -122,18 +132,18 @@ exit_loop:
} }
sprintf(fstab_file, "fstab.%s", suffix); sprintf(fstab_file, "fstab.%s", suffix);
} }
if (should_skip) {
// When dt fstab fails, fall back to default fstab
LOGI("dt fstab contains error, falling back to default fstab");
fstab.clear();
if (!read_fstab_file(fstab_file, fstab)) return;
// Patch init to force IsDtFstabCompatible() return false } else {
auto init = mmap_data("/init", true); // Patch init to force IsDtFstabCompatible() return false
init.patch({ make_pair("android,fstab", "xxx") }); auto init = mmap_data("/init", true);
} else { init.patch({make_pair("android,fstab", "xxx")});
if (fstab_file[0] == '\0') {
LOGE("Cannot find fstab");
return;
} }
// Parse and load the fstab file } else if (!read_fstab_file(fstab_file, fstab)) return;
read_fstab_file(fstab_file, fstab);
}
// Append oppo's custom fstab // Append oppo's custom fstab
if (access("oplus.fstab", F_OK) == 0) { if (access("oplus.fstab", F_OK) == 0) {