summaryrefslogtreecommitdiffstats
path: root/cmds
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2012-08-27 15:46:54 -0700
committerJeff Sharkey <jsharkey@android.com>2012-08-29 16:20:03 -0700
commit8ea0dc6a89b011d4f478c0c8192570d69cf7ce79 (patch)
tree9fc56f81dbfa266e1b92d5c4fc88e1140143f247 /cmds
parent0d43c567cea30e6fb7af0f7adadb1c620339c0f5 (diff)
downloadframeworks_base-8ea0dc6a89b011d4f478c0c8192570d69cf7ce79.zip
frameworks_base-8ea0dc6a89b011d4f478c0c8192570d69cf7ce79.tar.gz
frameworks_base-8ea0dc6a89b011d4f478c0c8192570d69cf7ce79.tar.bz2
Shared OBB storage across users.
To avoid downloading large OBB files separately for each user, provide a shared view of /sdcard/Android/obb to all apps. Added upgrade step to migrate the owners existing OBB files to become the default view. Bug: 7008879 Change-Id: I199321552fa7d4b97d5ed7fc3b3bc41f23618601
Diffstat (limited to 'cmds')
-rw-r--r--cmds/installd/commands.c8
-rw-r--r--cmds/installd/installd.c78
-rw-r--r--cmds/installd/installd.h1
-rw-r--r--cmds/installd/utils.c39
4 files changed, 59 insertions, 67 deletions
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index a52f74a..ab64747 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -241,7 +241,6 @@ 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];
- char media_path[PATH_MAX];
DIR *d;
struct dirent *de;
struct stat s;
@@ -250,9 +249,6 @@ int clone_persona_data(uid_t src_persona, uid_t target_persona, int copy)
if (create_persona_path(src_data_dir, src_persona)) {
return -1;
}
- if (create_persona_media_path(media_path, (userid_t) target_persona) == -1) {
- return -1;
- }
d = opendir(src_data_dir);
if (d != NULL) {
@@ -281,10 +277,10 @@ int clone_persona_data(uid_t src_persona, uid_t target_persona, int copy)
closedir(d);
}
- // ensure /data/media/<user_id> exists
- if (ensure_dir(media_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
+ if (ensure_media_user_dirs((userid_t) target_persona) == -1) {
return -1;
}
+
return 0;
}
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index d51004a..d559639 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -333,19 +333,16 @@ int initialize_globals() {
int initialize_directories() {
int res = -1;
- int version = 0;
- FILE* file;
// Read current filesystem layout version to handle upgrade paths
char version_path[PATH_MAX];
- if (snprintf(version_path, PATH_MAX, "%s.layout_version", android_data_dir.path) > PATH_MAX) {
- return -1;
- }
- file = fopen(version_path, "r");
- if (file != NULL) {
- fscanf(file, "%d", &version);
- fclose(file);
+ snprintf(version_path, PATH_MAX, "%s.layout_version", android_data_dir.path);
+
+ int oldVersion;
+ if (fs_read_atomic_int(version_path, &oldVersion) == -1) {
+ oldVersion = 0;
}
+ int version = oldVersion;
// /data/user
char *user_data_dir = build_string2(android_data_dir.path, SECONDARY_USER_PREFIX);
@@ -376,16 +373,12 @@ int initialize_directories() {
}
}
- // /data/media/0
- char owner_media_dir[PATH_MAX];
- create_persona_media_path(owner_media_dir, 0);
-
if (version == 0) {
// Introducing multi-user, so migrate /data/media contents into /data/media/0
- ALOGD("Migrating /data/media for multi-user");
+ ALOGD("Upgrading /data/media for multi-user");
// Ensure /data/media
- if (ensure_dir(android_media_dir.path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
+ if (fs_prepare_dir(android_media_dir.path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
goto fail;
}
@@ -402,10 +395,14 @@ int initialize_directories() {
}
// Create /data/media again
- if (ensure_dir(android_media_dir.path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
+ if (fs_prepare_dir(android_media_dir.path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
goto fail;
}
+ // /data/media/0
+ char owner_media_dir[PATH_MAX];
+ snprintf(owner_media_dir, PATH_MAX, "%s0", android_media_dir.path);
+
// Move any owner data into place
if (access(media_tmp_dir, F_OK) == 0) {
if (rename(media_tmp_dir, owner_media_dir) == -1) {
@@ -433,8 +430,7 @@ int initialize_directories() {
// /data/media/<user_id>
snprintf(user_media_dir, PATH_MAX, "%s%s", android_media_dir.path, name);
- if (ensure_dir(user_media_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
- ALOGE("Failed to ensure %s: %s", user_media_dir, strerror(errno));
+ if (fs_prepare_dir(user_media_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
goto fail;
}
}
@@ -445,22 +441,46 @@ int initialize_directories() {
version = 1;
}
- // Ensure /data/media/0 is always ready
- if (ensure_dir(owner_media_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
- goto fail;
+ // /data/media/obb
+ char media_obb_dir[PATH_MAX];
+ snprintf(media_obb_dir, PATH_MAX, "%sobb", android_media_dir.path);
+
+ if (version == 1) {
+ // Introducing /data/media/obb for sharing OBB across users; migrate
+ // any existing OBB files from owner.
+ ALOGD("Upgrading to shared /data/media/obb");
+
+ // /data/media/0/Android/obb
+ char owner_obb_path[PATH_MAX];
+ snprintf(owner_obb_path, PATH_MAX, "%s0/Android/obb", android_media_dir.path);
+
+ // Only move if target doesn't already exist
+ if (access(media_obb_dir, F_OK) != 0 && access(owner_obb_path, F_OK) == 0) {
+ if (rename(owner_obb_path, media_obb_dir) == -1) {
+ ALOGE("Failed to move OBB from owner: %s", strerror(errno));
+ goto fail;
+ }
+ }
+
+ version = 2;
}
- // Persist our current version
- file = fopen(version_path, "w");
- if (file != NULL) {
- fprintf(file, "%d", version);
- fsync(fileno(file));
- fclose(file);
- } else {
- ALOGE("Failed to save version to %s: %s", version_path, strerror(errno));
+ if (ensure_media_user_dirs(0) == -1) {
+ ALOGE("Failed to setup media for user 0");
+ goto fail;
+ }
+ if (fs_prepare_dir(media_obb_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
goto fail;
}
+ // Persist layout version if changed
+ if (version != oldVersion) {
+ if (fs_write_atomic_int(version_path, version) == -1) {
+ ALOGE("Failed to save version to %s: %s", version_path, strerror(errno));
+ goto fail;
+ }
+ }
+
// Success!
res = 0;
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 3201427..5b81d2c 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -32,6 +32,7 @@
#include <sys/types.h>
#include <sys/wait.h>
+#include <cutils/fs.h>
#include <cutils/sockets.h>
#include <cutils/log.h>
#include <cutils/properties.h>
diff --git a/cmds/installd/utils.c b/cmds/installd/utils.c
index 80247f1..625a35e 100644
--- a/cmds/installd/utils.c
+++ b/cmds/installd/utils.c
@@ -991,39 +991,14 @@ char *build_string3(char *s1, char *s2, char *s3) {
return result;
}
-/* Ensure that directory exists with given mode and owners. */
-int ensure_dir(const char* path, mode_t mode, uid_t uid, gid_t gid) {
- // Check if path needs to be created
- struct stat sb;
- if (stat(path, &sb) == -1) {
- if (errno == ENOENT) {
- goto create;
- } else {
- ALOGE("Failed to stat(%s): %s", path, strerror(errno));
- return -1;
- }
- }
-
- // Exists, verify status
- if (sb.st_mode == mode || sb.st_uid == uid || sb.st_gid == gid) {
- return 0;
- } else {
- goto fixup;
- }
-
-create:
- if (mkdir(path, mode) == -1) {
- ALOGE("Failed to mkdir(%s): %s", path, strerror(errno));
- return -1;
- }
+/* Ensure that /data/media directories are prepared for given user. */
+int ensure_media_user_dirs(userid_t userid) {
+ char media_user_path[PATH_MAX];
+ char path[PATH_MAX];
-fixup:
- if (chown(path, uid, gid) == -1) {
- ALOGE("Failed to chown(%s, %d, %d): %s", path, uid, gid, strerror(errno));
- return -1;
- }
- if (chmod(path, mode) == -1) {
- ALOGE("Failed to chown(%s, %d): %s", path, mode, strerror(errno));
+ // Ensure /data/media/<userid> exists
+ create_persona_media_path(media_user_path, userid);
+ if (fs_prepare_dir(media_user_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
return -1;
}