OtaPreopt: Add support for logical partitions

Use logical partitions prepared by update_engine if possible.

Bug: 128867786
Test: DexOptOtaTests
Change-Id: I6979487b91d24b7309c876f2bdc26a827e2fcd1e
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index 2211a9c..2e2cc18 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -25,6 +25,7 @@
 #include <android-base/logging.h>
 #include <android-base/macros.h>
 #include <android-base/stringprintf.h>
+#include <libdm/dm.h>
 #include <selinux/android.h>
 
 #include <apexd.h>
@@ -78,7 +79,28 @@
 }
 
 static void TryExtraMount(const char* name, const char* slot, const char* target) {
-    std::string block_device = StringPrintf("/dev/block/by-name/%s%s", name, slot);
+    std::string partition_name = StringPrintf("%s%s", name, slot);
+
+    // See whether update_engine mounted a logical partition.
+    {
+        auto& dm = dm::DeviceMapper::Instance();
+        if (dm.GetState(partition_name) != dm::DmDeviceState::INVALID) {
+            std::string path;
+            if (dm.GetDmDevicePathByName(partition_name, &path)) {
+                int mount_result = mount(path.c_str(),
+                                         target,
+                                         "ext4",
+                                         MS_RDONLY,
+                                         /* data */ nullptr);
+                if (mount_result == 0) {
+                    return;
+                }
+            }
+        }
+    }
+
+    // Fall back and attempt a direct mount.
+    std::string block_device = StringPrintf("/dev/block/by-name/%s", partition_name.c_str());
     int mount_result = mount(block_device.c_str(),
                              target,
                              "ext4",