Skip to content

Commit e671cce

Browse files
jsharkeyAndroid (Google) Code Review
authored andcommitted
Merge "Shared OBB storage across users." into jb-mr1-dev
2 parents c0c1c94 + 8ea0dc6 commit e671cce

File tree

4 files changed

+59
-67
lines changed

4 files changed

+59
-67
lines changed

cmds/installd/commands.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,6 @@ int clone_persona_data(uid_t src_persona, uid_t target_persona, int copy)
241241
{
242242
char src_data_dir[PKG_PATH_MAX];
243243
char pkg_path[PKG_PATH_MAX];
244-
char media_path[PATH_MAX];
245244
DIR *d;
246245
struct dirent *de;
247246
struct stat s;
@@ -250,9 +249,6 @@ int clone_persona_data(uid_t src_persona, uid_t target_persona, int copy)
250249
if (create_persona_path(src_data_dir, src_persona)) {
251250
return -1;
252251
}
253-
if (create_persona_media_path(media_path, (userid_t) target_persona) == -1) {
254-
return -1;
255-
}
256252

257253
d = opendir(src_data_dir);
258254
if (d != NULL) {
@@ -281,10 +277,10 @@ int clone_persona_data(uid_t src_persona, uid_t target_persona, int copy)
281277
closedir(d);
282278
}
283279

284-
// ensure /data/media/<user_id> exists
285-
if (ensure_dir(media_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
280+
if (ensure_media_user_dirs((userid_t) target_persona) == -1) {
286281
return -1;
287282
}
283+
288284
return 0;
289285
}
290286

cmds/installd/installd.c

Lines changed: 49 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -333,19 +333,16 @@ int initialize_globals() {
333333

334334
int initialize_directories() {
335335
int res = -1;
336-
int version = 0;
337-
FILE* file;
338336

339337
// Read current filesystem layout version to handle upgrade paths
340338
char version_path[PATH_MAX];
341-
if (snprintf(version_path, PATH_MAX, "%s.layout_version", android_data_dir.path) > PATH_MAX) {
342-
return -1;
343-
}
344-
file = fopen(version_path, "r");
345-
if (file != NULL) {
346-
fscanf(file, "%d", &version);
347-
fclose(file);
339+
snprintf(version_path, PATH_MAX, "%s.layout_version", android_data_dir.path);
340+
341+
int oldVersion;
342+
if (fs_read_atomic_int(version_path, &oldVersion) == -1) {
343+
oldVersion = 0;
348344
}
345+
int version = oldVersion;
349346

350347
// /data/user
351348
char *user_data_dir = build_string2(android_data_dir.path, SECONDARY_USER_PREFIX);
@@ -376,16 +373,12 @@ int initialize_directories() {
376373
}
377374
}
378375

379-
// /data/media/0
380-
char owner_media_dir[PATH_MAX];
381-
create_persona_media_path(owner_media_dir, 0);
382-
383376
if (version == 0) {
384377
// Introducing multi-user, so migrate /data/media contents into /data/media/0
385-
ALOGD("Migrating /data/media for multi-user");
378+
ALOGD("Upgrading /data/media for multi-user");
386379

387380
// Ensure /data/media
388-
if (ensure_dir(android_media_dir.path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
381+
if (fs_prepare_dir(android_media_dir.path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
389382
goto fail;
390383
}
391384

@@ -402,10 +395,14 @@ int initialize_directories() {
402395
}
403396

404397
// Create /data/media again
405-
if (ensure_dir(android_media_dir.path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
398+
if (fs_prepare_dir(android_media_dir.path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
406399
goto fail;
407400
}
408401

402+
// /data/media/0
403+
char owner_media_dir[PATH_MAX];
404+
snprintf(owner_media_dir, PATH_MAX, "%s0", android_media_dir.path);
405+
409406
// Move any owner data into place
410407
if (access(media_tmp_dir, F_OK) == 0) {
411408
if (rename(media_tmp_dir, owner_media_dir) == -1) {
@@ -433,8 +430,7 @@ int initialize_directories() {
433430

434431
// /data/media/<user_id>
435432
snprintf(user_media_dir, PATH_MAX, "%s%s", android_media_dir.path, name);
436-
if (ensure_dir(user_media_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
437-
ALOGE("Failed to ensure %s: %s", user_media_dir, strerror(errno));
433+
if (fs_prepare_dir(user_media_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
438434
goto fail;
439435
}
440436
}
@@ -445,22 +441,46 @@ int initialize_directories() {
445441
version = 1;
446442
}
447443

448-
// Ensure /data/media/0 is always ready
449-
if (ensure_dir(owner_media_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
450-
goto fail;
444+
// /data/media/obb
445+
char media_obb_dir[PATH_MAX];
446+
snprintf(media_obb_dir, PATH_MAX, "%sobb", android_media_dir.path);
447+
448+
if (version == 1) {
449+
// Introducing /data/media/obb for sharing OBB across users; migrate
450+
// any existing OBB files from owner.
451+
ALOGD("Upgrading to shared /data/media/obb");
452+
453+
// /data/media/0/Android/obb
454+
char owner_obb_path[PATH_MAX];
455+
snprintf(owner_obb_path, PATH_MAX, "%s0/Android/obb", android_media_dir.path);
456+
457+
// Only move if target doesn't already exist
458+
if (access(media_obb_dir, F_OK) != 0 && access(owner_obb_path, F_OK) == 0) {
459+
if (rename(owner_obb_path, media_obb_dir) == -1) {
460+
ALOGE("Failed to move OBB from owner: %s", strerror(errno));
461+
goto fail;
462+
}
463+
}
464+
465+
version = 2;
451466
}
452467

453-
// Persist our current version
454-
file = fopen(version_path, "w");
455-
if (file != NULL) {
456-
fprintf(file, "%d", version);
457-
fsync(fileno(file));
458-
fclose(file);
459-
} else {
460-
ALOGE("Failed to save version to %s: %s", version_path, strerror(errno));
468+
if (ensure_media_user_dirs(0) == -1) {
469+
ALOGE("Failed to setup media for user 0");
470+
goto fail;
471+
}
472+
if (fs_prepare_dir(media_obb_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
461473
goto fail;
462474
}
463475

476+
// Persist layout version if changed
477+
if (version != oldVersion) {
478+
if (fs_write_atomic_int(version_path, version) == -1) {
479+
ALOGE("Failed to save version to %s: %s", version_path, strerror(errno));
480+
goto fail;
481+
}
482+
}
483+
464484
// Success!
465485
res = 0;
466486

cmds/installd/installd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <sys/types.h>
3333
#include <sys/wait.h>
3434

35+
#include <cutils/fs.h>
3536
#include <cutils/sockets.h>
3637
#include <cutils/log.h>
3738
#include <cutils/properties.h>

cmds/installd/utils.c

Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -991,39 +991,14 @@ char *build_string3(char *s1, char *s2, char *s3) {
991991
return result;
992992
}
993993

994-
/* Ensure that directory exists with given mode and owners. */
995-
int ensure_dir(const char* path, mode_t mode, uid_t uid, gid_t gid) {
996-
// Check if path needs to be created
997-
struct stat sb;
998-
if (stat(path, &sb) == -1) {
999-
if (errno == ENOENT) {
1000-
goto create;
1001-
} else {
1002-
ALOGE("Failed to stat(%s): %s", path, strerror(errno));
1003-
return -1;
1004-
}
1005-
}
1006-
1007-
// Exists, verify status
1008-
if (sb.st_mode == mode || sb.st_uid == uid || sb.st_gid == gid) {
1009-
return 0;
1010-
} else {
1011-
goto fixup;
1012-
}
1013-
1014-
create:
1015-
if (mkdir(path, mode) == -1) {
1016-
ALOGE("Failed to mkdir(%s): %s", path, strerror(errno));
1017-
return -1;
1018-
}
994+
/* Ensure that /data/media directories are prepared for given user. */
995+
int ensure_media_user_dirs(userid_t userid) {
996+
char media_user_path[PATH_MAX];
997+
char path[PATH_MAX];
1019998

1020-
fixup:
1021-
if (chown(path, uid, gid) == -1) {
1022-
ALOGE("Failed to chown(%s, %d, %d): %s", path, uid, gid, strerror(errno));
1023-
return -1;
1024-
}
1025-
if (chmod(path, mode) == -1) {
1026-
ALOGE("Failed to chown(%s, %d): %s", path, mode, strerror(errno));
999+
// Ensure /data/media/<userid> exists
1000+
create_persona_media_path(media_user_path, userid);
1001+
if (fs_prepare_dir(media_user_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) {
10271002
return -1;
10281003
}
10291004

0 commit comments

Comments
 (0)