summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhimanshuz <himanshuz@google.com>2023-07-27 21:15:00 +0000
committerhimanshuz <himanshuz@google.com>2023-08-29 10:38:43 +0000
commit0ad0862159efbc52390c404132499e7bc42d8fc6 (patch)
tree997b6f08508a4708f46aaf042b6ec701ab6197d9
parentc2b3fefa016a239e6b3814caf5e5a89abe2037f3 (diff)
downloadvold-0ad0862159efbc52390c404132499e7bc42d8fc6.tar.gz
Adding public volume mounts for clone user.
Public SdCard Volumes are mounted only for user 0 (foreground user). This gives ENONT if the cloned user tries to access the files in SdCard with paths like "/storage/AB02-G212/DCIM/" This change adds SdCard Volume mnt under /mnt/usr/<cloned-user>/ which allows cloned apps access to SdCard via direct file paths. Bug: 203395175 Test: Manual by building and flashing device. Change-Id: I091c40d3cb19915145cd5af40d1e79d5a9ecfa02
-rw-r--r--VolumeManager.cpp27
-rw-r--r--model/PublicVolume.cpp50
-rw-r--r--model/PublicVolume.h2
3 files changed, 79 insertions, 0 deletions
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index e29b9206..d47d9f31 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -68,6 +68,7 @@
#include "model/EmulatedVolume.h"
#include "model/ObbVolume.h"
#include "model/PrivateVolume.h"
+#include "model/PublicVolume.h"
#include "model/StubVolume.h"
using android::OK;
@@ -88,6 +89,7 @@ using android::vold::IsVirtioBlkDevice;
using android::vold::PrepareAndroidDirs;
using android::vold::PrepareAppDirFromRoot;
using android::vold::PrivateVolume;
+using android::vold::PublicVolume;
using android::vold::Symlink;
using android::vold::Unlink;
using android::vold::UnmountTree;
@@ -457,6 +459,31 @@ int VolumeManager::onUserStarted(userid_t userId) {
if (mStartedUsers.find(userId) == mStartedUsers.end()) {
createEmulatedVolumesForUser(userId);
+ std::list<std::string> public_vols;
+ listVolumes(VolumeBase::Type::kPublic, public_vols);
+ for (const std::string& id : public_vols) {
+ PublicVolume* pvol = static_cast<PublicVolume*>(findVolume(id).get());
+ if (pvol->getState() != VolumeBase::State::kMounted) {
+ continue;
+ }
+ if (pvol->isVisible() == 0) {
+ continue;
+ }
+ userid_t mountUserId = pvol->getMountUserId();
+ if (userId == mountUserId) {
+ // No need to bind mount for the user that owns the mount
+ continue;
+ }
+ if (mountUserId != VolumeManager::Instance()->getSharedStorageUser(userId)) {
+ // No need to bind if the user does not share storage with the mount owner
+ continue;
+ }
+ auto bindMountStatus = pvol->bindMountForUser(userId);
+ if (bindMountStatus != OK) {
+ LOG(ERROR) << "Bind Mounting Public Volume: " << pvol << " for user: " << userId
+ << "Failed. Error: " << bindMountStatus;
+ }
+ }
}
mStartedUsers.insert(userId);
diff --git a/model/PublicVolume.cpp b/model/PublicVolume.cpp
index 034fb23e..e86d0026 100644
--- a/model/PublicVolume.cpp
+++ b/model/PublicVolume.cpp
@@ -257,9 +257,45 @@ status_t PublicVolume::doMount() {
// See comment in model/EmulatedVolume.cpp
ConfigureMaxDirtyRatioForFuse(GetFuseMountPathForUser(user_id, stableName), 40u);
+ auto vol_manager = VolumeManager::Instance();
+ // Create bind mounts for all running users
+ for (userid_t started_user : vol_manager->getStartedUsers()) {
+ userid_t mountUserId = getMountUserId();
+ if (started_user == mountUserId) {
+ // No need to bind mount for the user that owns the mount
+ continue;
+ }
+ if (mountUserId != VolumeManager::Instance()->getSharedStorageUser(started_user)) {
+ // No need to bind if the user does not share storage with the mount owner
+ continue;
+ }
+ auto bindMountStatus = bindMountForUser(started_user);
+ if (bindMountStatus != OK) {
+ LOG(ERROR) << "Bind Mounting Public Volume: " << stableName
+ << " for user: " << started_user << "Failed. Error: " << bindMountStatus;
+ }
+ }
return OK;
}
+status_t PublicVolume::bindMountForUser(userid_t user_id) {
+ userid_t mountUserId = getMountUserId();
+ std::string stableName = getId();
+ if (!mFsUuid.empty()) {
+ stableName = mFsUuid;
+ }
+
+ LOG(INFO) << "Bind Mounting Public Volume for user: " << user_id
+ << ".Mount owner: " << mountUserId;
+ auto sourcePath = GetFuseMountPathForUser(mountUserId, stableName);
+ auto destPath = GetFuseMountPathForUser(user_id, stableName);
+ PrepareDir(destPath, 0770, AID_ROOT, AID_MEDIA_RW);
+ auto mountRes = BindMount(sourcePath, destPath);
+ LOG(INFO) << "Mount status: " << mountRes;
+
+ return mountRes;
+}
+
status_t PublicVolume::doUnmount() {
// Unmount the storage before we kill the FUSE process. If we kill
// the FUSE process first, most file system operations will return
@@ -274,6 +310,20 @@ status_t PublicVolume::doUnmount() {
stableName = mFsUuid;
}
+ // Unmount bind mounts for running users
+ auto vol_manager = VolumeManager::Instance();
+ int user_id = getMountUserId();
+ for (int started_user : vol_manager->getStartedUsers()) {
+ if (started_user == user_id) {
+ // No need to remove bind mount for the user that owns the mount
+ continue;
+ }
+ LOG(INFO) << "Removing Public Volume Bind Mount for: " << started_user;
+ auto mountPath = GetFuseMountPathForUser(started_user, stableName);
+ ForceUnmount(mountPath);
+ rmdir(mountPath.c_str());
+ }
+
if (UnmountUserFuse(getMountUserId(), getInternalPath(), stableName) != OK) {
PLOG(INFO) << "UnmountUserFuse failed on public fuse volume";
return -errno;
diff --git a/model/PublicVolume.h b/model/PublicVolume.h
index 3156b537..ca553b06 100644
--- a/model/PublicVolume.h
+++ b/model/PublicVolume.h
@@ -42,6 +42,8 @@ class PublicVolume : public VolumeBase {
explicit PublicVolume(dev_t device);
virtual ~PublicVolume();
+ status_t bindMountForUser(userid_t user_id);
+
protected:
status_t doCreate() override;
status_t doDestroy() override;