diff --git a/Utils.cpp b/Utils.cpp index 15a5e49..e3a419f 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -1330,6 +1330,21 @@ bool writeStringToFile(const std::string& payload, const std::string& filename) return true; } +status_t AbortFuseConnections() { + namespace fs = std::filesystem; + + for (const auto& itEntry : fs::directory_iterator("/sys/fs/fuse/connections")) { + std::string abortPath = itEntry.path().string() + "/abort"; + LOG(DEBUG) << "Aborting fuse connection entry " << abortPath; + bool ret = writeStringToFile("1", abortPath); + if (!ret) { + LOG(WARNING) << "Failed to write to " << abortPath; + } + } + + return OK; +} + status_t EnsureDirExists(const std::string& path, mode_t mode, uid_t uid, gid_t gid) { if (access(path.c_str(), F_OK) != 0) { PLOG(WARNING) << "Dir does not exist: " << path; diff --git a/Utils.h b/Utils.h index eac3cf4..c4926e7 100644 --- a/Utils.h +++ b/Utils.h @@ -50,6 +50,8 @@ extern bool sSleepOnUnmount; status_t CreateDeviceNode(const std::string& path, dev_t dev); status_t DestroyDeviceNode(const std::string& path); +status_t AbortFuseConnections(); + int SetQuotaInherit(const std::string& path); int SetQuotaProjectId(const std::string& path, long projectId); /* diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp index 1020526..a37ba5a 100644 --- a/VoldNativeService.cpp +++ b/VoldNativeService.cpp @@ -175,6 +175,13 @@ binder::Status VoldNativeService::shutdown() { return translate(VolumeManager::Instance()->shutdown()); } +binder::Status VoldNativeService::abortFuse() { + ENFORCE_SYSTEM_OR_ROOT; + ACQUIRE_LOCK; + + return translate(VolumeManager::Instance()->abortFuse()); +} + binder::Status VoldNativeService::onUserAdded(int32_t userId, int32_t userSerial) { ENFORCE_SYSTEM_OR_ROOT; ACQUIRE_LOCK; diff --git a/VoldNativeService.h b/VoldNativeService.h index 060d704..c7d8849 100644 --- a/VoldNativeService.h +++ b/VoldNativeService.h @@ -36,6 +36,7 @@ class VoldNativeService : public BinderService, public os::Bn binder::Status monitor(); binder::Status reset(); binder::Status shutdown(); + binder::Status abortFuse(); binder::Status onUserAdded(int32_t userId, int32_t userSerial); binder::Status onUserRemoved(int32_t userId); diff --git a/VolumeManager.cpp b/VolumeManager.cpp index f42f3e7..a543573 100644 --- a/VolumeManager.cpp +++ b/VolumeManager.cpp @@ -905,6 +905,10 @@ int VolumeManager::remountAppStorageDirs(int uid, int pid, return 0; } +int VolumeManager::abortFuse() { + return android::vold::AbortFuseConnections(); +} + int VolumeManager::reset() { // Tear down all existing disks/volumes and start from a blank slate so // newly connected framework hears all events. @@ -940,6 +944,7 @@ int VolumeManager::shutdown() { mDisks.clear(); mPendingDisks.clear(); android::vold::sSleepOnUnmount = true; + return 0; } diff --git a/VolumeManager.h b/VolumeManager.h index a9087fd..3277f75 100644 --- a/VolumeManager.h +++ b/VolumeManager.h @@ -120,6 +120,8 @@ class VolumeManager { int remountUid(uid_t uid, int32_t remountMode); int remountAppStorageDirs(int uid, int pid, const std::vector& packageNames); + /* Aborts all FUSE filesystems, in case the FUSE daemon is no longer up. */ + int abortFuse(); /* Reset all internal state, typically during framework boot */ int reset(); /* Prepare for device shutdown, safely unmounting all devices */ diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl index 68e2ba9..6d14959 100644 --- a/binder/android/os/IVold.aidl +++ b/binder/android/os/IVold.aidl @@ -25,6 +25,7 @@ import android.os.IVoldTaskListener; interface IVold { void setListener(IVoldListener listener); + void abortFuse(); void monitor(); void reset(); void shutdown(); diff --git a/vdc.cpp b/vdc.cpp index a6a3fb0..c0b798d 100644 --- a/vdc.cpp +++ b/vdc.cpp @@ -99,6 +99,8 @@ int main(int argc, char** argv) { checkStatus(args, vold->fdeEnable(passwordType, "", encryptionFlags)); } else if (args[0] == "cryptfs" && args[1] == "mountdefaultencrypted") { checkStatus(args, vold->mountDefaultEncrypted()); + } else if (args[0] == "volume" && args[1] == "abort_fuse") { + checkStatus(args, vold->abortFuse()); } else if (args[0] == "volume" && args[1] == "shutdown") { checkStatus(args, vold->shutdown()); } else if (args[0] == "volume" && args[1] == "reset") {