From 82e90de23d0ee47e785307e77c5ab0ba9a4de26f Mon Sep 17 00:00:00 2001 From: Risan Date: Tue, 4 Feb 2020 16:07:21 +0900 Subject: [PATCH] Add disk for StubVolume StubVolume is a volume type for ARC++ external storage. Named StubVolume because it is managed from outside Android (not through Android kernel). Previously, StubVolume is a diskless volume. However, as mentioned in jsharkey@ email, a disk is needed for StubVolume to hold "kInternal" (external storage type that is "external" from Android perspective, but is "internal" to the device. For example shared directory from ChromeOS to Android) and "kIndexable" (whether or not a disk should be indexed by MediaStore). The addition of disk means we could expose the createStubVolume API to add a disk flags, which is also introduced in this CL. Both kInternal and kIndexable will be introduced in separate CL. Bug: 132796154 Test: Mount/unmount ARC++ removable device in ChromeOS. Change-Id: I8b77fa1cf50ab38a2892272154dafdb78f079378 --- VoldNativeService.cpp | 13 +++++++---- VoldNativeService.h | 3 ++- VolumeManager.cpp | 44 ++++++++++++++++-------------------- VolumeManager.h | 5 ++-- binder/android/os/IVold.aidl | 2 +- model/Disk.cpp | 19 ++++++++++++++++ model/Disk.h | 8 +++++++ model/StubVolume.cpp | 6 +++-- model/StubVolume.h | 2 +- 9 files changed, 64 insertions(+), 38 deletions(-) diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp index 3643c74..d648ebc 100644 --- a/VoldNativeService.cpp +++ b/VoldNativeService.cpp @@ -488,9 +488,12 @@ binder::Status VoldNativeService::destroyObb(const std::string& volId) { return translate(VolumeManager::Instance()->destroyObb(volId)); } -binder::Status VoldNativeService::createStubVolume( - const std::string& sourcePath, const std::string& mountPath, const std::string& fsType, - const std::string& fsUuid, const std::string& fsLabel, std::string* _aidl_return) { +binder::Status VoldNativeService::createStubVolume(const std::string& sourcePath, + const std::string& mountPath, + const std::string& fsType, + const std::string& fsUuid, + const std::string& fsLabel, int32_t flags, + std::string* _aidl_return) { ENFORCE_SYSTEM_OR_ROOT; CHECK_ARGUMENT_PATH(sourcePath); CHECK_ARGUMENT_PATH(mountPath); @@ -499,8 +502,8 @@ binder::Status VoldNativeService::createStubVolume( // is quite meaningless. ACQUIRE_LOCK; - return translate(VolumeManager::Instance()->createStubVolume(sourcePath, mountPath, fsType, - fsUuid, fsLabel, _aidl_return)); + return translate(VolumeManager::Instance()->createStubVolume( + sourcePath, mountPath, fsType, fsUuid, fsLabel, flags, _aidl_return)); } binder::Status VoldNativeService::destroyStubVolume(const std::string& volId) { diff --git a/VoldNativeService.h b/VoldNativeService.h index 7de2a67..a276de3 100644 --- a/VoldNativeService.h +++ b/VoldNativeService.h @@ -74,7 +74,8 @@ class VoldNativeService : public BinderService, public os::Bn binder::Status createStubVolume(const std::string& sourcePath, const std::string& mountPath, const std::string& fsType, const std::string& fsUuid, - const std::string& fsLabel, std::string* _aidl_return); + const std::string& fsLabel, int32_t flags, + std::string* _aidl_return); binder::Status destroyStubVolume(const std::string& volId); binder::Status fstrim(int32_t fstrimFlags, diff --git a/VolumeManager.cpp b/VolumeManager.cpp index 4427c9b..7be5e4f 100644 --- a/VolumeManager.cpp +++ b/VolumeManager.cpp @@ -114,7 +114,7 @@ VolumeManager* VolumeManager::Instance() { VolumeManager::VolumeManager() { mDebug = false; mNextObbId = 0; - mNextStubVolumeId = 0; + mNextStubId = 0; // For security reasons, assume that a secure keyguard is // showing until we hear otherwise mSecureKeyguardShowing = true; @@ -340,11 +340,6 @@ std::shared_ptr VolumeManager::findVolume(const std:: return vol; } } - for (const auto& vol : mStubVolumes) { - if (vol->getId() == id) { - return vol; - } - } for (const auto& vol : mObbVolumes) { if (vol->getId() == id) { return vol; @@ -767,7 +762,6 @@ int VolumeManager::shutdown() { } mInternalEmulatedVolumes.clear(); - mStubVolumes.clear(); mDisks.clear(); mPendingDisks.clear(); android::vold::sSleepOnUnmount = true; @@ -782,9 +776,6 @@ int VolumeManager::unmountAll() { for (const auto& vol : mInternalEmulatedVolumes) { vol->unmount(); } - for (const auto& stub : mStubVolumes) { - stub->unmount(); - } for (const auto& disk : mDisks) { disk->unmountAll(); } @@ -941,27 +932,30 @@ int VolumeManager::destroyObb(const std::string& volId) { int VolumeManager::createStubVolume(const std::string& sourcePath, const std::string& mountPath, const std::string& fsType, const std::string& fsUuid, - const std::string& fsLabel, std::string* outVolId) { - int id = mNextStubVolumeId++; - auto vol = std::shared_ptr( - new android::vold::StubVolume(id, sourcePath, mountPath, fsType, fsUuid, fsLabel)); - vol->create(); + const std::string& fsLabel, int32_t flags __unused, + std::string* outVolId) { + dev_t stubId = --mNextStubId; + auto vol = std::shared_ptr( + new android::vold::StubVolume(stubId, sourcePath, mountPath, fsType, fsUuid, fsLabel)); - mStubVolumes.push_back(vol); + // TODO (b/132796154): Passed each supported flags explicitly here. + // StubDisk doesn't have device node corresponds to it. So, a fake device + // number is used. The supported flags will be infered from the + // currently-unused flags parameter. + auto disk = std::shared_ptr( + new android::vold::Disk("stub", stubId, "stub", android::vold::Disk::Flags::kStub)); + disk->initializePartition(vol); + handleDiskAdded(disk); *outVolId = vol->getId(); return android::OK; } int VolumeManager::destroyStubVolume(const std::string& volId) { - auto i = mStubVolumes.begin(); - while (i != mStubVolumes.end()) { - if ((*i)->getId() == volId) { - (*i)->destroy(); - i = mStubVolumes.erase(i); - } else { - ++i; - } - } + auto tokens = android::base::Split(volId, ":"); + CHECK(tokens.size() == 2); + dev_t stubId; + CHECK(android::base::ParseUint(tokens[1], &stubId)); + handleDiskRemoved(stubId); return android::OK; } diff --git a/VolumeManager.h b/VolumeManager.h index eb48736..992b6dc 100644 --- a/VolumeManager.h +++ b/VolumeManager.h @@ -163,7 +163,7 @@ class VolumeManager { int createStubVolume(const std::string& sourcePath, const std::string& mountPath, const std::string& fsType, const std::string& fsUuid, - const std::string& fsLabel, std::string* outVolId); + const std::string& fsLabel, int32_t flags, std::string* outVolId); int destroyStubVolume(const std::string& volId); int mountAppFuse(uid_t uid, int mountId, android::base::unique_fd* device_fd); @@ -192,7 +192,6 @@ class VolumeManager { std::list> mDisks; std::list> mPendingDisks; std::list> mObbVolumes; - std::list> mStubVolumes; std::list> mInternalEmulatedVolumes; std::unordered_map mAddedUsers; @@ -205,7 +204,7 @@ class VolumeManager { std::shared_ptr mPrimary; int mNextObbId; - int mNextStubVolumeId; + int mNextStubId; bool mSecureKeyguardShowing; }; diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl index f1e463a..d4a55c8 100644 --- a/binder/android/os/IVold.aidl +++ b/binder/android/os/IVold.aidl @@ -125,7 +125,7 @@ interface IVold { @utf8InCpp String createStubVolume(@utf8InCpp String sourcePath, @utf8InCpp String mountPath, @utf8InCpp String fsType, - @utf8InCpp String fsUuid, @utf8InCpp String fsLabel); + @utf8InCpp String fsUuid, @utf8InCpp String fsLabel, int flags); void destroyStubVolume(@utf8InCpp String volId); FileDescriptor openAppFuseFile(int uid, int mountId, int fileId, int flags); diff --git a/model/Disk.cpp b/model/Disk.cpp index f8357a9..d08891a 100644 --- a/model/Disk.cpp +++ b/model/Disk.cpp @@ -180,6 +180,10 @@ status_t Disk::create() { auto listener = VolumeManager::Instance()->getListener(); if (listener) listener->onDiskCreated(getId(), mFlags); + if (isStub()) { + createStubVolume(); + return OK; + } readMetadata(); readPartitions(); return OK; @@ -243,6 +247,15 @@ void Disk::createPrivateVolume(dev_t device, const std::string& partGuid) { vol->create(); } +void Disk::createStubVolume() { + CHECK(mVolumes.size() == 1); + auto listener = VolumeManager::Instance()->getListener(); + if (listener) listener->onDiskMetadataChanged(getId(), mSize, mLabel, mSysPath); + if (listener) listener->onDiskScanned(getId()); + mVolumes[0]->setDiskId(getId()); + mVolumes[0]->create(); +} + void Disk::destroyAllVolumes() { for (const auto& vol : mVolumes) { vol->destroy(); @@ -443,6 +456,12 @@ status_t Disk::readPartitions() { return OK; } +void Disk::initializePartition(std::shared_ptr vol) { + CHECK(isStub()); + CHECK(mVolumes.empty()); + mVolumes.push_back(vol); +} + status_t Disk::unmountAll() { for (const auto& vol : mVolumes) { vol->unmount(); diff --git a/model/Disk.h b/model/Disk.h index d82d141..99c98fc 100644 --- a/model/Disk.h +++ b/model/Disk.h @@ -17,6 +17,7 @@ #ifndef ANDROID_VOLD_DISK_H #define ANDROID_VOLD_DISK_H +#include "StubVolume.h" #include "Utils.h" #include "VolumeBase.h" @@ -52,6 +53,9 @@ class Disk { kUsb = 1 << 3, /* Flag that disk is EMMC internal */ kEmmc = 1 << 4, + /* Flag that disk is Stub disk, i.e., disk that is managed from outside + * Android (e.g., ARC++). */ + kStub = 1 << 5, }; const std::string& getId() const { return mId; } @@ -74,6 +78,7 @@ class Disk { status_t readMetadata(); status_t readPartitions(); + void initializePartition(std::shared_ptr vol); status_t unmountAll(); @@ -109,11 +114,14 @@ class Disk { void createPublicVolume(dev_t device); void createPrivateVolume(dev_t device, const std::string& partGuid); + void createStubVolume(); void destroyAllVolumes(); int getMaxMinors(); + bool isStub() { return mFlags & kStub; } + DISALLOW_COPY_AND_ASSIGN(Disk); }; diff --git a/model/StubVolume.cpp b/model/StubVolume.cpp index edd0861..d2cd8a8 100644 --- a/model/StubVolume.cpp +++ b/model/StubVolume.cpp @@ -16,6 +16,8 @@ #include "StubVolume.h" +#include + #include #include @@ -24,7 +26,7 @@ using android::base::StringPrintf; namespace android { namespace vold { -StubVolume::StubVolume(int id, const std::string& sourcePath, const std::string& mountPath, +StubVolume::StubVolume(dev_t id, const std::string& sourcePath, const std::string& mountPath, const std::string& fsType, const std::string& fsUuid, const std::string& fsLabel) : VolumeBase(Type::kStub), @@ -33,7 +35,7 @@ StubVolume::StubVolume(int id, const std::string& sourcePath, const std::string& mFsType(fsType), mFsUuid(fsUuid), mFsLabel(fsLabel) { - setId(StringPrintf("stub:%d", id)); + setId(StringPrintf("stub:%llu", (unsigned long long)id)); } StubVolume::~StubVolume() {} diff --git a/model/StubVolume.h b/model/StubVolume.h index 538cae9..3697b53 100644 --- a/model/StubVolume.h +++ b/model/StubVolume.h @@ -31,7 +31,7 @@ namespace vold { */ class StubVolume : public VolumeBase { public: - StubVolume(int id, const std::string& sourcePath, const std::string& mountPath, + StubVolume(dev_t id, const std::string& sourcePath, const std::string& mountPath, const std::string& fsType, const std::string& fsUuid, const std::string& fsLabel); virtual ~StubVolume();