Commit 19182ffd authored by LoveSy's avatar LoveSy Committed by John Wu

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.
parent afcc6006
...@@ -27,7 +27,11 @@ void fstab_entry::to_file(FILE *fp) { ...@@ -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) ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -122,18 +132,18 @@ exit_loop:
} }
sprintf(fstab_file, "fstab.%s", suffix); sprintf(fstab_file, "fstab.%s", suffix);
} }
if (should_skip) {
// Patch init to force IsDtFstabCompatible() return false // When dt fstab fails, fall back to default fstab
auto init = mmap_data("/init", true); LOGI("dt fstab contains error, falling back to default fstab");
init.patch({ make_pair("android,fstab", "xxx") }); fstab.clear();
} else { if (!read_fstab_file(fstab_file, fstab)) return;
if (fstab_file[0] == '\0') {
LOGE("Cannot find fstab"); } else {
return; // Patch init to force IsDtFstabCompatible() return false
auto init = mmap_data("/init", true);
init.patch({make_pair("android,fstab", "xxx")});
} }
// 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) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment