recovery: mount with ensure_path_mounted_at() am: 73a84acc5e
am: db89d287b8

Change-Id: I3371d0a31e6133ece456ed6c528b5dddd5797c8c
diff --git a/VintfObjectRecovery.cpp b/VintfObjectRecovery.cpp
index ce76c07..b2a9e8a 100644
--- a/VintfObjectRecovery.cpp
+++ b/VintfObjectRecovery.cpp
@@ -17,69 +17,43 @@
 #include "VintfObjectRecovery.h"
 
 #include <sys/mount.h>
-#include <sys/stat.h>
 
 #include <set>
 
 #include <android-base/logging.h>
 #include <android-base/strings.h>
 #include <fs_mgr.h>
-
-#include "utils.h"
+#include <fs_mgr/roots.h>
 
 namespace android {
 namespace vintf {
 
 namespace details {
 using android::base::StartsWith;
-using FstabMgr = std::unique_ptr<struct fstab, decltype(&fs_mgr_free_fstab)>;
 
 static const char* const kMountImageRootDir = "/mnt";
 static const char* const kSystemImageRootDir = "/mnt/system";
 
-static status_t mountAt(const FstabMgr& fstab, const char* path, const char* mountPoint) {
-    mkdir(mountPoint, 0755);  // in case it doesn't already exist
-
-    fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab.get(), path);
-    if (rec == nullptr) {
-        LOG(WARNING) << "No mount point for " << path;
-        return NAME_NOT_FOUND;
-    }
-    int result = mount(rec->blk_device, mountPoint, rec->fs_type, rec->flags, rec->fs_options);
-    if (result != 0) {
-        PLOG(WARNING) << "Can't mount " << path;
-    }
-    return result == 0 ? OK : -errno;
-}
-
-static FstabMgr defaultFstabMgr() {
-    return FstabMgr{fs_mgr_read_fstab_default(), &fs_mgr_free_fstab};
-}
-
 class RecoveryPartitionMounter {
    public:
-    RecoveryPartitionMounter() : fstab_(defaultFstabMgr()) {}
+    RecoveryPartitionMounter() {}
     ~RecoveryPartitionMounter() {
         for (const auto& pair : mounted_) {
-            umount(pair.second.c_str());
+            if (umount(pair.second.c_str()) != 0) {
+                PLOG(ERROR) << "Cannot unmount " << pair.first << " at " << pair.second;
+            }
         }
         mounted_.clear();
     }
 
     status_t mount(const std::string& path) {
         if (path == "/system") {
-            if (!fstab_) return UNKNOWN_ERROR;
-            if (fs_mgr_get_entry_for_mount_point(fstab_.get(), "/system") == nullptr) {
-                return mount("/", kSystemImageRootDir);
-            } else {
-                return mount("/system", kSystemImageRootDir);
-            }
+            return mount(android::fs_mgr::GetSystemRoot(), kSystemImageRootDir);
         }
         return mount(path, kMountImageRootDir + path);
     }
 
    private:
-    FstabMgr fstab_;
     std::map<std::string, std::string> mounted_;
 
     status_t mount(const std::string& path, const std::string& mountPoint) {
@@ -87,12 +61,16 @@
             return OK;
         }
 
-        if (!fstab_) return UNKNOWN_ERROR;
-        status_t status = mountAt(fstab_, path.c_str(), mountPoint.c_str());
-        if (status == OK) {
-            mounted_.emplace(path, mountPoint);
+        Fstab fstab;
+        if (!ReadDefaultFstab(&fstab)) {
+            return errno ? -errno : UNKNOWN_ERROR;
         }
-        return status;
+        if (!android::fs_mgr::EnsurePathMounted(&fstab, path, mountPoint)) {
+            return errno ? -errno : UNKNOWN_ERROR;
+        }
+
+        mounted_.emplace(path, mountPoint);
+        return OK;
     }
 };
 
diff --git a/test/Android.bp b/test/Android.bp
index 0535b23..255ed14 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -92,6 +92,11 @@
         "libvintf",
         "libhidl-gen-utils",
         "libfs_mgr",
+        "liblp",
+        "libcrypto",
+        "libcrypto_utils",
+        "libext4_utils",
+        "libcutils",
         "libgtest",
         "libbase",
         "liblog",
diff --git a/test/VintfObjectRecoveryTest.cpp b/test/VintfObjectRecoveryTest.cpp
index d7a4367..023f0be 100644
--- a/test/VintfObjectRecoveryTest.cpp
+++ b/test/VintfObjectRecoveryTest.cpp
@@ -14,23 +14,46 @@
  * limitations under the License.
  */
 
-#include <gtest/gtest.h>
+#include <dirent.h>
+
+#include <memory>
 
 #include <android-base/logging.h>
+#include <gtest/gtest.h>
 #include <vintf/VintfObjectRecovery.h>
 
 namespace android {
 namespace vintf {
 
+bool directoryEmpty(const char* path) {
+    auto dir = std::unique_ptr<DIR, decltype(&closedir)>(opendir(path), &closedir);
+    if (!dir) return true;
+    for (struct dirent* dirent; (dirent = readdir(dir.get())) != nullptr;) {
+        if (strcmp(dirent->d_name, ".") == 0) continue;
+        if (strcmp(dirent->d_name, "..") == 0) continue;
+        LOG(ERROR) << "Seen: " << path << "/" << dirent->d_name;
+        return false;
+    }
+    return true;
+}
+
 struct VintfObjectRecoveryTest : public ::testing::Test {};
 
 TEST_F(VintfObjectRecoveryTest, LoadAllVintf) {
     std::string error;
     ASSERT_EQ(COMPATIBLE, VintfObjectRecovery::CheckCompatibility({}, &error)) << error;
 
+    EXPECT_TRUE(directoryEmpty("/mnt/system"));
+    EXPECT_TRUE(directoryEmpty("/mnt/vendor"));
+    EXPECT_TRUE(directoryEmpty("/mnt/odm"));
+
     ASSERT_EQ(COMPATIBLE, VintfObjectRecovery::CheckCompatibility({}, &error))
         << "Second CheckCompatibility call should still be successful because all "
-        << "partitions should already be mounted, but error: " << error;
+        << "partitions should already be unmounted, but error: " << error;
+
+    EXPECT_TRUE(directoryEmpty("/mnt/system"));
+    EXPECT_TRUE(directoryEmpty("/mnt/vendor"));
+    EXPECT_TRUE(directoryEmpty("/mnt/odm"));
 }
 
 }  // namespace vintf