diff options
author | 2019-01-29 21:11:50 +0000 | |
---|---|---|
committer | 2019-01-29 21:11:50 +0000 | |
commit | 3163e53e920bc225c8128f346b3daa009a241e08 (patch) | |
tree | a6da2503a8f9d02c03819cc789a5de892178e50c | |
parent | d1569ad0045cc1b61ab6cc708d838de5386fbbc5 (diff) | |
parent | 900b3c2127c16cc8d3e55a5d936cb4d11b0eb6d4 (diff) |
Merge "installd: clear app's cache before doing a snapshot"
-rw-r--r-- | cmds/installd/InstalldNativeService.cpp | 21 | ||||
-rw-r--r-- | cmds/installd/tests/installd_service_test.cpp | 55 |
2 files changed, 73 insertions, 3 deletions
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index cae212c8a8..7da5642fa3 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -766,9 +766,6 @@ static int32_t copy_directory_recursive(const char* from, const char* to) { return android_fork_execvp(ARRAY_SIZE(argv), argv, nullptr, false, true); } -// TODO(narayan): We should pass through the ceDataInode so that we can call -// clearAppData(FLAG_CLEAR_CACHE_ONLY | FLAG_CLEAR_CODE_CACHE before we commence -// the copy. binder::Status InstalldNativeService::snapshotAppData( const std::unique_ptr<std::string>& volumeUuid, const std::string& packageName, int32_t user, int32_t storageFlags) { @@ -813,6 +810,24 @@ binder::Status InstalldNativeService::snapshotAppData( return ok(); } + // ce_data_inode is not needed when FLAG_CLEAR_CACHE_ONLY is set. + binder::Status clear_cache_result = clearAppData(volumeUuid, packageName, user, + storageFlags | FLAG_CLEAR_CACHE_ONLY, 0); + if (!clear_cache_result.isOk()) { + // It should be fine to continue snapshot if we for some reason failed + // to clear cache. + LOG(WARNING) << "Failed to clear cache of app " << packageName; + } + + // ce_data_inode is not needed when FLAG_CLEAR_CODE_CACHE_ONLY is set. + binder::Status clear_code_cache_result = clearAppData(volumeUuid, packageName, user, + storageFlags | FLAG_CLEAR_CODE_CACHE_ONLY, 0); + if (!clear_code_cache_result.isOk()) { + // It should be fine to continue snapshot if we for some reason failed + // to clear code_cache. + LOG(WARNING) << "Failed to clear code_cache of app " << packageName; + } + if (storageFlags & FLAG_STORAGE_DE) { auto from = create_data_user_de_package_path(volume_uuid, user, package_name); auto to = create_data_misc_de_rollback_path(volume_uuid, user); diff --git a/cmds/installd/tests/installd_service_test.cpp b/cmds/installd/tests/installd_service_test.cpp index 29eb6c5dd7..ee22e86005 100644 --- a/cmds/installd/tests/installd_service_test.cpp +++ b/cmds/installd/tests/installd_service_test.cpp @@ -433,6 +433,61 @@ TEST_F(ServiceTest, SnapshotAppData_WrongVolumeUuid) { "com.foo", 0, FLAG_STORAGE_DE).isOk()); } +TEST_F(ServiceTest, CreateAppDataSnapshot_ClearsCache) { + auto fake_package_ce_path = create_data_user_ce_package_path("TEST", 0, "com.foo"); + auto fake_package_de_path = create_data_user_de_package_path("TEST", 0, "com.foo"); + auto fake_package_ce_cache_path = read_path_inode(fake_package_ce_path, + "cache", kXattrInodeCache); + auto fake_package_ce_code_cache_path = read_path_inode(fake_package_ce_path, + "code_cache", kXattrInodeCache); + auto fake_package_de_cache_path = fake_package_de_path + "/cache"; + auto fake_package_de_code_cache_path = fake_package_de_path + "/code_cache"; + + ASSERT_TRUE(mkdirs(fake_package_ce_path, 700)); + ASSERT_TRUE(mkdirs(fake_package_de_path, 700)); + ASSERT_TRUE(mkdirs(fake_package_ce_cache_path, 700)); + ASSERT_TRUE(mkdirs(fake_package_ce_code_cache_path, 700)); + ASSERT_TRUE(mkdirs(fake_package_de_cache_path, 700)); + ASSERT_TRUE(mkdirs(fake_package_de_code_cache_path, 700)); + + auto deleter = [&fake_package_ce_path, &fake_package_de_path, + &fake_package_ce_cache_path, &fake_package_ce_code_cache_path, + &fake_package_de_cache_path, &fake_package_de_code_cache_path]() { + delete_dir_contents(fake_package_ce_path, true); + delete_dir_contents(fake_package_de_path, true); + delete_dir_contents(fake_package_ce_cache_path, true); + delete_dir_contents(fake_package_ce_code_cache_path, true); + delete_dir_contents(fake_package_de_cache_path, true); + delete_dir_contents(fake_package_de_code_cache_path, true); + rmdir(fake_package_ce_cache_path.c_str()); + rmdir(fake_package_ce_code_cache_path.c_str()); + rmdir(fake_package_de_cache_path.c_str()); + rmdir(fake_package_de_code_cache_path.c_str()); + }; + auto scope_guard = android::base::make_scope_guard(deleter); + + ASSERT_TRUE(android::base::WriteStringToFile( + "TEST_CONTENT_CE", fake_package_ce_cache_path + "/file1", + 0700, 10000, 20000, false /* follow_symlinks */)); + ASSERT_TRUE(android::base::WriteStringToFile( + "TEST_CONTENT_CE", fake_package_ce_code_cache_path + "/file1", + 0700, 10000, 20000, false /* follow_symlinks */)); + ASSERT_TRUE(android::base::WriteStringToFile( + "TEST_CONTENT_DE", fake_package_de_cache_path + "/file1", + 0700, 10000, 20000, false /* follow_symlinks */)); + ASSERT_TRUE(android::base::WriteStringToFile( + "TEST_CONTENT_DE", fake_package_de_code_cache_path + "/file1", + 0700, 10000, 20000, false /* follow_symlinks */)); + ASSERT_TRUE(service->snapshotAppData(std::make_unique<std::string>("TEST"), + "com.foo", 0, FLAG_STORAGE_CE | FLAG_STORAGE_DE).isOk()); + // The snapshot call must clear cache. + struct stat sb; + ASSERT_EQ(-1, stat((fake_package_ce_cache_path + "/file1").c_str(), &sb)); + ASSERT_EQ(-1, stat((fake_package_ce_code_cache_path + "/file1").c_str(), &sb)); + ASSERT_EQ(-1, stat((fake_package_de_cache_path + "/file1").c_str(), &sb)); + ASSERT_EQ(-1, stat((fake_package_de_code_cache_path + "/file1").c_str(), &sb)); +} + TEST_F(ServiceTest, RestoreAppDataSnapshot) { auto rollback_ce_dir = create_data_misc_ce_rollback_path("TEST", 0); auto rollback_de_dir = create_data_misc_de_rollback_path("TEST", 0); |