TEST_F(UtilsTest, CreatePersonaPath_Secondary) { char path[PKG_PATH_MAX]; EXPECT_EQ(0, create_persona_path(path, 1)) << "Should successfully build primary user path."; EXPECT_STREQ("/data/user/1/", path) << "Primary user should have correct path"; }
int delete_persona(uid_t persona) { char pkgdir[PKG_PATH_MAX]; if (create_persona_path(pkgdir, persona)) return -1; return delete_dir_contents(pkgdir, 1, NULL); }
/* Try to ensure free_size bytes of storage are available. * Returns 0 on success. * This is rather simple-minded because doing a full LRU would * be potentially memory-intensive, and without atime it would * also require that apps constantly modify file metadata even * when just reading from the cache, which is pretty awful. */ int free_cache(int64_t free_size) { const char *name; int dfd, subfd; DIR *d; struct dirent *de; int64_t avail; char datadir[PKG_PATH_MAX];//ALPS00106329 + avail = disk_free(); if (avail < 0) return -1; LOGI("free_cache(%" PRId64 ") avail %" PRId64 "\n", free_size, avail); if (avail >= free_size) return 0; //ALPS00106329 + if (create_persona_path(datadir, 0)) { LOGE("couldn't get directory for persona 0"); return -1; } d = opendir(datadir); //ALPS00106329 - if (d == NULL) { LOGE("cannot open %s: %s\n", datadir, strerror(errno));//ALPS00106329 + return -1; } dfd = dirfd(d); while ((de = readdir(d))) { if (de->d_type != DT_DIR) continue; name = de->d_name; /* always skip "." and ".." */ if (name[0] == '.') { if (name[1] == 0) continue; if ((name[1] == '.') && (name[2] == 0)) continue; } subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY); if (subfd < 0) continue; delete_dir_contents_fd(subfd, "cache"); close(subfd); avail = disk_free(); if (avail >= free_size) { closedir(d); return 0; } } closedir(d); /* Fail case - not possible to free space */ return -1; }
int clone_persona_data(uid_t src_persona, uid_t target_persona, int copy) { char src_data_dir[PKG_PATH_MAX]; char pkg_path[PKG_PATH_MAX]; DIR *d; struct dirent *de; struct stat s; uid_t uid; if (create_persona_path(src_data_dir, src_persona)) { return -1; } d = opendir(src_data_dir); if (d != NULL) { while ((de = readdir(d))) { const char *name = de->d_name; if (de->d_type == DT_DIR) { int subfd; /* always skip "." and ".." */ if (name[0] == '.') { if (name[1] == 0) continue; if ((name[1] == '.') && (name[2] == 0)) continue; } /* Create the full path to the package's data dir */ create_pkg_path(pkg_path, name, PKG_DIR_POSTFIX, src_persona); /* Get the file stat */ if (stat(pkg_path, &s) < 0) continue; /* Get the uid of the package */ ALOGI("Adding datadir for uid = %lu\n", s.st_uid); uid = (uid_t) s.st_uid % PER_USER_RANGE; /* Create the directory for the target */ make_user_data(name, uid + target_persona * PER_USER_RANGE, target_persona, NULL); } } closedir(d); } if (ensure_media_user_dirs((userid_t) target_persona) == -1) { return -1; } return 0; }
int delete_persona(uid_t persona) { char data_path[PKG_PATH_MAX]; if (create_persona_path(data_path, persona)) { return -1; } if (delete_dir_contents(data_path, 1, NULL)) { return -1; } char media_path[PATH_MAX]; if (create_persona_media_path(media_path, (userid_t) persona) == -1) { return -1; } if (delete_dir_contents(media_path, 1, NULL) == -1) { return -1; } return 0; }
/* Try to ensure free_size bytes of storage are available. * Returns 0 on success. * This is rather simple-minded because doing a full LRU would * be potentially memory-intensive, and without atime it would * also require that apps constantly modify file metadata even * when just reading from the cache, which is pretty awful. */ int free_cache(int64_t free_size) { cache_t* cache; int64_t avail; DIR *d; struct dirent *de; char tmpdir[PATH_MAX]; char *dirpos; avail = data_disk_free(); if (avail < 0) return -1; ALOGI("free_cache(%" PRId64 ") avail %" PRId64 "\n", free_size, avail); if (avail >= free_size) return 0; cache = start_cache_collection(); // Collect cache files for primary user. if (create_persona_path(tmpdir, 0) == 0) { //ALOGI("adding cache files from %s\n", tmpdir); add_cache_files(cache, tmpdir, "cache"); } // Search for other users and add any cache files from them. snprintf(tmpdir, sizeof(tmpdir), "%s%s", android_data_dir.path, SECONDARY_USER_PREFIX); dirpos = tmpdir + strlen(tmpdir); d = opendir(tmpdir); if (d != NULL) { while ((de = readdir(d))) { if (de->d_type == DT_DIR) { const char *name = de->d_name; /* always skip "." and ".." */ if (name[0] == '.') { if (name[1] == 0) continue; if ((name[1] == '.') && (name[2] == 0)) continue; } if ((strlen(name)+(dirpos-tmpdir)) < (sizeof(tmpdir)-1)) { strcpy(dirpos, name); //ALOGI("adding cache files from %s\n", tmpdir); add_cache_files(cache, tmpdir, "cache"); } else { ALOGW("Path exceeds limit: %s%s", tmpdir, name); } } } closedir(d); } // Collect cache files on external storage for all users (if it is mounted as part // of the internal storage). strcpy(tmpdir, android_media_dir.path); dirpos = tmpdir + strlen(tmpdir); d = opendir(tmpdir); if (d != NULL) { while ((de = readdir(d))) { if (de->d_type == DT_DIR) { const char *name = de->d_name; /* skip any dir that doesn't start with a number, so not a user */ if (name[0] < '0' || name[0] > '9') { continue; } if ((strlen(name)+(dirpos-tmpdir)) < (sizeof(tmpdir)-1)) { strcpy(dirpos, name); if (lookup_media_dir(tmpdir, "Android") == 0 && lookup_media_dir(tmpdir, "data") == 0) { //ALOGI("adding cache files from %s\n", tmpdir); add_cache_files(cache, tmpdir, "cache"); } } else { ALOGW("Path exceeds limit: %s%s", tmpdir, name); } } } closedir(d); } clear_cache_files(cache, free_size); finish_cache_collection(cache); return data_disk_free() >= free_size ? 0 : -1; }