recovery: Map logical partitions before installation

Change-Id: I785b49086a2baf462e97be831b495d7db72f7a42
diff --git a/recovery_main.cpp b/recovery_main.cpp
index 303aa1d..ab27f11 100644
--- a/recovery_main.cpp
+++ b/recovery_main.cpp
@@ -593,7 +593,7 @@
       }
 
       case Device::ENTER_FASTBOOT:
-        if (android::fs_mgr::LogicalPartitionsMapped()) {
+        if (logical_partitions_mapped()) {
           ui->Print("Partitions may be mounted - rebooting to enter fastboot.");
           Reboot("fastboot");
         } else {
diff --git a/recovery_utils/include/recovery_utils/roots.h b/recovery_utils/include/recovery_utils/roots.h
index 96c53d4..783eea4 100644
--- a/recovery_utils/include/recovery_utils/roots.h
+++ b/recovery_utils/include/recovery_utils/roots.h
@@ -60,3 +60,5 @@
 
 // Returns true if there is /cache in the volumes.
 bool HasCache();
+
+bool logical_partitions_mapped();
\ No newline at end of file
diff --git a/recovery_utils/roots.cpp b/recovery_utils/roots.cpp
index 00a4b01..36deef5 100644
--- a/recovery_utils/roots.cpp
+++ b/recovery_utils/roots.cpp
@@ -39,6 +39,7 @@
 #include <ext4_utils/wipe.h>
 #include <fs_mgr.h>
 #include <fs_mgr/roots.h>
+#include <fs_mgr_dm_linear.h>
 
 #include "otautil/sysutil.h"
 
@@ -363,6 +364,8 @@
   return format_volume(volume, "");
 }
 
+static bool logical_partitions_auto_mapped = false;
+
 int setup_install_mounts() {
   if (fstab.empty()) {
     LOG(ERROR) << "can't set up install mounts: no fstab loaded";
@@ -386,6 +389,16 @@
       }
     }
   }
+  // Map logical partitions
+  if (android::base::GetBoolProperty("ro.boot.dynamic_partitions", false) &&
+      !logical_partitions_mapped()) {
+    std::string super_name = fs_mgr_get_super_partition_name();
+    if (!android::fs_mgr::CreateLogicalPartitions("/dev/block/by-name/" + super_name)) {
+      LOG(ERROR) << "Failed to map logical partitions";
+    } else {
+      logical_partitions_auto_mapped = true;
+    }
+  }
   return 0;
 }
 
@@ -394,3 +407,7 @@
   static bool has_cache = volume_for_mount_point(CACHE_ROOT) != nullptr;
   return has_cache;
 }
+
+bool logical_partitions_mapped() {
+  return android::fs_mgr::LogicalPartitionsMapped() || logical_partitions_auto_mapped;
+}