Fix vold wedge when unmounting Android/
In EmulatedVolume#doMount, if some operations fail, we call
EmulatedVolume#doUnmount.
During this unmount we try to unmount Android/ causing a FUSE_LOOKUP
on the FUSE mount. If the FUSE mount is not up, this can hang.
Now we introduce a new state to prevent unmounting Android/ if it
wasn't mounted.
Test: atest AdoptableHostTest
Bug: 151685786
Change-Id: I6246d3910c352034d2a4fb09ad9c1e7fd91cba5e
diff --git a/model/EmulatedVolume.cpp b/model/EmulatedVolume.cpp
index 02d5c37..b212c0e 100644
--- a/model/EmulatedVolume.cpp
+++ b/model/EmulatedVolume.cpp
@@ -48,6 +48,7 @@
mRawPath = rawPath;
mLabel = "emulated";
mFuseMounted = false;
+ mAndroidMounted = false;
mUseSdcardFs = IsFilesystemSupported("sdcardfs");
mAppDataIsolationEnabled = base::GetBoolProperty(kVoldAppDataIsolationEnabled, false);
}
@@ -59,6 +60,7 @@
mRawPath = rawPath;
mLabel = fsUuid;
mFuseMounted = false;
+ mAndroidMounted = false;
mUseSdcardFs = IsFilesystemSupported("sdcardfs");
mAppDataIsolationEnabled = base::GetBoolProperty(kVoldAppDataIsolationEnabled, false);
}
@@ -87,6 +89,8 @@
}
status_t EmulatedVolume::mountFuseBindMounts() {
+ CHECK(!mAndroidMounted);
+
std::string androidSource;
std::string label = getLabel();
int userId = getMountUserId();
@@ -109,6 +113,8 @@
if (status != OK) {
return status;
}
+ mAndroidMounted = true;
+
// Installers get the same view as all other apps, with the sole exception that the
// OBB dirs (Android/obb) are writable to them. On sdcardfs devices, this requires
// a special bind mount, since app-private and OBB dirs share the same GID, but we
@@ -129,6 +135,8 @@
}
status_t EmulatedVolume::unmountFuseBindMounts() {
+ CHECK(mAndroidMounted);
+
std::string label = getLabel();
int userId = getMountUserId();
@@ -158,7 +166,6 @@
}
LOG(INFO) << "Unmounted " << androidTarget;
}
-
return OK;
}
@@ -297,7 +304,10 @@
// Ignoring unmount return status because we do want to try to unmount
// the rest cleanly.
- unmountFuseBindMounts();
+ if (mAndroidMounted) {
+ unmountFuseBindMounts();
+ mAndroidMounted = false;
+ }
if (UnmountUserFuse(userId, getInternalPath(), label) != OK) {
PLOG(INFO) << "UnmountUserFuse failed on emulated fuse volume";
return -errno;