From 28443c23fb22fd9cc07117842c4c2155e3fde5fc Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Tue, 30 May 2017 14:38:42 -0600 Subject: [PATCH] Consistent "low storage" behavior. When freeing cached data, the caller can now provide a "reserved" size which we won't clear cached data from. Bug: 38008706 Test: cts-tradefed run commandAndExit cts-dev -m CtsJobSchedulerTestCases -t android.jobscheduler.cts.StorageConstraintTest Test: cts-tradefed run commandAndExit cts-dev -m CtsAppSecurityHostTestCases -t android.appsecurity.cts.StorageHostTest Change-Id: Ieb91b3e5345a950d4785fd7915f520f0a68a567a (cherry picked from commit 60f8a5330ca921d936ae306bf6d17596b82b518c) --- cmds/installd/InstalldNativeService.cpp | 31 ++++++++++++++------------ cmds/installd/InstalldNativeService.h | 4 ++-- cmds/installd/binder/android/os/IInstalld.aidl | 3 ++- cmds/installd/tests/installd_cache_test.cpp | 16 ++++++------- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index 509dd92b14..dec23d3945 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -915,15 +915,8 @@ binder::Status InstalldNativeService::destroyUserData(const std::unique_ptr& uuid, - int64_t freeStorageSize, int32_t flags) { + int64_t targetFreeBytes, int64_t cacheReservedBytes, int32_t flags) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); std::lock_guard lock(mLock); @@ -938,11 +931,12 @@ binder::Status InstalldNativeService::freeCache(const std::unique_ptr= freeStorageSize) { + if (free >= targetFreeBytes) { return ok(); } @@ -999,6 +993,7 @@ binder::Status InstalldNativeService::freeCache(const std::unique_ptr left, std::shared_ptr right) { return (left->getCacheRatio() < right->getCacheRatio()); }; @@ -1007,6 +1002,7 @@ binder::Status InstalldNativeService::freeCache(const std::unique_ptrloadStats(); queue.push(it.second); + cacheTotal += it.second->cacheUsed; } ATRACE_END(); @@ -1023,6 +1019,12 @@ binder::Status InstalldNativeService::freeCache(const std::unique_ptr 0 && cleared >= (cacheTotal - cacheReservedBytes)) { + LOG(DEBUG) << "Refusing to clear cached data in reserved space"; + break; + } + // Find the best tracker to work with; this might involve swapping // if the active tracker is no longer the most over quota bool nextBetter = active && !queue.empty() @@ -1052,13 +1054,14 @@ binder::Status InstalldNativeService::freeCache(const std::unique_ptrcacheUsed -= item->size; needed -= item->size; + cleared += item->size; } // Verify that we're actually done before bailing, since sneaky // apps might be using hardlinks if (needed <= 0) { free = data_disk_free(data_path); - needed = freeStorageSize - free; + needed = targetFreeBytes - free; if (needed <= 0) { break; } else { @@ -1073,11 +1076,11 @@ binder::Status InstalldNativeService::freeCache(const std::unique_ptr= freeStorageSize) { + if (free >= targetFreeBytes) { return ok(); } else { return error(StringPrintf("Failed to free up %" PRId64 " on %s; final free space %" PRId64, - freeStorageSize, data_path.c_str(), free)); + targetFreeBytes, data_path.c_str(), free)); } } diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h index 200fc77341..7f7fa74cfb 100644 --- a/cmds/installd/InstalldNativeService.h +++ b/cmds/installd/InstalldNativeService.h @@ -99,8 +99,8 @@ public: binder::Status removeIdmap(const std::string& overlayApkPath); binder::Status rmPackageDir(const std::string& packageDir); binder::Status markBootComplete(const std::string& instructionSet); - binder::Status freeCache(const std::unique_ptr& uuid, int64_t freeStorageSize, - int32_t flags); + binder::Status freeCache(const std::unique_ptr& uuid, int64_t targetFreeBytes, + int64_t cacheReservedBytes, int32_t flags); binder::Status linkNativeLibraryDirectory(const std::unique_ptr& uuid, const std::string& packageName, const std::string& nativeLibPath32, int32_t userId); binder::Status createOatDir(const std::string& oatDir, const std::string& instructionSet); diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl index 6b99c1dbf9..6185ecb607 100644 --- a/cmds/installd/binder/android/os/IInstalld.aidl +++ b/cmds/installd/binder/android/os/IInstalld.aidl @@ -64,7 +64,8 @@ interface IInstalld { void removeIdmap(@utf8InCpp String overlayApkPath); void rmPackageDir(@utf8InCpp String packageDir); void markBootComplete(@utf8InCpp String instructionSet); - void freeCache(@nullable @utf8InCpp String uuid, long freeStorageSize, int flags); + void freeCache(@nullable @utf8InCpp String uuid, long targetFreeBytes, + long cacheReservedBytes, int flags); void linkNativeLibraryDirectory(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName, @utf8InCpp String nativeLibPath32, int userId); void createOatDir(@utf8InCpp String oatDir, @utf8InCpp String instructionSet); diff --git a/cmds/installd/tests/installd_cache_test.cpp b/cmds/installd/tests/installd_cache_test.cpp index 174ce77026..aed068c390 100644 --- a/cmds/installd/tests/installd_cache_test.cpp +++ b/cmds/installd/tests/installd_cache_test.cpp @@ -146,7 +146,7 @@ TEST_F(CacheTest, FreeCache_All) { EXPECT_EQ(0, exists("com.example/cache/foo/one")); EXPECT_EQ(0, exists("com.example/cache/foo/two")); - service->freeCache(testUuid, kTbInBytes, + service->freeCache(testUuid, kTbInBytes, 0, FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); EXPECT_EQ(0, exists("com.example/normal")); @@ -163,13 +163,13 @@ TEST_F(CacheTest, FreeCache_Age) { touch("com.example/cache/foo/one", kMbInBytes, 60); touch("com.example/cache/foo/two", kMbInBytes, 120); - service->freeCache(testUuid, free() + kKbInBytes, + service->freeCache(testUuid, free() + kKbInBytes, 0, FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); EXPECT_EQ(-1, exists("com.example/cache/foo/one")); EXPECT_EQ(0, exists("com.example/cache/foo/two")); - service->freeCache(testUuid, free() + kKbInBytes, + service->freeCache(testUuid, free() + kKbInBytes, 0, FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); EXPECT_EQ(-1, exists("com.example/cache/foo/one")); @@ -197,7 +197,7 @@ TEST_F(CacheTest, FreeCache_Tombstone) { EXPECT_EQ(2 * kMbInBytes, size("com.example/cache/bar/bar1")); EXPECT_EQ(2 * kMbInBytes, size("com.example/cache/bar/bar2")); - service->freeCache(testUuid, kTbInBytes, + service->freeCache(testUuid, kTbInBytes, 0, FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); EXPECT_EQ(-1, exists("com.example/cache/foo/foo1")); @@ -219,7 +219,7 @@ TEST_F(CacheTest, FreeCache_Group) { setxattr("com.example/cache/foo", "user.cache_group"); - service->freeCache(testUuid, free() + kKbInBytes, + service->freeCache(testUuid, free() + kKbInBytes, 0, FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); EXPECT_EQ(-1, exists("com.example/cache/foo/foo1")); @@ -264,7 +264,7 @@ TEST_F(CacheTest, FreeCache_GroupTombstone) { setxattr("com.example/cache/tomb", "user.cache_tombstone"); setxattr("com.example/cache/tomb/group", "user.cache_group"); - service->freeCache(testUuid, free() + kKbInBytes, + service->freeCache(testUuid, free() + kKbInBytes, 0, FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/file1")); @@ -285,7 +285,7 @@ TEST_F(CacheTest, FreeCache_GroupTombstone) { EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file2")); - service->freeCache(testUuid, free() + kKbInBytes, + service->freeCache(testUuid, free() + kKbInBytes, 0, FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); EXPECT_EQ(-1, size("com.example/cache/group/file1")); @@ -306,7 +306,7 @@ TEST_F(CacheTest, FreeCache_GroupTombstone) { EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file2")); - service->freeCache(testUuid, kTbInBytes, + service->freeCache(testUuid, kTbInBytes, 0, FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); EXPECT_EQ(-1, size("com.example/cache/group/file1")); -- 2.11.0