From b6488f3f0481e83f0685214b9dfabeef09f43af3 Mon Sep 17 00:00:00 2001 From: Zim Date: Tue, 17 Mar 2020 15:15:42 +0000 Subject: [PATCH] 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 --- model/EmulatedVolume.cpp | 14 ++++++++++++-- model/EmulatedVolume.h | 3 +++ 2 files changed, 15 insertions(+), 2 deletions(-) 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 @@ EmulatedVolume::EmulatedVolume(const std::string& rawPath, int userId) mRawPath = rawPath; mLabel = "emulated"; mFuseMounted = false; + mAndroidMounted = false; mUseSdcardFs = IsFilesystemSupported("sdcardfs"); mAppDataIsolationEnabled = base::GetBoolProperty(kVoldAppDataIsolationEnabled, false); } @@ -59,6 +60,7 @@ EmulatedVolume::EmulatedVolume(const std::string& rawPath, dev_t device, const s mRawPath = rawPath; mLabel = fsUuid; mFuseMounted = false; + mAndroidMounted = false; mUseSdcardFs = IsFilesystemSupported("sdcardfs"); 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() { + CHECK(!mAndroidMounted); + std::string androidSource; std::string label = getLabel(); int userId = getMountUserId(); @@ -109,6 +113,8 @@ status_t EmulatedVolume::mountFuseBindMounts() { 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::mountFuseBindMounts() { } status_t EmulatedVolume::unmountFuseBindMounts() { + CHECK(mAndroidMounted); + std::string label = getLabel(); int userId = getMountUserId(); @@ -158,7 +166,6 @@ status_t EmulatedVolume::unmountFuseBindMounts() { } LOG(INFO) << "Unmounted " << androidTarget; } - return OK; } @@ -297,7 +304,10 @@ status_t EmulatedVolume::doUnmount() { // 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; diff --git a/model/EmulatedVolume.h b/model/EmulatedVolume.h index b25fb7c..9bff0ca 100644 --- a/model/EmulatedVolume.h +++ b/model/EmulatedVolume.h @@ -63,6 +63,9 @@ class EmulatedVolume : public VolumeBase { /* Whether we mounted FUSE for this volume */ bool mFuseMounted; + /* Whether we mounted Android/ for this volume */ + bool mAndroidMounted; + /* Whether to use sdcardfs for this volume */ bool mUseSdcardFs;