summaryrefslogtreecommitdiff
path: root/incfs/MountRegistry.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'incfs/MountRegistry.cpp')
-rw-r--r--incfs/MountRegistry.cpp45
1 files changed, 36 insertions, 9 deletions
diff --git a/incfs/MountRegistry.cpp b/incfs/MountRegistry.cpp
index b7b53c8..4f16f73 100644
--- a/incfs/MountRegistry.cpp
+++ b/incfs/MountRegistry.cpp
@@ -302,6 +302,25 @@ static bool forEachLine(base::borrowed_fd fd, Callback&& cb) {
return true;
}
+static std::string fixBackingDir(std::string_view dir, std::string_view mountDir) {
+ if (!dir.starts_with("/proc/"sv)) {
+ return std::string(dir);
+ }
+
+ // HACK:
+ // Vold uses a secure way of mounting incremental storages, where it passes in
+ // a virtual symlink in /proc/self/fd/... instead of the original path. Unfortunately,
+ // this symlink string gets preserved by the system and we can't resolve it later.
+ // But it's the only place that uses this symlink, and we know exactly how the
+ // mount and backing directory paths look in that case - so can recover one from
+ // another.
+ if (path::endsWith(mountDir, "mount"sv)) {
+ return path::join(path::dirName(mountDir), "backing_store"sv);
+ }
+ // Well, hack didn't work. Still may not return a /proc/ path
+ return {};
+}
+
bool MountRegistry::Mounts::loadFrom(base::borrowed_fd fd, std::string_view filesystem) {
struct MountInfo {
std::string backing;
@@ -327,19 +346,21 @@ bool MountRegistry::Mounts::loadFrom(base::borrowed_fd fd, std::string_view file
}
const auto groupId = items[2];
auto subdir = items[3];
- auto backingDir = items.rbegin()[1];
auto mountPoint = std::string(items[4]);
fixProcPath(mountPoint);
mountPoint = path::normalize(mountPoint);
auto& mount = mountsByGroup[std::string(groupId)];
- if (mount.backing.empty()) {
- mount.backing.assign(backingDir);
- } else if (mount.backing != backingDir) {
- LOG(WARNING) << "[incfs] root '" << *mount.roots.begin()
- << "' mounted in multiple places with different backing dirs, '"
- << mount.backing << "' vs new '" << backingDir
- << "'; updating to the new one";
- mount.backing.assign(backingDir);
+ auto backingDir = fixBackingDir(items.rbegin()[1], mountPoint);
+ if (!backingDir.empty()) {
+ if (mount.backing.empty()) {
+ mount.backing = std::move(backingDir);
+ } else if (mount.backing != backingDir) {
+ LOG(WARNING) << "[incfs] root '" << *mount.roots.begin()
+ << "' mounted in multiple places with different backing dirs, '"
+ << mount.backing << "' vs new '" << backingDir
+ << "'; updating to the new one";
+ mount.backing = std::move(backingDir);
+ }
}
if (subdir == "/"sv) {
mount.roots.emplace(mountPoint);
@@ -368,6 +389,12 @@ bool MountRegistry::Mounts::loadFrom(base::borrowed_fd fd, std::string_view file
<< mount.bindPoints.size() << " bind(s), ignoring";
continue;
}
+ if (mount.backing.empty()) {
+ LOG(WARNING) << "[incfs] mount '" << *mount.roots.begin()
+ << "' has no backing dir, but " << mount.bindPoints.size()
+ << " bind(s), ignoring";
+ continue;
+ }
Root& root = roots[index];
auto& binds = root.binds;