Merge "[CloneProfile] Create user mount directory before creating bind mounts." into main
diff --git a/Utils.cpp b/Utils.cpp
index 696b0b4..a3db43e 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -1562,15 +1562,9 @@
return -1;
}
- // Shell is neither AID_ROOT nor AID_EVERYBODY. Since it equally needs 'execute' access to
- // /mnt/user/0 to 'adb shell ls /sdcard' for instance, we set the uid bit of /mnt/user/0 to
- // AID_SHELL. This gives shell access along with apps running as group everybody (user 0 apps)
- // These bits should be consistent with what is set in zygote in
- // com_android_internal_os_Zygote#MountEmulatedStorage on volume bind mount during app fork
- result = PrepareDir(pre_fuse_path, 0710, user_id ? AID_ROOT : AID_SHELL,
- multiuser_get_uid(user_id, AID_EVERYBODY));
+ result = PrepareMountDirForUser(user_id);
if (result != android::OK) {
- PLOG(ERROR) << "Failed to prepare directory " << pre_fuse_path;
+ PLOG(ERROR) << "Failed to create Mount Directory for user " << user_id;
return -1;
}
@@ -1808,5 +1802,22 @@
return enabled;
}
+status_t PrepareMountDirForUser(userid_t user_id) {
+ std::string pre_fuse_path(StringPrintf("/mnt/user/%d", user_id));
+ LOG(INFO) << "Creating mount directory " << pre_fuse_path;
+ // Shell is neither AID_ROOT nor AID_EVERYBODY. Since it equally needs 'execute' access to
+ // /mnt/user/0 to 'adb shell ls /sdcard' for instance, we set the uid bit of /mnt/user/0 to
+ // AID_SHELL. This gives shell access along with apps running as group everybody (user 0 apps)
+ // These bits should be consistent with what is set in zygote in
+ // com_android_internal_os_Zygote#MountEmulatedStorage on volume bind mount during app fork
+ auto result = PrepareDir(pre_fuse_path, 0710, user_id ? AID_ROOT : AID_SHELL,
+ multiuser_get_uid(user_id, AID_EVERYBODY));
+ if (result != android::OK) {
+ PLOG(ERROR) << "Failed to prepare directory " << pre_fuse_path;
+ return -1;
+ }
+ return result;
+}
+
} // namespace vold
} // namespace android
diff --git a/Utils.h b/Utils.h
index 690f79e..39723ec 100644
--- a/Utils.h
+++ b/Utils.h
@@ -219,6 +219,8 @@
// referenced inside the current process via the virtual procfs symlink returned here.
std::pair<android::base::unique_fd, std::string> OpenDirInProcfs(std::string_view path);
+status_t PrepareMountDirForUser(userid_t user_id);
+
} // namespace vold
} // namespace android
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index a1ac20d..2171717 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -473,6 +473,13 @@
// No need to bind if the user does not share storage with the mount owner
continue;
}
+ // Create mount directory for the user as there is a chance that no other Volume is
+ // mounted for the user (ex: if the user is just started), so /mnt/user/user_id does
+ // not exist yet.
+ auto mountDirStatus = android::vold::PrepareMountDirForUser(userId);
+ if (mountDirStatus != OK) {
+ LOG(ERROR) << "Failed to create Mount Directory for user " << userId;
+ }
auto bindMountStatus = pvol->bindMountForUser(userId);
if (bindMountStatus != OK) {
LOG(ERROR) << "Bind Mounting Public Volume: " << pvol << " for user: " << userId
diff --git a/model/PublicVolume.cpp b/model/PublicVolume.cpp
index e86d002..91b1ca2 100644
--- a/model/PublicVolume.cpp
+++ b/model/PublicVolume.cpp
@@ -269,6 +269,12 @@
// No need to bind if the user does not share storage with the mount owner
continue;
}
+ // Create mount directory for the user as there is a chance that no other Volume is mounted
+ // for the user (ex: if the user is just started), so /mnt/user/user_id does not exist yet.
+ auto mountDirStatus = PrepareMountDirForUser(started_user);
+ if (mountDirStatus != OK) {
+ LOG(ERROR) << "Failed to create Mount Directory for user " << started_user;
+ }
auto bindMountStatus = bindMountForUser(started_user);
if (bindMountStatus != OK) {
LOG(ERROR) << "Bind Mounting Public Volume: " << stableName