Merge "Clean up libcutils/libutils tests."
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 8528752..ed955ea 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -114,25 +114,6 @@
   return cmd;
 }
 
-// Convenience wrapper over the property API that returns an
-// std::string.
-std::string GetProperty(const char* key) {
-  std::vector<char> temp(PROPERTY_VALUE_MAX);
-  const int len = property_get(key, &temp[0], nullptr);
-  if (len < 0) {
-    return "";
-  }
-  return std::string(&temp[0], len);
-}
-
-bool SetProperty(const char* key, const std::string& val) {
-  return property_set(key, val.c_str()) == 0;
-}
-
-bool SetProperty(const char* key, const char* val) {
-  return property_set(key, val) == 0;
-}
-
 constexpr int32_t kEmptyBootReason = 0;
 constexpr int32_t kUnknownBootReason = 1;
 
@@ -746,11 +727,13 @@
 void BootReasonAddToHistory(const std::string& system_boot_reason) {
   if (system_boot_reason.empty()) return;
   LOG(INFO) << "Canonical boot reason: " << system_boot_reason;
-  auto old_system_boot_reason = GetProperty(system_reboot_reason_property);
-  if (!SetProperty(system_reboot_reason_property, system_boot_reason)) {
-    SetProperty(system_reboot_reason_property, system_boot_reason.substr(0, PROPERTY_VALUE_MAX - 1));
+  auto old_system_boot_reason = android::base::GetProperty(system_reboot_reason_property, "");
+  if (!android::base::SetProperty(system_reboot_reason_property, system_boot_reason)) {
+    android::base::SetProperty(system_reboot_reason_property,
+                               system_boot_reason.substr(0, PROPERTY_VALUE_MAX - 1));
   }
-  auto reason_history = android::base::Split(GetProperty(history_reboot_reason_property), "\n");
+  auto reason_history =
+      android::base::Split(android::base::GetProperty(history_reboot_reason_property, ""), "\n");
   static auto mark = time(nullptr);
   auto mark_str = std::string(",") + std::to_string(mark);
   auto marked_system_boot_reason = system_boot_reason + mark_str;
@@ -773,7 +756,8 @@
   reason_history.insert(reason_history.begin(), marked_system_boot_reason);
   // If the property string is too long ( > PROPERTY_VALUE_MAX)
   // we get an error, so trim out last entry and try again.
-  while (!(SetProperty(history_reboot_reason_property, android::base::Join(reason_history, '\n')))) {
+  while (!android::base::SetProperty(history_reboot_reason_property,
+                                     android::base::Join(reason_history, '\n'))) {
     auto it = std::prev(reason_history.end());
     if (it == reason_history.end()) break;
     reason_history.erase(it);
@@ -782,7 +766,7 @@
 
 // Scrub, Sanitize, Standardize and Enhance the boot reason string supplied.
 std::string BootReasonStrToReason(const std::string& boot_reason) {
-  std::string ret(GetProperty(system_reboot_reason_property));
+  auto ret = android::base::GetProperty(system_reboot_reason_property, "");
   std::string reason(boot_reason);
   // If sys.boot.reason == ro.boot.bootreason, let's re-evaluate
   if (reason == ret) ret = "";
@@ -922,7 +906,7 @@
     if (isBluntRebootReason(ret)) {
       // Content buffer no longer will have console data. Beware if more
       // checks added below, that depend on parsing console content.
-      content = GetProperty(last_reboot_reason_property);
+      content = android::base::GetProperty(last_reboot_reason_property, "");
       transformReason(content);
 
       // Anything in last is better than 'super-blunt' reboot or shutdown.
@@ -966,7 +950,7 @@
   static const std::string kBuildDateKey = "build_date";
   std::string boot_complete_prefix = "boot_complete";
 
-  std::string build_date_str = GetProperty("ro.build.date.utc");
+  auto build_date_str = android::base::GetProperty("ro.build.date.utc", "");
   int32_t build_date;
   if (!android::base::ParseInt(build_date_str, &build_date)) {
     return std::string();
@@ -989,7 +973,7 @@
 
 // Records the value of a given ro.boottime.init property in milliseconds.
 void RecordInitBootTimeProp(BootEventRecordStore* boot_event_store, const char* property) {
-  std::string value = GetProperty(property);
+  auto value = android::base::GetProperty(property, "");
 
   int32_t time_in_ms;
   if (android::base::ParseInt(value, &time_in_ms)) {
@@ -1007,7 +991,7 @@
 
   // |ro.boot.boottime| is of the form 'stage1:time1,...,stageN:timeN',
   // where timeN is in milliseconds.
-  std::string value = GetProperty("ro.boot.boottime");
+  auto value = android::base::GetProperty("ro.boot.boottime", "");
   if (value.empty()) {
     // ro.boot.boottime is not reported on all devices.
     return BootloaderTimingMap();
@@ -1081,7 +1065,7 @@
 void LogBootInfoToStatsd(std::chrono::milliseconds end_time,
                          std::chrono::milliseconds total_duration, int32_t bootloader_duration_ms,
                          double time_since_last_boot_sec) {
-  const std::string reason(GetProperty(bootloader_reboot_reason_property));
+  const auto reason = android::base::GetProperty(bootloader_reboot_reason_property, "");
 
   if (reason.empty()) {
     android::util::stats_write(android::util::BOOT_SEQUENCE_REPORTED, "<EMPTY>", "<EMPTY>",
@@ -1091,7 +1075,7 @@
     return;
   }
 
-  const std::string system_reason(GetProperty(system_reboot_reason_property));
+  const auto system_reason = android::base::GetProperty(system_reboot_reason_property, "");
   android::util::stats_write(android::util::BOOT_SEQUENCE_REPORTED, reason.c_str(),
                              system_reason.c_str(), end_time.count(), total_duration.count(),
                              (int64_t)bootloader_duration_ms,
@@ -1099,19 +1083,20 @@
 }
 
 void SetSystemBootReason() {
-  const std::string bootloader_boot_reason(GetProperty(bootloader_reboot_reason_property));
+  const auto bootloader_boot_reason =
+      android::base::GetProperty(bootloader_reboot_reason_property, "");
   const std::string system_boot_reason(BootReasonStrToReason(bootloader_boot_reason));
   // Record the scrubbed system_boot_reason to the property
   BootReasonAddToHistory(system_boot_reason);
   // Shift last_reboot_reason_property to last_last_reboot_reason_property
-  std::string last_boot_reason(GetProperty(last_reboot_reason_property));
+  auto last_boot_reason = android::base::GetProperty(last_reboot_reason_property, "");
   if (last_boot_reason.empty() || isKernelRebootReason(system_boot_reason)) {
     last_boot_reason = system_boot_reason;
   } else {
     transformReason(last_boot_reason);
   }
-  SetProperty(last_last_reboot_reason_property, last_boot_reason);
-  SetProperty(last_reboot_reason_property, "");
+  android::base::SetProperty(last_last_reboot_reason_property, last_boot_reason);
+  android::base::SetProperty(last_reboot_reason_property, "");
 }
 
 // Gets the boot time offset. This is useful when Android is running in a
@@ -1198,7 +1183,7 @@
 // Records the boot_reason metric by querying the ro.boot.bootreason system
 // property.
 void RecordBootReason() {
-  const std::string reason(GetProperty(bootloader_reboot_reason_property));
+  const auto reason = android::base::GetProperty(bootloader_reboot_reason_property, "");
 
   if (reason.empty()) {
     // Log an empty boot reason value as '<EMPTY>' to ensure the value is intentional
@@ -1216,12 +1201,12 @@
   boot_event_store.AddBootEventWithValue("boot_reason", boot_reason);
 
   // Log the scrubbed system_boot_reason.
-  const std::string system_reason(GetProperty(system_reboot_reason_property));
+  const auto system_reason = android::base::GetProperty(system_reboot_reason_property, "");
   int32_t system_boot_reason = BootReasonStrToEnum(system_reason);
   boot_event_store.AddBootEventWithValue("system_boot_reason", system_boot_reason);
 
   if (reason == "") {
-    SetProperty(bootloader_reboot_reason_property, system_reason);
+    android::base::SetProperty(bootloader_reboot_reason_property, system_reason);
   }
 }
 
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index b508b56..df1e326 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -565,26 +565,6 @@
         if (!duplicate_or_more_specific) mounts.emplace_back(new_mount_point);
     }
 
-    // if not itemized /system or /, system as root, fake one up?
-
-    // do we want or need to?
-    if (mount_point && ("/system"s != mount_point)) return mounts;
-    if (std::find(mounts.begin(), mounts.end(), "/system") != mounts.end()) return mounts;
-
-    // fs_mgr_overlayfs_verity_enabled_list says not to?
-    if (std::find(verity.begin(), verity.end(), "system") != verity.end()) return mounts;
-
-    // confirm that fstab is missing system
-    if (GetEntryForMountPoint(fstab, "/") != nullptr ||
-        GetEntryForMountPoint(fstab, "/system") != nullptr) {
-        return mounts;
-    }
-
-    // We have a stunted fstab (w/o system or / ) passed in by the caller,
-    // verity claims are assumed accurate because they are collected internally
-    // from fs_mgr_fstab_default() from within fs_mgr_update_verity_state(),
-    // Can (re)evaluate /system with impunity since we know it is ever-present.
-    mounts.emplace_back("/system");
     return mounts;
 }
 
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 7d5bf57..1b077bc 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -157,6 +157,37 @@
     return fstab;
 }
 
+static bool GetRootEntry(FstabEntry* root_entry) {
+    Fstab proc_mounts;
+    if (!ReadFstabFromFile("/proc/mounts", &proc_mounts)) {
+        LOG(ERROR) << "Could not read /proc/mounts and /system not in fstab, /system will not be "
+                      "available for overlayfs";
+        return false;
+    }
+
+    auto entry = std::find_if(proc_mounts.begin(), proc_mounts.end(), [](const auto& entry) {
+        return entry.mount_point == "/" && entry.fs_type != "rootfs";
+    });
+
+    if (entry == proc_mounts.end()) {
+        LOG(ERROR) << "Could not get mount point for '/' in /proc/mounts, /system will not be "
+                      "available for overlayfs";
+        return false;
+    }
+
+    *root_entry = std::move(*entry);
+
+    // We don't know if we're avb or not, so we query device mapper as if we are avb.  If we get a
+    // success, then mark as avb, otherwise default to verify.
+    auto& dm = android::dm::DeviceMapper::Instance();
+    if (dm.GetState("vroot") != android::dm::DmDeviceState::INVALID) {
+        root_entry->fs_mgr_flags.avb = true;
+    } else {
+        root_entry->fs_mgr_flags.verify = true;
+    }
+    return true;
+}
+
 // Class Definitions
 // -----------------
 FirstStageMount::FirstStageMount(Fstab fstab)
@@ -443,7 +474,7 @@
 
     if (system_partition == fstab_.end()) return true;
 
-    if (MountPartition(system_partition, true /* erase_used_fstab_entry */)) {
+    if (MountPartition(system_partition, false)) {
         SwitchRoot("/system");
     } else {
         PLOG(ERROR) << "Failed to mount /system";
@@ -487,6 +518,12 @@
     if (!TrySkipMountingPartitions()) return false;
 
     for (auto current = fstab_.begin(); current != fstab_.end();) {
+        // We've already mounted /system above.
+        if (current->mount_point == "/system") {
+            ++current;
+            continue;
+        }
+
         Fstab::iterator end;
         if (!MountPartition(current, false, &end)) {
             if (current->fs_mgr_flags.no_fail) {
@@ -503,6 +540,15 @@
         current = end;
     }
 
+    // If we don't see /system or / in the fstab, then we need to create an root entry for
+    // overlayfs.
+    if (!GetEntryForMountPoint(&fstab_, "/system") && !GetEntryForMountPoint(&fstab_, "/")) {
+        FstabEntry root_entry;
+        if (GetRootEntry(&root_entry)) {
+            fstab_.emplace_back(std::move(root_entry));
+        }
+    }
+
     // heads up for instantiating required device(s) for overlayfs logic
     const auto devices = fs_mgr_overlayfs_required_devices(&fstab_);
     for (auto const& device : devices) {