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
gugelfrei
Zim 4 years ago
parent 6b12257702
commit b6488f3f04

@ -48,6 +48,7 @@ EmulatedVolume::EmulatedVolume(const std::string& rawPath, int userId)
mRawPath = rawPath; mRawPath = rawPath;
mLabel = "emulated"; mLabel = "emulated";
mFuseMounted = false; mFuseMounted = false;
mAndroidMounted = false;
mUseSdcardFs = IsFilesystemSupported("sdcardfs"); mUseSdcardFs = IsFilesystemSupported("sdcardfs");
mAppDataIsolationEnabled = base::GetBoolProperty(kVoldAppDataIsolationEnabled, false); mAppDataIsolationEnabled = base::GetBoolProperty(kVoldAppDataIsolationEnabled, false);
} }
@ -59,6 +60,7 @@ EmulatedVolume::EmulatedVolume(const std::string& rawPath, dev_t device, const s
mRawPath = rawPath; mRawPath = rawPath;
mLabel = fsUuid; mLabel = fsUuid;
mFuseMounted = false; mFuseMounted = false;
mAndroidMounted = false;
mUseSdcardFs = IsFilesystemSupported("sdcardfs"); mUseSdcardFs = IsFilesystemSupported("sdcardfs");
mAppDataIsolationEnabled = base::GetBoolProperty(kVoldAppDataIsolationEnabled, false); mAppDataIsolationEnabled = base::GetBoolProperty(kVoldAppDataIsolationEnabled, false);
} }
@ -87,6 +89,8 @@ static status_t doFuseBindMount(const std::string& source, const std::string& ta
} }
status_t EmulatedVolume::mountFuseBindMounts() { status_t EmulatedVolume::mountFuseBindMounts() {
CHECK(!mAndroidMounted);
std::string androidSource; std::string androidSource;
std::string label = getLabel(); std::string label = getLabel();
int userId = getMountUserId(); int userId = getMountUserId();
@ -109,6 +113,8 @@ status_t EmulatedVolume::mountFuseBindMounts() {
if (status != OK) { if (status != OK) {
return status; return status;
} }
mAndroidMounted = true;
// Installers get the same view as all other apps, with the sole exception that the // 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 // 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 // a special bind mount, since app-private and OBB dirs share the same GID, but we
@ -129,6 +135,8 @@ status_t EmulatedVolume::mountFuseBindMounts() {
} }
status_t EmulatedVolume::unmountFuseBindMounts() { status_t EmulatedVolume::unmountFuseBindMounts() {
CHECK(mAndroidMounted);
std::string label = getLabel(); std::string label = getLabel();
int userId = getMountUserId(); int userId = getMountUserId();
@ -158,7 +166,6 @@ status_t EmulatedVolume::unmountFuseBindMounts() {
} }
LOG(INFO) << "Unmounted " << androidTarget; LOG(INFO) << "Unmounted " << androidTarget;
} }
return OK; return OK;
} }
@ -297,7 +304,10 @@ status_t EmulatedVolume::doUnmount() {
// Ignoring unmount return status because we do want to try to unmount // Ignoring unmount return status because we do want to try to unmount
// the rest cleanly. // the rest cleanly.
unmountFuseBindMounts(); if (mAndroidMounted) {
unmountFuseBindMounts();
mAndroidMounted = false;
}
if (UnmountUserFuse(userId, getInternalPath(), label) != OK) { if (UnmountUserFuse(userId, getInternalPath(), label) != OK) {
PLOG(INFO) << "UnmountUserFuse failed on emulated fuse volume"; PLOG(INFO) << "UnmountUserFuse failed on emulated fuse volume";
return -errno; return -errno;

@ -63,6 +63,9 @@ class EmulatedVolume : public VolumeBase {
/* Whether we mounted FUSE for this volume */ /* Whether we mounted FUSE for this volume */
bool mFuseMounted; bool mFuseMounted;
/* Whether we mounted Android/ for this volume */
bool mAndroidMounted;
/* Whether to use sdcardfs for this volume */ /* Whether to use sdcardfs for this volume */
bool mUseSdcardFs; bool mUseSdcardFs;

Loading…
Cancel
Save