More volume UUID awareness.
Teach free_cache() and restorecon_data() about building per-volume
paths. Also clean up restorecon_data() by using std::string when
building paths.
Clearer names for path building utility methods, and tests to verify.
Bug: 19993667
Change-Id: Iacfbcdaa5b901cc2490bc8eba366dfdeb44f1d93
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index 763cb42..e10116e 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -46,21 +46,7 @@
CHECK(is_valid_filename(package_name));
CHECK(is_valid_package_name(package_name) == 0);
- if (volume_uuid == nullptr) {
- if (user == 0) {
- // /data/data/com.example
- return StringPrintf("%sdata/%s", android_data_dir.path, package_name);
- } else {
- // /data/user/0/com.example
- return StringPrintf("%suser/%u/%s", android_data_dir.path, user, package_name);
- }
- } else {
- CHECK(is_valid_filename(volume_uuid));
-
- // /mnt/expand/uuid/user/0/com.example
- return StringPrintf("%s%s/user/%u/%s", android_mnt_expand_dir.path,
- volume_uuid, user, package_name);
- }
+ return StringPrintf("%s/%s", create_data_user_path(volume_uuid, user).c_str(), package_name);
}
int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname,
@@ -81,55 +67,36 @@
}
}
+std::string create_data_path(const char* volume_uuid) {
+ if (volume_uuid == nullptr) {
+ return "/data";
+ } else {
+ CHECK(is_valid_filename(volume_uuid));
+ return StringPrintf("/mnt/expand/%s", volume_uuid);
+ }
+}
+
/**
* Create the path name for user data for a certain userid.
- * Returns 0 on success, and -1 on failure.
*/
-int create_user_path(char path[PKG_PATH_MAX],
- userid_t userid)
-{
- size_t userid_len;
- const char* userid_prefix;
- if (userid == 0) {
- userid_prefix = PRIMARY_USER_PREFIX;
- userid_len = 0;
+std::string create_data_user_path(const char* volume_uuid, userid_t userid) {
+ std::string data(create_data_path(volume_uuid));
+ if (volume_uuid == nullptr) {
+ if (userid == 0) {
+ return StringPrintf("%s/data", data.c_str());
+ } else {
+ return StringPrintf("%s/user/%u", data.c_str(), userid);
+ }
} else {
- userid_prefix = SECONDARY_USER_PREFIX;
- userid_len = snprintf(NULL, 0, "%d/", userid);
+ return StringPrintf("%s/user/%u", data.c_str(), userid);
}
-
- char *dst = path;
- size_t dst_size = PKG_PATH_MAX;
-
- if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0
- || append_and_increment(&dst, userid_prefix, &dst_size) < 0) {
- ALOGE("Error building prefix for user path");
- return -1;
- }
-
- if (userid != 0) {
- if (dst_size < userid_len + 1) {
- ALOGE("Error building user path");
- return -1;
- }
- int ret = snprintf(dst, dst_size, "%d/", userid);
- if (ret < 0 || (size_t) ret != userid_len) {
- ALOGE("Error appending userid to path");
- return -1;
- }
- }
- return 0;
}
/**
* Create the path name for media for a certain userid.
- * Returns 0 on success, and -1 on failure.
*/
-int create_user_media_path(char path[PATH_MAX], userid_t userid) {
- if (snprintf(path, PATH_MAX, "%s%d", android_media_dir.path, userid) > PATH_MAX) {
- return -1;
- }
- return 0;
+std::string create_data_media_path(const char* volume_uuid, userid_t userid) {
+ return StringPrintf("%s/media/%u", create_data_path(volume_uuid).c_str(), userid);
}
/**
@@ -459,13 +426,13 @@
return -1;
}
-int64_t data_disk_free()
+int64_t data_disk_free(const std::string& data_path)
{
struct statfs sfs;
- if (statfs(android_data_dir.path, &sfs) == 0) {
+ if (statfs(data_path.c_str(), &sfs) == 0) {
return sfs.f_bavail * sfs.f_bsize;
} else {
- ALOGE("Couldn't statfs %s: %s\n", android_data_dir.path, strerror(errno));
+ PLOG(ERROR) << "Couldn't statfs " << data_path;
return -1;
}
}
@@ -823,7 +790,7 @@
return lhs->modTime < rhs->modTime ? -1 : (lhs->modTime > rhs->modTime ? 1 : 0);
}
-void clear_cache_files(cache_t* cache, int64_t free_size)
+void clear_cache_files(const std::string& data_path, cache_t* cache, int64_t free_size)
{
size_t i;
int skip = 0;
@@ -848,7 +815,7 @@
for (i=0; i<cache->numFiles; i++) {
skip++;
if (skip > 10) {
- if (data_disk_free() > free_size) {
+ if (data_disk_free(data_path) > free_size) {
return;
}
skip = 0;
@@ -1090,12 +1057,9 @@
}
/* Ensure that /data/media directories are prepared for given user. */
-int ensure_media_user_dirs(userid_t userid) {
- char media_user_path[PATH_MAX];
-
- // Ensure /data/media/<userid> exists
- create_user_media_path(media_user_path, userid);
- if (fs_prepare_dir(media_user_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
+int ensure_media_user_dirs(const char* uuid, userid_t userid) {
+ std::string media_user_path(create_data_media_path(uuid, userid));
+ if (fs_prepare_dir(media_user_path.c_str(), 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
return -1;
}