From f6e42ce3905f80cc4087bcb7c79d2d6ca11e7eca Mon Sep 17 00:00:00 2001 From: Chaosmaster Date: Mon, 27 Jan 2020 00:17:04 +0100 Subject: [PATCH] Implement autodetection for SAR, based on the installed system This will detect whether SAR is present in the currently installed OS and set the property ro.twrp.sar accordingly. After setting the property it will call the bootscript /sbin/sarsetup.sh (if present) to give device maintainers the option to do setup operations depending on SAR-status, such as modifiyng the fstab. If no system is detected and AB_OTA_UPDATER is defined or built with Android 10 and upwards, it will fallback to using SAR, otherwise it will use ro.build.system_root_image as basis for deciding whether SAR is required or not. The property ro.twrp.sar will also be used by TWPartitionManager::Get_Android_Root_Path() This allows maintaining a single TWRP-build for devices switching to SAR for Android 10. The default behavior (when no system is installed) is determined by the build-flags AB_OTA_UPDATER and BOARD_BUILD_SYSTEM_ROOT_IMAGE Change-Id: I2a48c6c81a6ea6fad6e452c06bfbe4d9da0f1e5c --- partition.cpp | 32 ++++++++++++++++++++++++-------- partitionmanager.cpp | 15 +++++++++++---- partitions.hpp | 4 ++-- twrp.cpp | 44 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 80 insertions(+), 15 deletions(-) diff --git a/partition.cpp b/partition.cpp index 8d86f694..646959c3 100644 --- a/partition.cpp +++ b/partition.cpp @@ -272,7 +272,7 @@ TWPartition::~TWPartition(void) { // Do nothing } -bool TWPartition::Process_Fstab_Line(const char *fstab_line, bool Display_Error, std::map *twrp_flags) { +bool TWPartition::Process_Fstab_Line(const char *fstab_line, bool Display_Error, std::map *twrp_flags, bool Sar_Detect) { char full_line[MAX_FSTAB_LINE_LENGTH]; char twflags[MAX_FSTAB_LINE_LENGTH] = ""; char* ptr; @@ -309,11 +309,12 @@ bool TWPartition::Process_Fstab_Line(const char *fstab_line, bool Display_Error, Mount_Point = ptr; if (fstab_version == 2) { additional_entry = PartitionManager.Find_Partition_By_Path(Mount_Point); - if (additional_entry) { + if (!Sar_Detect && additional_entry) { LOGINFO("Found an additional entry for '%s'\n", Mount_Point.c_str()); } } - LOGINFO("Processing '%s'\n", Mount_Point.c_str()); + if(!Sar_Detect) + LOGINFO("Processing '%s'\n", Mount_Point.c_str()); Backup_Path = Mount_Point; Storage_Path = Mount_Point; Display_Name = ptr + 1; @@ -410,7 +411,12 @@ bool TWPartition::Process_Fstab_Line(const char *fstab_line, bool Display_Error, if (Primary_Block_Device.find("*") != string::npos) Wildcard_Block_Device = true; - if (Mount_Point == "auto") { + if (Sar_Detect) { + if(Is_File_System(Fstab_File_System) && (Mount_Point == "/" || Mount_Point == "/system" || Mount_Point == "/system_root")) + Find_Actual_Block_Device(); + else + return true; + } else if (Mount_Point == "auto") { Mount_Point = "/auto"; char autoi[5]; sprintf(autoi, "%i", auto_index); @@ -437,9 +443,6 @@ bool TWPartition::Process_Fstab_Line(const char *fstab_line, bool Display_Error, Find_Actual_Block_Device(); Setup_File_System(Display_Error); if (Mount_Point == "/" || Mount_Point == "/system" || Mount_Point == "/system_root") { - Mount_Point = PartitionManager.Get_Android_Root_Path(); - Backup_Path = Mount_Point; - Storage_Path = Mount_Point; Display_Name = "System"; Backup_Display_Name = Display_Name; Storage_Name = Display_Name; @@ -601,6 +604,19 @@ bool TWPartition::Process_Fstab_Line(const char *fstab_line, bool Display_Error, } } + if (Is_File_System(Fstab_File_System) && (Mount_Point == "/" || Mount_Point == "/system" || Mount_Point == "/system_root")) { + if (Sar_Detect) { + Mount_Point = "/s"; + Mount_Read_Only = true; + Can_Be_Mounted = true; + } else { + Mount_Point = PartitionManager.Get_Android_Root_Path(); + Backup_Path = Mount_Point; + Storage_Path = Mount_Point; + Make_Dir(Mount_Point, Display_Error); + } + } + return true; } @@ -2911,7 +2927,7 @@ bool TWPartition::Find_Wildcard_Block_Devices(const string& Device) { TWPartition *part = new TWPartition; char buffer[MAX_FSTAB_LINE_LENGTH]; sprintf(buffer, "%s %s-%i auto defaults defaults", item.c_str(), Mount_Point.c_str(), ++mount_point_index); - part->Process_Fstab_Line(buffer, false, NULL); + part->Process_Fstab_Line(buffer, false, NULL, false); char display[MAX_FSTAB_LINE_LENGTH]; sprintf(display, "%s %i", Storage_Name.c_str(), mount_point_index); part->Storage_Name = display; diff --git a/partitionmanager.cpp b/partitionmanager.cpp index 141576f5..f63b3f3e 100755 --- a/partitionmanager.cpp +++ b/partitionmanager.cpp @@ -111,7 +111,7 @@ TWPartitionManager::TWPartitionManager(void) { #endif } -int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error) { +int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error, bool Sar_Detect) { FILE *fstabFile; char fstab_line[MAX_FSTAB_LINE_LENGTH]; TWPartition* settings_partition = NULL; @@ -198,7 +198,7 @@ int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error) fstab_line[line_size] = '\n'; TWPartition* partition = new TWPartition(); - if (partition->Process_Fstab_Line(fstab_line, Display_Error, &twrp_flags)) + if (partition->Process_Fstab_Line(fstab_line, Display_Error, &twrp_flags, Sar_Detect)) Partitions.push_back(partition); else delete partition; @@ -213,7 +213,7 @@ int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error) for (std::map::iterator mapit=twrp_flags.begin(); mapit!=twrp_flags.end(); mapit++) { if (Find_Partition_By_Path(mapit->first) == NULL) { TWPartition* partition = new TWPartition(); - if (partition->Process_Fstab_Line(mapit->second.fstab_line, Display_Error, NULL)) + if (partition->Process_Fstab_Line(mapit->second.fstab_line, Display_Error, NULL, Sar_Detect)) Partitions.push_back(partition); else delete partition; @@ -227,6 +227,13 @@ int TWPartitionManager::Process_Fstab(string Fstab_Filename, bool Display_Error) std::vector::iterator iter; for (iter = Partitions.begin(); iter != Partitions.end(); iter++) { + if (Sar_Detect) { + if ((*iter)->Mount_Point == "/s") + return true; + else + continue; + } + (*iter)->Partition_Post_Processing(Display_Error); if ((*iter)->Is_Storage) { @@ -2840,7 +2847,7 @@ string TWPartitionManager::Get_Active_Slot_Display() { } string TWPartitionManager::Get_Android_Root_Path() { - if (property_get_bool("ro.build.system_root_image", false)) + if (property_get_bool("ro.twrp.sar", false)) return "/system_root"; return "/system"; } diff --git a/partitions.hpp b/partitions.hpp index 4071b942..92970d92 100644 --- a/partitions.hpp +++ b/partitions.hpp @@ -178,7 +178,7 @@ protected: void Setup_Data_Media(); // Sets up a partition as a /data/media emulated storage partition private: - bool Process_Fstab_Line(const char *fstab_line, bool Display_Error, std::map *twrp_flags); // Processes a fstab line + bool Process_Fstab_Line(const char *fstab_line, bool Display_Error, std::map *twrp_flags, bool Sar_Detect); // Processes a fstab line void Setup_Data_Partition(bool Display_Error); // Setup data partition after fstab processed void Setup_Cache_Partition(bool Display_Error); // Setup cache partition after fstab processed bool Find_Wildcard_Block_Devices(const string& Device); // Searches for and finds wildcard block devices @@ -305,7 +305,7 @@ public: ~TWPartitionManager() {} public: - int Process_Fstab(string Fstab_Filename, bool Display_Error); // Parses the fstab and populates the partitions + int Process_Fstab(string Fstab_Filename, bool Display_Error, bool Sar_Detect); // Parses the fstab and populates the partitions int Write_Fstab(); // Creates /etc/fstab file that's used by the command line for mount commands void Output_Partition_Logging(); // Outputs partition information to the log void Output_Partition(TWPartition* Part); // Outputs partition details to the log diff --git a/twrp.cpp b/twrp.cpp index dac00932..bb062f70 100755 --- a/twrp.cpp +++ b/twrp.cpp @@ -117,8 +117,50 @@ int main(int argc, char **argv) { if (!TWFunc::Path_Exists(fstab_filename)) { fstab_filename = "/etc/recovery.fstab"; } + + // Begin SAR detection + { + TWPartitionManager SarPartitionManager; + printf("=> Processing %s for SAR-detection\n", fstab_filename.c_str()); + if (!SarPartitionManager.Process_Fstab(fstab_filename, 1, 1)) { + LOGERR("Failing out of recovery due to problem with fstab.\n"); + return -1; + } + + mkdir("/s", 0755); + +#if defined(AB_OTA_UPDATER) || defined(__ANDROID_API_Q__) + bool fallback_sar = true; +#else + bool fallback_sar = property_get_bool("ro.build.system_root_image", false); +#endif + + if(SarPartitionManager.Mount_By_Path("/s", false)) { + if (TWFunc::Path_Exists("/s/build.prop")) { + LOGINFO("SAR-DETECT: Non-SAR System detected\n"); + property_set("ro.twrp.sar", "0"); + rmdir("/system_root"); + } else if (TWFunc::Path_Exists("/s/system/build.prop")) { + LOGINFO("SAR-DETECT: SAR System detected\n"); + property_set("ro.twrp.sar", "1"); + } else { + LOGINFO("SAR-DETECT: No build.prop found, falling back to %s\n", fallback_sar ? "SAR" : "Non-SAR"); + property_set("ro.twrp.sar", fallback_sar ? "1" : "0"); + } + SarPartitionManager.UnMount_By_Path("/s", false); + } else { + LOGINFO("SAR-DETECT: Could not mount system partition, falling back to %s\n", fallback_sar ? "SAR":"Non-SAR"); + property_set("ro.twrp.sar", fallback_sar ? "1" : "0"); + } + + rmdir("/s"); + + TWFunc::check_and_run_script("/sbin/sarsetup.sh", "boot"); + } + // End SAR detection + printf("=> Processing %s\n", fstab_filename.c_str()); - if (!PartitionManager.Process_Fstab(fstab_filename, 1)) { + if (!PartitionManager.Process_Fstab(fstab_filename, 1, 0)) { LOGERR("Failing out of recovery due to problem with fstab.\n"); return -1; }