roots: volume_for_path() parses and tries prefixes.

Commit cc323958f99e40fea06c511656c69c0b2e2d47f7 in system/core has
changed fs_mgr_get_entry_for_mount_point() to do an exact match only,
which breaks the behavior in volume_for_path().

This CL changes the volume_for_path() implementation to parse and pass
prefixes locally. For a given path like "/cache/recovery/last_log", it
will in turn attempt the prefixes of "/cache/recovery/last_log",
"/cache/recovery", "/cache", "/" and return the first hit.

Bug: 63912287
Test: Build and boot into recovery image on bullhead. 'View recovery
      logs' works.
Change-Id: Ic8635b0939649dd5cc9ca501ebc3a2d1fbf5849d
diff --git a/roots.cpp b/roots.cpp
index fdcbfe8..835a1dd 100644
--- a/roots.cpp
+++ b/roots.cpp
@@ -68,8 +68,27 @@
   printf("\n");
 }
 
+// Finds the volume specified by the given path. fs_mgr_get_entry_for_mount_point() does exact match
+// only, so it attempts the prefixes recursively (e.g. "/cache/recovery/last_log",
+// "/cache/recovery", "/cache", "/" for a given path of "/cache/recovery/last_log") and returns the
+// first match or nullptr.
 Volume* volume_for_path(const char* path) {
-  return fs_mgr_get_entry_for_mount_point(fstab, path);
+  if (path == nullptr || path[0] == '\0') return nullptr;
+  std::string str(path);
+  while (true) {
+    Volume* result = fs_mgr_get_entry_for_mount_point(fstab, str.c_str());
+    if (result != nullptr || str == "/") {
+      return result;
+    }
+    size_t slash = str.find_last_of('/');
+    if (slash == std::string::npos) return nullptr;
+    if (slash == 0) {
+      str = "/";
+    } else {
+      str = str.substr(0, slash);
+    }
+  }
+  return nullptr;
 }
 
 // Mount the volume specified by path at the given mount_point.