Bind mount pkg specific dirs in the zygote child namespaces.
- Also update vold to create sandboxes for secondary storage devices.
- Since bind mounts are created in the process specific namespaces, we
don't need /mnt/storage anymore which we were using it to prevent
some bind mounts from propagating onto /mnt/runtime/write.
- Create bind mounts for {media,obb} dirs similar to data dir in
per process namespace.
- Also fix a bug where we are not passing correct packages to vold when
a new user starts.
Bug: 111890351
Test: manual
Change-Id: I7849efc4fbf3c654606fa30de7ab2de0236d766f
diff --git a/Utils.cpp b/Utils.cpp
index cdca85e..d348f71 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -24,6 +24,7 @@
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include <android-base/unique_fd.h>
#include <cutils/fs.h>
#include <logwrap/logwrap.h>
#include <private/android_filesystem_config.h>
@@ -788,5 +789,74 @@
return OK;
}
+static status_t delete_dir_contents(DIR* dir) {
+ // Shamelessly borrowed from android::installd
+ int dfd = dirfd(dir);
+ if (dfd < 0) {
+ return -errno;
+ }
+
+ status_t result;
+ struct dirent* de;
+ while ((de = readdir(dir))) {
+ const char* name = de->d_name;
+ if (de->d_type == DT_DIR) {
+ /* always skip "." and ".." */
+ if (name[0] == '.') {
+ if (name[1] == 0) continue;
+ if ((name[1] == '.') && (name[2] == 0)) continue;
+ }
+
+ android::base::unique_fd subfd(
+ openat(dfd, name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC));
+ if (subfd.get() == -1) {
+ PLOG(ERROR) << "Couldn't openat " << name;
+ result = -errno;
+ continue;
+ }
+ std::unique_ptr<DIR, decltype(&closedir)> subdirp(fdopendir(subfd), closedir);
+ if (!subdirp) {
+ PLOG(ERROR) << "Couldn't fdopendir " << name;
+ result = -errno;
+ continue;
+ }
+ result = delete_dir_contents(subdirp.get());
+ if (unlinkat(dfd, name, AT_REMOVEDIR) < 0) {
+ PLOG(ERROR) << "Couldn't unlinkat " << name;
+ result = -errno;
+ }
+ } else {
+ if (unlinkat(dfd, name, 0) < 0) {
+ PLOG(ERROR) << "Couldn't unlinkat " << name;
+ result = -errno;
+ }
+ }
+ }
+ return result;
+}
+
+status_t DeleteDirContentsAndDir(const std::string& pathname) {
+ // Shamelessly borrowed from android::installd
+ std::unique_ptr<DIR, decltype(&closedir)> dirp(opendir(pathname.c_str()), closedir);
+ if (!dirp) {
+ if (errno == ENOENT) {
+ return OK;
+ }
+ PLOG(ERROR) << "Failed to opendir " << pathname;
+ return -errno;
+ }
+ status_t res = delete_dir_contents(dirp.get());
+ if (res < 0) {
+ return res;
+ }
+ dirp.reset(nullptr);
+ if (rmdir(pathname.c_str()) != 0) {
+ PLOG(ERROR) << "rmdir failed on " << pathname;
+ return -errno;
+ }
+ LOG(VERBOSE) << "Success: rmdir on " << pathname;
+ return OK;
+}
+
} // namespace vold
} // namespace android