Merge "Detect the absence of the default fstab"
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index de72f23..a11bb28 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -44,6 +44,7 @@
 
 #include "block_dev_initializer.h"
 #include "devices.h"
+#include "result.h"
 #include "snapuserd_transition.h"
 #include "switch_root.h"
 #include "uevent.h"
@@ -51,6 +52,7 @@
 #include "util.h"
 
 using android::base::ReadFileToString;
+using android::base::Result;
 using android::base::Split;
 using android::base::StringPrintf;
 using android::base::Timer;
@@ -81,7 +83,7 @@
 
     // The factory method to create either FirstStageMountVBootV1 or FirstStageMountVBootV2
     // based on device tree configurations.
-    static std::unique_ptr<FirstStageMount> Create();
+    static Result<std::unique_ptr<FirstStageMount>> Create();
     bool DoCreateDevices();    // Creates devices and logical partitions from storage devices
     bool DoFirstStageMount();  // Mounts fstab entries read from device tree.
     bool InitDevices();
@@ -160,7 +162,7 @@
     return is_android_dt_value_expected("vbmeta/compatible", "android,vbmeta");
 }
 
-static Fstab ReadFirstStageFstab() {
+static Result<Fstab> ReadFirstStageFstab() {
     Fstab fstab;
     if (!ReadFstabFromDt(&fstab)) {
         if (ReadDefaultFstab(&fstab)) {
@@ -170,7 +172,7 @@
                                        }),
                         fstab.end());
         } else {
-            LOG(INFO) << "Failed to fstab for first stage mount";
+            return Error() << "failed to read default fstab for first stage mount";
         }
     }
     return fstab;
@@ -236,12 +238,16 @@
     super_partition_name_ = fs_mgr_get_super_partition_name();
 }
 
-std::unique_ptr<FirstStageMount> FirstStageMount::Create() {
+Result<std::unique_ptr<FirstStageMount>> FirstStageMount::Create() {
     auto fstab = ReadFirstStageFstab();
-    if (IsDtVbmetaCompatible(fstab)) {
-        return std::make_unique<FirstStageMountVBootV2>(std::move(fstab));
+    if (!fstab.ok()) {
+        return fstab.error();
+    }
+
+    if (IsDtVbmetaCompatible(*fstab)) {
+        return std::make_unique<FirstStageMountVBootV2>(std::move(*fstab));
     } else {
-        return std::make_unique<FirstStageMountVBootV1>(std::move(fstab));
+        return std::make_unique<FirstStageMountVBootV1>(std::move(*fstab));
     }
 }
 
@@ -836,12 +842,12 @@
 // ----------------
 // Creates devices and logical partitions from storage devices
 bool DoCreateDevices() {
-    std::unique_ptr<FirstStageMount> handle = FirstStageMount::Create();
-    if (!handle) {
-        LOG(ERROR) << "Failed to create FirstStageMount";
+    auto fsm = FirstStageMount::Create();
+    if (!fsm.ok()) {
+        LOG(ERROR) << "Failed to create FirstStageMount: " << fsm.error();
         return false;
     }
-    return handle->DoCreateDevices();
+    return (*fsm)->DoCreateDevices();
 }
 
 // Mounts partitions specified by fstab in device tree.
@@ -852,17 +858,17 @@
         return true;
     }
 
-    std::unique_ptr<FirstStageMount> handle = FirstStageMount::Create();
-    if (!handle) {
-        LOG(ERROR) << "Failed to create FirstStageMount";
+    auto fsm = FirstStageMount::Create();
+    if (!fsm.ok()) {
+        LOG(ERROR) << "Failed to create FirstStageMount " << fsm.error();
         return false;
     }
 
     if (create_devices) {
-        if (!handle->DoCreateDevices()) return false;
+        if (!(*fsm)->DoCreateDevices()) return false;
     }
 
-    return handle->DoFirstStageMount();
+    return (*fsm)->DoFirstStageMount();
 }
 
 void SetInitAvbVersionInRecovery() {
@@ -872,8 +878,12 @@
     }
 
     auto fstab = ReadFirstStageFstab();
+    if (!fstab.ok()) {
+        LOG(ERROR) << fstab.error();
+        return;
+    }
 
-    if (!IsDtVbmetaCompatible(fstab)) {
+    if (!IsDtVbmetaCompatible(*fstab)) {
         LOG(INFO) << "Skipped setting INIT_AVB_VERSION (not vbmeta compatible)";
         return;
     }
@@ -883,7 +893,7 @@
     // We only set INIT_AVB_VERSION when the AVB verification succeeds, i.e., the
     // Open() function returns a valid handle.
     // We don't need to mount partitions here in recovery mode.
-    FirstStageMountVBootV2 avb_first_mount(std::move(fstab));
+    FirstStageMountVBootV2 avb_first_mount(std::move(*fstab));
     if (!avb_first_mount.InitDevices()) {
         LOG(ERROR) << "Failed to init devices for INIT_AVB_VERSION";
         return;