Automatically use correct lower paths for setupAppDir.
When we're asked to create an app directory, find the corresponding volume, and use the raw path of that volume to create the directory. This ensures this will continue working on devices that don't have sdcardfs. Bug: 146419093 Test: manual test on cuttlefish Change-Id: I91d735c1adbcca171e5af73aca0abd7ef396d0b7
This commit is contained in:
parent
bb972c0e0e
commit
0a7e9925a6
4 changed files with 66 additions and 4 deletions
|
@ -830,16 +830,47 @@ int VolumeManager::setupAppDir(const std::string& path, const std::string& appDi
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
// Find the volume it belongs to
|
||||
auto filter_fn = [&](const VolumeBase& vol) {
|
||||
if (vol.getState() != VolumeBase::State::kMounted) {
|
||||
// The volume must be mounted
|
||||
return false;
|
||||
}
|
||||
if ((vol.getMountFlags() & VolumeBase::MountFlags::kVisible) == 0) {
|
||||
// and visible
|
||||
return false;
|
||||
}
|
||||
if (vol.getInternalPath().empty()) {
|
||||
return false;
|
||||
}
|
||||
if (vol.getMountUserId() != USER_UNKNOWN &&
|
||||
vol.getMountUserId() != multiuser_get_user_id(appUid)) {
|
||||
// The app dir must be created on a volume with the same user-id
|
||||
return false;
|
||||
}
|
||||
if (!path.empty() && StartsWith(path, vol.getPath())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
auto volume = findVolumeWithFilter(filter_fn);
|
||||
if (volume == nullptr) {
|
||||
LOG(ERROR) << "Failed to find mounted volume for " << path;
|
||||
return -EINVAL;
|
||||
}
|
||||
// Convert paths to lower filesystem paths to avoid making FUSE requests for these reasons:
|
||||
// 1. A FUSE request from vold puts vold at risk of hanging if the FUSE daemon is down
|
||||
// 2. The FUSE daemon prevents requests on /mnt/user/0/emulated/<userid != 0> and a request
|
||||
// on /storage/emulated/10 means /mnt/user/0/emulated/10
|
||||
// TODO(b/146419093): Use lower filesystem paths that don't depend on sdcardfs
|
||||
const std::string lowerPath = "/mnt/runtime/default/" + path.substr(9);
|
||||
const std::string lowerAppDirRoot = "/mnt/runtime/default/" + appDirRoot.substr(9);
|
||||
const std::string lowerPath =
|
||||
volume->getInternalPath() + path.substr(volume->getPath().length());
|
||||
const std::string lowerAppDirRoot =
|
||||
volume->getInternalPath() + appDirRoot.substr(volume->getPath().length());
|
||||
|
||||
// First create the root which holds app dirs, if needed.
|
||||
int ret = PrepareDirsFromRoot(lowerAppDirRoot, "/mnt/runtime/default/", 0771, AID_MEDIA_RW, AID_MEDIA_RW);
|
||||
int ret = PrepareDirsFromRoot(lowerAppDirRoot, volume->getInternalPath(), 0771, AID_MEDIA_RW,
|
||||
AID_MEDIA_RW);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -83,6 +83,24 @@ class VolumeManager {
|
|||
std::shared_ptr<android::vold::Disk> findDisk(const std::string& id);
|
||||
std::shared_ptr<android::vold::VolumeBase> findVolume(const std::string& id);
|
||||
|
||||
template <typename Fn>
|
||||
std::shared_ptr<android::vold::VolumeBase> findVolumeWithFilter(Fn fn) {
|
||||
for (const auto& vol : mInternalEmulatedVolumes) {
|
||||
if (fn(*vol)) {
|
||||
return vol;
|
||||
}
|
||||
}
|
||||
for (const auto& disk : mDisks) {
|
||||
for (const auto& vol : disk->getVolumes()) {
|
||||
if (fn(*vol)) {
|
||||
return vol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void listVolumes(android::vold::VolumeBase::Type type, std::list<std::string>& list) const;
|
||||
|
||||
const std::set<userid_t>& getStartedUsers() const { return mStartedUsers; }
|
||||
|
|
|
@ -162,6 +162,17 @@ void Disk::listVolumes(VolumeBase::Type type, std::list<std::string>& list) cons
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<VolumeBase>> Disk::getVolumes() const {
|
||||
std::vector<std::shared_ptr<VolumeBase>> vols;
|
||||
for (const auto& vol : mVolumes) {
|
||||
vols.push_back(vol);
|
||||
auto stackedVolumes = vol->getVolumes();
|
||||
vols.insert(vols.end(), stackedVolumes.begin(), stackedVolumes.end());
|
||||
}
|
||||
|
||||
return vols;
|
||||
}
|
||||
|
||||
status_t Disk::create() {
|
||||
CHECK(!mCreated);
|
||||
mCreated = true;
|
||||
|
|
|
@ -67,6 +67,8 @@ class Disk {
|
|||
|
||||
void listVolumes(VolumeBase::Type type, std::list<std::string>& list) const;
|
||||
|
||||
std::vector<std::shared_ptr<VolumeBase>> getVolumes() const;
|
||||
|
||||
status_t create();
|
||||
status_t destroy();
|
||||
|
||||
|
|
Loading…
Reference in a new issue