Snap for 6310897 from 8b43fdd100b0337d247350070fdd1bb154012d02 to mainline-release

Change-Id: I7e1b901398e41e0238ae9d5f709e8091d1a0ac35
diff --git a/otautil/include/otautil/sysutil.h b/otautil/include/otautil/sysutil.h
index 326db86..d0d2e67 100644
--- a/otautil/include/otautil/sysutil.h
+++ b/otautil/include/otautil/sysutil.h
@@ -103,7 +103,7 @@
 
 // Reboots the device into the specified target, by additionally handling quiescent reboot mode.
 // All unknown targets reboot into Android.
-bool Reboot(std::string_view target);
+[[noreturn]] void Reboot(std::string_view target);
 
 // Triggers a shutdown.
 bool Shutdown(std::string_view target);
diff --git a/otautil/sysutil.cpp b/otautil/sysutil.cpp
index 6cd46c6..b3ead97 100644
--- a/otautil/sysutil.cpp
+++ b/otautil/sysutil.cpp
@@ -219,14 +219,18 @@
   ranges_.clear();
 }
 
-bool Reboot(std::string_view target) {
+void Reboot(std::string_view target) {
   std::string cmd = "reboot," + std::string(target);
   // Honor the quiescent mode if applicable.
   if (target != "bootloader" && target != "fastboot" &&
       android::base::GetBoolProperty("ro.boot.quiescent", false)) {
     cmd += ",quiescent";
   }
-  return android::base::SetProperty(ANDROID_RB_PROPERTY, cmd);
+  if (!android::base::SetProperty(ANDROID_RB_PROPERTY, cmd)) {
+    LOG(FATAL) << "Reboot failed";
+  }
+
+  while (true) pause();
 }
 
 bool Shutdown(std::string_view target) {
diff --git a/recovery.cpp b/recovery.cpp
index 0382697..7675121 100644
--- a/recovery.cpp
+++ b/recovery.cpp
@@ -781,13 +781,7 @@
           ui->Print("Retry attempt %d\n", retry_count);
 
           // Reboot back into recovery to retry the update.
-          if (!Reboot("recovery")) {
-            ui->Print("Reboot failed\n");
-          } else {
-            while (true) {
-              pause();
-            }
-          }
+          Reboot("recovery");
         }
         // If this is an eng or userdebug build, then automatically
         // turn the text display on if the script fails so the error
diff --git a/recovery_ui/ui.cpp b/recovery_ui/ui.cpp
index 6f5cbbc..3307217 100644
--- a/recovery_ui/ui.cpp
+++ b/recovery_ui/ui.cpp
@@ -375,9 +375,6 @@
       case RecoveryUI::REBOOT:
         if (reboot_enabled) {
           Reboot("userrequested,recovery,ui");
-          while (true) {
-            pause();
-          }
         }
         break;
 
diff --git a/updater/install.cpp b/updater/install.cpp
index 62ff87e..7608dc3 100644
--- a/updater/install.cpp
+++ b/updater/install.cpp
@@ -733,7 +733,6 @@
 
   Reboot(property);
 
-  sleep(5);
   return ErrorAbort(state, kRebootFailure, "%s() failed to reboot", name);
 }
 
diff --git a/updater/updater_runtime.cpp b/updater/updater_runtime.cpp
index c4222a5..b1b8863 100644
--- a/updater/updater_runtime.cpp
+++ b/updater/updater_runtime.cpp
@@ -43,10 +43,62 @@
   return std::string(name);
 }
 
+static struct {
+  const char* name;
+  unsigned flag;
+} mount_flags_list[] = {
+  { "noatime", MS_NOATIME },
+  { "noexec", MS_NOEXEC },
+  { "nosuid", MS_NOSUID },
+  { "nodev", MS_NODEV },
+  { "nodiratime", MS_NODIRATIME },
+  { "ro", MS_RDONLY },
+  { "rw", 0 },
+  { "remount", MS_REMOUNT },
+  { "bind", MS_BIND },
+  { "rec", MS_REC },
+  { "unbindable", MS_UNBINDABLE },
+  { "private", MS_PRIVATE },
+  { "slave", MS_SLAVE },
+  { "shared", MS_SHARED },
+  { "defaults", 0 },
+  { 0, 0 },
+};
+
+static bool setMountFlag(const std::string& flag, unsigned* mount_flags) {
+  for (const auto& [name, value] : mount_flags_list) {
+    if (flag == name) {
+      *mount_flags |= value;
+      return true;
+    }
+  }
+  return false;
+}
+
+static bool parseMountFlags(const std::string& flags, unsigned* mount_flags,
+                            std::string* fs_options) {
+  bool is_flag_set = false;
+  std::vector<std::string> flag_list;
+  for (const auto& flag : android::base::Split(flags, ",")) {
+    if (!setMountFlag(flag, mount_flags)) {
+      // Unknown flag, so it must be a filesystem specific option.
+      flag_list.push_back(flag);
+    } else {
+      is_flag_set = true;
+    }
+  }
+  *fs_options = android::base::Join(flag_list, ',');
+  return is_flag_set;
+}
+
 int UpdaterRuntime::Mount(const std::string_view location, const std::string_view mount_point,
                           const std::string_view fs_type, const std::string_view mount_options) {
   std::string mount_point_string(mount_point);
+  std::string mount_options_string(mount_options);
   char* secontext = nullptr;
+  unsigned mount_flags = 0;
+  std::string fs_options;
+
   if (sehandle_) {
     selabel_lookup(sehandle_, &secontext, mount_point_string.c_str(), 0755);
     setfscreatecon(secontext);
@@ -59,9 +111,13 @@
     setfscreatecon(nullptr);
   }
 
+  if (!parseMountFlags(mount_options_string, &mount_flags, &fs_options)) {
+    // Fall back to default
+    mount_flags = MS_NOATIME | MS_NODEV | MS_NODIRATIME;
+  }
+
   return mount(std::string(location).c_str(), mount_point_string.c_str(),
-               std::string(fs_type).c_str(), MS_NOATIME | MS_NODEV | MS_NODIRATIME,
-               std::string(mount_options).c_str());
+               std::string(fs_type).c_str(), mount_flags, fs_options.c_str());
 }
 
 bool UpdaterRuntime::IsMounted(const std::string_view mount_point) const {