Merge "vold: Do not cache CE keys in vold"
diff --git a/Checkpoint.cpp b/Checkpoint.cpp
index 88f7cad..df5fc88 100644
--- a/Checkpoint.cpp
+++ b/Checkpoint.cpp
@@ -320,13 +320,13 @@
uint64_t free_bytes = 0;
if (is_fs_cp) {
statvfs(mnt_pnt.c_str(), &data);
- free_bytes = data.f_bavail * data.f_frsize;
+ free_bytes = ((uint64_t) data.f_bavail) * data.f_frsize;
} else {
std::string bow_device = fs_mgr_find_bow_device(blk_device);
if (!bow_device.empty()) {
std::string content;
if (android::base::ReadFileToString(bow_device + "/bow/free", &content)) {
- free_bytes = std::strtoul(content.c_str(), NULL, 10);
+ free_bytes = std::strtoull(content.c_str(), NULL, 10);
}
}
}
diff --git a/Utils.cpp b/Utils.cpp
index 67c48ad..a66e33c 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -1017,11 +1017,14 @@
std::string pass_through_path(
StringPrintf("%s/%s", pre_pass_through_path.c_str(), relative_upper_path.c_str()));
- std::string sdcardfs_path(
- StringPrintf("/mnt/runtime/full/%s", relative_upper_path.c_str()));
-
// Create directories.
- auto result = PrepareDir(pre_fuse_path, 0700, AID_ROOT, AID_ROOT);
+ // 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;
@@ -1053,8 +1056,16 @@
return -1;
}
linkpath += "/primary";
+ Symlink("/storage/emulated/" + std::to_string(user_id), linkpath);
- Symlink(fuse_path + "/" + std::to_string(user_id), linkpath);
+ std::string pass_through_linkpath(StringPrintf("/mnt/pass_through/%d/self", user_id));
+ result = PrepareDir(pass_through_linkpath, 0755, AID_ROOT, AID_ROOT);
+ if (result != android::OK) {
+ PLOG(ERROR) << "Failed to prepare directory " << pass_through_linkpath;
+ return -1;
+ }
+ pass_through_linkpath += "/primary";
+ Symlink("/storage/emulated/" + std::to_string(user_id), pass_through_linkpath);
}
// Open fuse fd.
@@ -1081,8 +1092,16 @@
return -errno;
}
- LOG(INFO) << "Bind mounting " << sdcardfs_path << " to " << pass_through_path;
- return BindMount(sdcardfs_path, pass_through_path);
+ if (IsFilesystemSupported("sdcardfs")) {
+ std::string sdcardfs_path(
+ StringPrintf("/mnt/runtime/full/%s", relative_upper_path.c_str()));
+
+ LOG(INFO) << "Bind mounting " << sdcardfs_path << " to " << pass_through_path;
+ return BindMount(sdcardfs_path, pass_through_path);
+ } else {
+ LOG(INFO) << "Bind mounting " << absolute_lower_path << " to " << pass_through_path;
+ return BindMount(absolute_lower_path, pass_through_path);
+ }
}
status_t UnmountUserFuse(userid_t user_id, const std::string& absolute_lower_path,
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index bc843b4..d8b1e32 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -264,10 +264,17 @@
void VolumeManager::handleDiskAdded(const std::shared_ptr<android::vold::Disk>& disk) {
// For security reasons, if secure keyguard is showing, wait
// until the user unlocks the device to actually touch it
+ // Additionally, wait until user 0 is actually started, since we need
+ // the user to be up before we can mount a FUSE daemon to handle the disk.
+ bool userZeroStarted = mStartedUsers.find(0) != mStartedUsers.end();
if (mSecureKeyguardShowing) {
LOG(INFO) << "Found disk at " << disk->getEventPath()
<< " but delaying scan due to secure keyguard";
mPendingDisks.push_back(disk);
+ } else if (!userZeroStarted) {
+ LOG(INFO) << "Found disk at " << disk->getEventPath()
+ << " but delaying scan due to user zero not having started";
+ mPendingDisks.push_back(disk);
} else {
disk->create();
mDisks.push_back(disk);
@@ -482,6 +489,8 @@
}
mStartedUsers.insert(userId);
+
+ createPendingDisksIfNeeded();
return 0;
}
@@ -496,17 +505,22 @@
return 0;
}
-int VolumeManager::onSecureKeyguardStateChanged(bool isShowing) {
- mSecureKeyguardShowing = isShowing;
- if (!mSecureKeyguardShowing) {
- // Now that secure keyguard has been dismissed, process
- // any pending disks
+void VolumeManager::createPendingDisksIfNeeded() {
+ bool userZeroStarted = mStartedUsers.find(0) != mStartedUsers.end();
+ if (!mSecureKeyguardShowing && userZeroStarted) {
+ // Now that secure keyguard has been dismissed and user 0 has
+ // started, process any pending disks
for (const auto& disk : mPendingDisks) {
disk->create();
mDisks.push_back(disk);
}
mPendingDisks.clear();
}
+}
+
+int VolumeManager::onSecureKeyguardStateChanged(bool isShowing) {
+ mSecureKeyguardShowing = isShowing;
+ createPendingDisksIfNeeded();
return 0;
}
@@ -792,7 +806,8 @@
#ifdef __ANDROID_DEBUGGABLE__
!StartsWith(test, "/mnt/scratch") &&
#endif
- !StartsWith(test, "/mnt/vendor") && !StartsWith(test, "/mnt/product")) ||
+ !StartsWith(test, "/mnt/vendor") && !StartsWith(test, "/mnt/product") &&
+ !StartsWith(test, "/mnt/installer")) ||
StartsWith(test, "/storage/")) {
toUnmount.push_front(test);
}
@@ -815,13 +830,21 @@
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);
+
// First create the root which holds app dirs, if needed.
- int ret = PrepareDirsFromRoot(appDirRoot, "/storage/", 0771, AID_MEDIA_RW, AID_MEDIA_RW);
+ int ret = PrepareDirsFromRoot(lowerAppDirRoot, "/mnt/runtime/default/", 0771, AID_MEDIA_RW, AID_MEDIA_RW);
if (ret != 0) {
return ret;
}
// Then, create app-specific dirs with the correct UID/GID
- return PrepareDirsFromRoot(path, appDirRoot, 0770, appUid, AID_MEDIA_RW);
+ return PrepareDirsFromRoot(lowerPath, lowerAppDirRoot, 0770, appUid, AID_MEDIA_RW);
}
int VolumeManager::createObb(const std::string& sourcePath, const std::string& sourceKey,
diff --git a/VolumeManager.h b/VolumeManager.h
index db32ecd..cacab85 100644
--- a/VolumeManager.h
+++ b/VolumeManager.h
@@ -94,6 +94,7 @@
int onUserStarted(userid_t userId);
int onUserStopped(userid_t userId);
+ void createPendingDisksIfNeeded();
int onSecureKeyguardStateChanged(bool isShowing);
int setPrimary(const std::shared_ptr<android::vold::VolumeBase>& vol);
diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl
index e7a44bc..1819e09 100644
--- a/binder/android/os/IVold.aidl
+++ b/binder/android/os/IVold.aidl
@@ -169,6 +169,7 @@
const int REMOUNT_MODE_INSTALLER = 5;
const int REMOUNT_MODE_FULL = 6;
const int REMOUNT_MODE_PASS_THROUGH = 7;
+ const int REMOUNT_MODE_ANDROID_WRITABLE = 8;
const int VOLUME_STATE_UNMOUNTED = 0;
const int VOLUME_STATE_CHECKING = 1;
diff --git a/model/EmulatedVolume.cpp b/model/EmulatedVolume.cpp
index aef7b77..082dea5 100644
--- a/model/EmulatedVolume.cpp
+++ b/model/EmulatedVolume.cpp
@@ -48,6 +48,7 @@
mRawPath = rawPath;
mLabel = "emulated";
mFuseMounted = false;
+ mUseSdcardFs = IsFilesystemSupported("sdcardfs");
}
EmulatedVolume::EmulatedVolume(const std::string& rawPath, dev_t device, const std::string& fsUuid,
@@ -57,6 +58,7 @@
mRawPath = rawPath;
mLabel = fsUuid;
mFuseMounted = false;
+ mUseSdcardFs = IsFilesystemSupported("sdcardfs");
}
EmulatedVolume::~EmulatedVolume() {}
@@ -71,33 +73,78 @@
}
}
-static status_t mountFuseBindMounts(int userId, const std::string& label) {
- // TODO(b/134706060) we don't actually want to mount the "write" view by
- // default, since it gives write access to all OBB dirs.
- std::string androidSource(
- StringPrintf("/mnt/runtime/default/%s/%d/Android", label.c_str(), userId));
- std::string androidTarget(
- StringPrintf("/mnt/user/%d/%s/%d/Android", userId, label.c_str(), userId));
-
- if (access(androidSource.c_str(), F_OK) != 0) {
+// Creates a bind mount from source to target, creating the source (!) directory
+// if not yet present.
+static status_t doFuseBindMount(const std::string& source, const std::string& target) {
+ if (access(source.c_str(), F_OK) != 0) {
// Android path may not exist yet if users has just been created; create it on
// the lower fs.
- if (fs_prepare_dir(androidSource.c_str(), 0771, AID_ROOT, AID_ROOT) != 0) {
- PLOG(ERROR) << "Failed to create " << androidSource;
+ if (fs_prepare_dir(source.c_str(), 0771, AID_MEDIA_RW, AID_MEDIA_RW) != 0) {
+ PLOG(ERROR) << "Failed to create " << source;
return -errno;
}
}
- LOG(INFO) << "Bind mounting " << androidSource << " on " << androidTarget;
- auto status = BindMount(androidSource, androidTarget);
+ LOG(INFO) << "Bind mounting " << source << " on " << target;
+ auto status = BindMount(source, target);
if (status != OK) {
return status;
}
- LOG(INFO) << "Bind mounted " << androidSource << " on " << androidTarget;
-
+ LOG(INFO) << "Bind mounted " << source << " on " << target;
return OK;
}
-static status_t unmountFuseBindMounts(int userId, const std::string& label) {
+status_t EmulatedVolume::mountFuseBindMounts() {
+ std::string androidSource;
+ std::string label = getLabel();
+ int userId = getMountUserId();
+
+ if (mUseSdcardFs) {
+ androidSource = StringPrintf("/mnt/runtime/default/%s/%d/Android", label.c_str(), userId);
+ } else {
+ androidSource = StringPrintf("/%s/%d/Android", mRawPath.c_str(), userId);
+ }
+ std::string androidTarget(
+ StringPrintf("/mnt/user/%d/%s/%d/Android", userId, label.c_str(), userId));
+
+ auto status = doFuseBindMount(androidSource, androidTarget);
+ if (status != OK) {
+ return status;
+ }
+
+ // Installers get the same view as all other apps, with the sole exception that the
+ // OBB dirs (Android/obb) are writable to them. On sdcardfs devices, this requires
+ // a special bind mount, since app-private and OBB dirs share the same GID, but we
+ // only want to give access to the latter.
+ if (!mUseSdcardFs) {
+ return OK;
+ }
+ std::string installerSource(
+ StringPrintf("/mnt/runtime/write/%s/%d/Android/obb", label.c_str(), userId));
+ std::string installerTarget(
+ StringPrintf("/mnt/installer/%d/%s/%d/Android/obb", userId, label.c_str(), userId));
+
+ status = doFuseBindMount(installerSource, installerTarget);
+ if (status != OK) {
+ return status;
+ }
+ return OK;
+}
+
+status_t EmulatedVolume::unmountFuseBindMounts() {
+ std::string label = getLabel();
+ int userId = getMountUserId();
+
+ if (mUseSdcardFs) {
+ std::string installerTarget(
+ StringPrintf("/mnt/installer/%d/%s/%d/Android/obb", userId, label.c_str(), userId));
+ LOG(INFO) << "Unmounting " << installerTarget;
+ auto status = UnmountTree(installerTarget);
+ if (status != OK) {
+ LOG(ERROR) << "Failed to unmount " << installerTarget;
+ // Intentional continue to try to unmount the other bind mount
+ }
+ }
+
std::string androidTarget(
StringPrintf("/mnt/user/%d/%s/%d/Android", userId, label.c_str(), userId));
@@ -137,7 +184,7 @@
// Mount sdcardfs regardless of FUSE, since we need it to bind-mount on top of the
// FUSE volume for various reasons.
- if (getMountUserId() == 0) {
+ if (mUseSdcardFs && getMountUserId() == 0) {
LOG(INFO) << "Executing sdcardfs";
int sdcardFsPid;
if (!(sdcardFsPid = fork())) {
@@ -198,12 +245,19 @@
bool is_ready = false;
callback->onVolumeChecking(std::move(fd), getPath(), getInternalPath(), &is_ready);
if (!is_ready) {
+ fd.reset();
+ doUnmount();
return -EIO;
}
}
// Only do the bind-mounts when we know for sure the FUSE daemon can resolve the path.
- return mountFuseBindMounts(user_id, label);
+ status_t res = mountFuseBindMounts();
+ if (res != OK) {
+ fd.reset();
+ doUnmount();
+ }
+ return res;
}
return OK;
@@ -231,7 +285,7 @@
// Ignoring unmount return status because we do want to try to unmount
// the rest cleanly.
- unmountFuseBindMounts(userId, label);
+ unmountFuseBindMounts();
if (UnmountUserFuse(userId, getInternalPath(), label) != OK) {
PLOG(INFO) << "UnmountUserFuse failed on emulated fuse volume";
return -errno;
@@ -239,7 +293,7 @@
mFuseMounted = false;
}
- if (getMountUserId() != 0) {
+ if (getMountUserId() != 0 || !mUseSdcardFs) {
// For sdcardfs, only unmount for user 0, since user 0 will always be running
// and the paths don't change for different users.
return OK;
diff --git a/model/EmulatedVolume.h b/model/EmulatedVolume.h
index 131761c..4f76a60 100644
--- a/model/EmulatedVolume.h
+++ b/model/EmulatedVolume.h
@@ -46,6 +46,9 @@
status_t doUnmount() override;
private:
+ status_t mountFuseBindMounts();
+ status_t unmountFuseBindMounts();
+
std::string getLabel();
std::string mRawPath;
std::string mLabel;
@@ -58,6 +61,9 @@
/* Whether we mounted FUSE for this volume */
bool mFuseMounted;
+ /* Whether to use sdcardfs for this volume */
+ bool mUseSdcardFs;
+
DISALLOW_COPY_AND_ASSIGN(EmulatedVolume);
};
diff --git a/model/PublicVolume.cpp b/model/PublicVolume.cpp
index 78f150d..b246c95 100644
--- a/model/PublicVolume.cpp
+++ b/model/PublicVolume.cpp
@@ -51,6 +51,7 @@
setId(StringPrintf("public:%u,%u", major(device), minor(device)));
mDevPath = StringPrintf("/dev/block/vold/%s", getId().c_str());
mFuseMounted = false;
+ mUseSdcardFs = IsFilesystemSupported("sdcardfs");
}
PublicVolume::~PublicVolume() {}
@@ -161,67 +162,69 @@
return OK;
}
- if (fs_prepare_dir(mSdcardFsDefault.c_str(), 0700, AID_ROOT, AID_ROOT) ||
- fs_prepare_dir(mSdcardFsRead.c_str(), 0700, AID_ROOT, AID_ROOT) ||
- fs_prepare_dir(mSdcardFsWrite.c_str(), 0700, AID_ROOT, AID_ROOT) ||
- fs_prepare_dir(mSdcardFsFull.c_str(), 0700, AID_ROOT, AID_ROOT)) {
- PLOG(ERROR) << getId() << " failed to create sdcardfs mount points";
- return -errno;
- }
-
- dev_t before = GetDevice(mSdcardFsFull);
-
- int sdcardFsPid;
- if (!(sdcardFsPid = fork())) {
- if (getMountFlags() & MountFlags::kPrimary) {
- // clang-format off
- if (execl(kSdcardFsPath, kSdcardFsPath,
- "-u", "1023", // AID_MEDIA_RW
- "-g", "1023", // AID_MEDIA_RW
- "-U", std::to_string(getMountUserId()).c_str(),
- "-w",
- mRawPath.c_str(),
- stableName.c_str(),
- NULL)) {
- // clang-format on
- PLOG(ERROR) << "Failed to exec";
- }
- } else {
- // clang-format off
- if (execl(kSdcardFsPath, kSdcardFsPath,
- "-u", "1023", // AID_MEDIA_RW
- "-g", "1023", // AID_MEDIA_RW
- "-U", std::to_string(getMountUserId()).c_str(),
- mRawPath.c_str(),
- stableName.c_str(),
- NULL)) {
- // clang-format on
- PLOG(ERROR) << "Failed to exec";
- }
+ if (mUseSdcardFs) {
+ if (fs_prepare_dir(mSdcardFsDefault.c_str(), 0700, AID_ROOT, AID_ROOT) ||
+ fs_prepare_dir(mSdcardFsRead.c_str(), 0700, AID_ROOT, AID_ROOT) ||
+ fs_prepare_dir(mSdcardFsWrite.c_str(), 0700, AID_ROOT, AID_ROOT) ||
+ fs_prepare_dir(mSdcardFsFull.c_str(), 0700, AID_ROOT, AID_ROOT)) {
+ PLOG(ERROR) << getId() << " failed to create sdcardfs mount points";
+ return -errno;
}
- LOG(ERROR) << "sdcardfs exiting";
- _exit(1);
- }
+ dev_t before = GetDevice(mSdcardFsFull);
- if (sdcardFsPid == -1) {
- PLOG(ERROR) << getId() << " failed to fork";
- return -errno;
- }
+ int sdcardFsPid;
+ if (!(sdcardFsPid = fork())) {
+ if (getMountFlags() & MountFlags::kPrimary) {
+ // clang-format off
+ if (execl(kSdcardFsPath, kSdcardFsPath,
+ "-u", "1023", // AID_MEDIA_RW
+ "-g", "1023", // AID_MEDIA_RW
+ "-U", std::to_string(getMountUserId()).c_str(),
+ "-w",
+ mRawPath.c_str(),
+ stableName.c_str(),
+ NULL)) {
+ // clang-format on
+ PLOG(ERROR) << "Failed to exec";
+ }
+ } else {
+ // clang-format off
+ if (execl(kSdcardFsPath, kSdcardFsPath,
+ "-u", "1023", // AID_MEDIA_RW
+ "-g", "1023", // AID_MEDIA_RW
+ "-U", std::to_string(getMountUserId()).c_str(),
+ mRawPath.c_str(),
+ stableName.c_str(),
+ NULL)) {
+ // clang-format on
+ PLOG(ERROR) << "Failed to exec";
+ }
+ }
- nsecs_t start = systemTime(SYSTEM_TIME_BOOTTIME);
- while (before == GetDevice(mSdcardFsFull)) {
- LOG(DEBUG) << "Waiting for sdcardfs to spin up...";
- usleep(50000); // 50ms
-
- nsecs_t now = systemTime(SYSTEM_TIME_BOOTTIME);
- if (nanoseconds_to_milliseconds(now - start) > 5000) {
- LOG(WARNING) << "Timed out while waiting for sdcardfs to spin up";
- return -ETIMEDOUT;
+ LOG(ERROR) << "sdcardfs exiting";
+ _exit(1);
}
+
+ if (sdcardFsPid == -1) {
+ PLOG(ERROR) << getId() << " failed to fork";
+ return -errno;
+ }
+
+ nsecs_t start = systemTime(SYSTEM_TIME_BOOTTIME);
+ while (before == GetDevice(mSdcardFsFull)) {
+ LOG(DEBUG) << "Waiting for sdcardfs to spin up...";
+ usleep(50000); // 50ms
+
+ nsecs_t now = systemTime(SYSTEM_TIME_BOOTTIME);
+ if (nanoseconds_to_milliseconds(now - start) > 5000) {
+ LOG(WARNING) << "Timed out while waiting for sdcardfs to spin up";
+ return -ETIMEDOUT;
+ }
+ }
+ /* sdcardfs will have exited already. The filesystem will still be running */
+ TEMP_FAILURE_RETRY(waitpid(sdcardFsPid, nullptr, 0));
}
- /* sdcardfs will have exited already. The filesystem will still be running */
- TEMP_FAILURE_RETRY(waitpid(sdcardFsPid, nullptr, 0));
bool isFuse = base::GetBoolProperty(kPropFuse, false);
if (isFuse) {
@@ -275,22 +278,24 @@
ForceUnmount(kAsecPath);
- ForceUnmount(mSdcardFsDefault);
- ForceUnmount(mSdcardFsRead);
- ForceUnmount(mSdcardFsWrite);
- ForceUnmount(mSdcardFsFull);
+ if (mUseSdcardFs) {
+ ForceUnmount(mSdcardFsDefault);
+ ForceUnmount(mSdcardFsRead);
+ ForceUnmount(mSdcardFsWrite);
+ ForceUnmount(mSdcardFsFull);
+
+ rmdir(mSdcardFsDefault.c_str());
+ rmdir(mSdcardFsRead.c_str());
+ rmdir(mSdcardFsWrite.c_str());
+ rmdir(mSdcardFsFull.c_str());
+
+ mSdcardFsDefault.clear();
+ mSdcardFsRead.clear();
+ mSdcardFsWrite.clear();
+ mSdcardFsFull.clear();
+ }
ForceUnmount(mRawPath);
-
- rmdir(mSdcardFsDefault.c_str());
- rmdir(mSdcardFsRead.c_str());
- rmdir(mSdcardFsWrite.c_str());
- rmdir(mSdcardFsFull.c_str());
rmdir(mRawPath.c_str());
-
- mSdcardFsDefault.clear();
- mSdcardFsRead.clear();
- mSdcardFsWrite.clear();
- mSdcardFsFull.clear();
mRawPath.clear();
return OK;
diff --git a/model/PublicVolume.h b/model/PublicVolume.h
index dd76373..3156b53 100644
--- a/model/PublicVolume.h
+++ b/model/PublicVolume.h
@@ -68,6 +68,9 @@
/* Whether we mounted FUSE for this volume */
bool mFuseMounted;
+ /* Whether to use sdcardfs for this volume */
+ bool mUseSdcardFs;
+
/* Filesystem type */
std::string mFsType;
/* Filesystem UUID */
diff --git a/vold_prepare_subdirs.cpp b/vold_prepare_subdirs.cpp
index 3a58b2e..d624d73 100644
--- a/vold_prepare_subdirs.cpp
+++ b/vold_prepare_subdirs.cpp
@@ -121,7 +121,7 @@
}
static bool prepare_apex_subdirs(struct selabel_handle* sehandle, const std::string& path) {
- if (!prepare_dir(sehandle, 0700, 0, 0, path + "/apexdata")) return false;
+ if (!prepare_dir(sehandle, 0711, 0, 0, path + "/apexdata")) return false;
auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir("/apex"), closedir);
if (!dirp) {
@@ -138,7 +138,7 @@
if (strchr(name, '@') != NULL) continue;
- if (!prepare_dir(sehandle, 0700, AID_SYSTEM, AID_SYSTEM, path + "/apexdata/" + name)) {
+ if (!prepare_dir(sehandle, 0771, AID_ROOT, AID_SYSTEM, path + "/apexdata/" + name)) {
return false;
}
}