OverlayFS support for fstab

Add overlayfs (lowerdir) mount entry support to fstab.

  overlay  <final dir>  overlay lowerdir=/1:/2

E.g.
  overlay /vendor overlay lowerdir=/odm/vnd_ovl1/1:/odm/vnd_ovl2

Test: Ensure mounting with fstab overlayfs entry
Change-Id: Ib025e203f8ac1836ab62dfa96fb14e8e108f82fb
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 42bf356..853b24d 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -298,6 +298,8 @@
             if (!ParseByteCount(arg, &entry->zram_backingdev_size)) {
                 LWARNING << "Warning: zram_backingdev_size= flag malformed: " << arg;
             }
+        } else if (StartsWith(flag, "lowerdir=")) {
+            entry->lowerdir = arg;
         } else {
             LWARNING << "Warning: unknown flag: " << flag;
         }
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index cb09383..9a94d79 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -92,6 +92,10 @@
     return false;
 }
 
+bool fs_mgr_overlayfs_mount_fstab_entry(const std::string&, const std::string&) {
+    return false;
+}
+
 std::vector<std::string> fs_mgr_overlayfs_required_devices(Fstab*) {
     return {};
 }
@@ -1295,6 +1299,18 @@
     }
 }
 
+bool fs_mgr_overlayfs_mount_fstab_entry(const std::string& lowers,
+                                        const std::string& mount_point) {
+    if (fs_mgr_overlayfs_invalid()) return false;
+
+    std::string aux = "lowerdir=" + lowers + ",override_creds=off";
+    auto rc = mount("overlay", mount_point.c_str(), "overlay", MS_RDONLY | MS_NOATIME, aux.c_str());
+
+    if (rc == 0) return true;
+
+    return false;
+}
+
 bool fs_mgr_overlayfs_mount_all(Fstab* fstab) {
     auto ret = false;
     if (fs_mgr_overlayfs_invalid()) return ret;
diff --git a/fs_mgr/include/fs_mgr_overlayfs.h b/fs_mgr/include/fs_mgr_overlayfs.h
index d45e2de..ac95ef5 100644
--- a/fs_mgr/include/fs_mgr_overlayfs.h
+++ b/fs_mgr/include/fs_mgr_overlayfs.h
@@ -27,6 +27,7 @@
 android::fs_mgr::Fstab fs_mgr_overlayfs_candidate_list(const android::fs_mgr::Fstab& fstab);
 
 bool fs_mgr_overlayfs_mount_all(android::fs_mgr::Fstab* fstab);
+bool fs_mgr_overlayfs_mount_fstab_entry (const std::string& lowers, const std::string& mount_point);
 std::vector<std::string> fs_mgr_overlayfs_required_devices(android::fs_mgr::Fstab* fstab);
 bool fs_mgr_overlayfs_setup(const char* backing = nullptr, const char* mount_point = nullptr,
                             bool* change = nullptr, bool force = true);
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
index 2704e47..f33768b 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -55,6 +55,7 @@
     std::string vbmeta_partition;
     uint64_t zram_backingdev_size = 0;
     std::string avb_keys;
+    std::string lowerdir;
 
     struct FsMgrFlags {
         bool wait : 1;
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 3faf430..a733839 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -331,6 +331,12 @@
     if (devices.empty()) {
         return true;
     }
+    // excluding overlays
+    for (auto iter = devices.begin(); iter != devices.end(); ) {
+        if (*iter=="overlay")  iter = devices.erase(iter);
+        else iter++;
+    }
+
     return block_dev_init_.InitDevices(std::move(devices));
 }
 
@@ -542,6 +548,11 @@
             continue;
         }
 
+        if (current->fs_type == "overlay") {
+            ++current;
+            continue;
+        }
+
         // Skip raw partition entries such as boot, dtbo, etc.
         // Having emmc fstab entries allows us to probe current->vbmeta_partition
         // in InitDevices() when they are AVB chained partitions.
@@ -591,6 +602,13 @@
     };
     MapScratchPartitionIfNeeded(&fstab_, init_devices);
 
+    for (auto current = fstab_.begin(); current != fstab_.end(); ) {
+        if (current->fs_type == "overlay") {
+            fs_mgr_overlayfs_mount_fstab_entry(current->lowerdir, current->mount_point);
+        }
+        ++current;
+    }
+
     fs_mgr_overlayfs_mount_all(&fstab_);
 
     return true;