Loading cmds/installd/CacheItem.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -38,12 +38,12 @@ CacheItem::CacheItem(FTSENT* p) { mParent = static_cast<CacheItem*>(p->fts_parent->fts_pointer); mParent = static_cast<CacheItem*>(p->fts_parent->fts_pointer); if (mParent) { if (mParent) { atomic = mParent->atomic; group = mParent->group; tombstone = mParent->tombstone; tombstone = mParent->tombstone; mName = p->fts_name; mName = p->fts_name; mName.insert(0, "/"); mName.insert(0, "/"); } else { } else { atomic = false; group = false; tombstone = false; tombstone = false; mName = p->fts_path; mName = p->fts_path; } } Loading cmds/installd/CacheItem.h +3 −3 Original line number Original line Diff line number Diff line Loading @@ -31,8 +31,8 @@ namespace installd { /** /** * Single cache item that can be purged to free up space. This may be an * Single cache item that can be purged to free up space. This may be an * isolated file, or an entire directory tree that should be atomically * isolated file, or an entire directory tree that should be deleted as a * deleted. * group. */ */ class CacheItem { class CacheItem { public: public: Loading @@ -46,7 +46,7 @@ public: short level; short level; bool directory; bool directory; bool atomic; bool group; bool tombstone; bool tombstone; int64_t size; int64_t size; time_t modified; time_t modified; Loading cmds/installd/CacheTracker.cpp +3 −3 Original line number Original line Diff line number Diff line Loading @@ -106,11 +106,11 @@ void CacheTracker::loadItemsFrom(const std::string& path) { switch (p->fts_info) { switch (p->fts_info) { case FTS_D: { case FTS_D: { auto item = static_cast<CacheItem*>(p->fts_pointer); auto item = static_cast<CacheItem*>(p->fts_pointer); item->atomic |= (getxattr(p->fts_path, kXattrCacheAtomic, nullptr, 0) >= 0); item->group |= (getxattr(p->fts_path, kXattrCacheGroup, nullptr, 0) >= 0); item->tombstone |= (getxattr(p->fts_path, kXattrCacheTombstone, nullptr, 0) >= 0); item->tombstone |= (getxattr(p->fts_path, kXattrCacheTombstone, nullptr, 0) >= 0); // When atomic, immediately collect all files under tree // When group, immediately collect all files under tree if (item->atomic) { if (item->group) { while ((p = fts_read(fts)) != nullptr) { while ((p = fts_read(fts)) != nullptr) { if (p->fts_info == FTS_DP && p->fts_level == item->level) break; if (p->fts_info == FTS_DP && p->fts_level == item->level) break; switch (p->fts_info) { switch (p->fts_info) { Loading cmds/installd/InstalldNativeService.cpp +9 −5 Original line number Original line Diff line number Diff line Loading @@ -768,15 +768,17 @@ binder::Status InstalldNativeService::freeCache(const std::unique_ptr<std::strin auto noop = (flags & FLAG_FREE_CACHE_NOOP); auto noop = (flags & FLAG_FREE_CACHE_NOOP); int64_t free = data_disk_free(data_path); int64_t free = data_disk_free(data_path); int64_t needed = freeStorageSize - free; if (free < 0) { if (free < 0) { return error("Failed to determine free space for " + data_path); return error("Failed to determine free space for " + data_path); } else if (free >= freeStorageSize) { return ok(); } } LOG(DEBUG) << "Found " << data_path << " with " << free << " free; caller requested " int64_t needed = freeStorageSize - free; << freeStorageSize; LOG(DEBUG) << "Device " << data_path << " has " << free << " free; requested " << freeStorageSize << "; needed " << needed; if (free >= freeStorageSize) { return ok(); } if (flags & FLAG_FREE_CACHE_V2) { if (flags & FLAG_FREE_CACHE_V2) { // This new cache strategy fairly removes files from UIDs by deleting // This new cache strategy fairly removes files from UIDs by deleting Loading Loading @@ -811,7 +813,9 @@ binder::Status InstalldNativeService::freeCache(const std::unique_ptr<std::strin tracker->cacheQuota = mCacheQuotas[uid]; tracker->cacheQuota = mCacheQuotas[uid]; } } if (tracker->cacheQuota == 0) { if (tracker->cacheQuota == 0) { #if MEASURE_DEBUG LOG(WARNING) << "UID " << uid << " has no cache quota; assuming 64MB"; LOG(WARNING) << "UID " << uid << " has no cache quota; assuming 64MB"; #endif tracker->cacheQuota = 67108864; tracker->cacheQuota = 67108864; } } trackers[uid] = tracker; trackers[uid] = tracker; Loading cmds/installd/tests/installd_cache_test.cpp +71 −62 Original line number Original line Diff line number Diff line Loading @@ -101,6 +101,7 @@ static int64_t free() { if (!statvfs("/data/local/tmp", &buf)) { if (!statvfs("/data/local/tmp", &buf)) { return buf.f_bavail * buf.f_bsize; return buf.f_bavail * buf.f_bsize; } else { } else { PLOG(ERROR) << "Failed to statvfs"; return -1; return -1; } } } } Loading Loading @@ -132,6 +133,8 @@ protected: }; }; TEST_F(CacheTest, FreeCache_All) { TEST_F(CacheTest, FreeCache_All) { LOG(INFO) << "FreeCache_All"; mkdir("com.example"); mkdir("com.example"); touch("com.example/normal", 1 * kMbInBytes, 60); touch("com.example/normal", 1 * kMbInBytes, 60); mkdir("com.example/cache"); mkdir("com.example/cache"); Loading @@ -152,6 +155,8 @@ TEST_F(CacheTest, FreeCache_All) { } } TEST_F(CacheTest, FreeCache_Age) { TEST_F(CacheTest, FreeCache_Age) { LOG(INFO) << "FreeCache_Age"; mkdir("com.example"); mkdir("com.example"); mkdir("com.example/cache"); mkdir("com.example/cache"); mkdir("com.example/cache/foo"); mkdir("com.example/cache/foo"); Loading @@ -172,6 +177,8 @@ TEST_F(CacheTest, FreeCache_Age) { } } TEST_F(CacheTest, FreeCache_Tombstone) { TEST_F(CacheTest, FreeCache_Tombstone) { LOG(INFO) << "FreeCache_Tombstone"; mkdir("com.example"); mkdir("com.example"); mkdir("com.example/cache"); mkdir("com.example/cache"); mkdir("com.example/cache/foo"); mkdir("com.example/cache/foo"); Loading Loading @@ -201,14 +208,16 @@ TEST_F(CacheTest, FreeCache_Tombstone) { EXPECT_EQ(0, size("com.example/cache/bar/bar2")); EXPECT_EQ(0, size("com.example/cache/bar/bar2")); } } TEST_F(CacheTest, FreeCache_Atomic) { TEST_F(CacheTest, FreeCache_Group) { LOG(INFO) << "FreeCache_Group"; mkdir("com.example"); mkdir("com.example"); mkdir("com.example/cache"); mkdir("com.example/cache"); mkdir("com.example/cache/foo"); mkdir("com.example/cache/foo"); touch("com.example/cache/foo/foo1", 1 * kMbInBytes, 60); touch("com.example/cache/foo/foo1", 1 * kMbInBytes, 60); touch("com.example/cache/foo/foo2", 1 * kMbInBytes, 120); touch("com.example/cache/foo/foo2", 1 * kMbInBytes, 120); setxattr("com.example/cache/foo", "user.cache_atomic"); setxattr("com.example/cache/foo", "user.cache_group"); service->freeCache(testUuid, free() + kKbInBytes, service->freeCache(testUuid, free() + kKbInBytes, FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); Loading @@ -217,25 +226,25 @@ TEST_F(CacheTest, FreeCache_Atomic) { EXPECT_EQ(-1, exists("com.example/cache/foo/foo2")); EXPECT_EQ(-1, exists("com.example/cache/foo/foo2")); } } TEST_F(CacheTest, FreeCache_AtomicTombstone) { TEST_F(CacheTest, FreeCache_GroupTombstone) { LOG(INFO) << "FreeCache_AtomicTombstone"; LOG(INFO) << "FreeCache_GroupTombstone"; mkdir("com.example"); mkdir("com.example"); mkdir("com.example/cache"); mkdir("com.example/cache"); // this dir must look really old for some reason? // this dir must look really old for some reason? mkdir("com.example/cache/atomic"); mkdir("com.example/cache/group"); touch("com.example/cache/atomic/file1", kMbInBytes, 120); touch("com.example/cache/group/file1", kMbInBytes, 120); touch("com.example/cache/atomic/file2", kMbInBytes, 120); touch("com.example/cache/group/file2", kMbInBytes, 120); mkdir("com.example/cache/atomic/dir"); mkdir("com.example/cache/group/dir"); touch("com.example/cache/atomic/dir/file1", kMbInBytes, 120); touch("com.example/cache/group/dir/file1", kMbInBytes, 120); touch("com.example/cache/atomic/dir/file2", kMbInBytes, 120); touch("com.example/cache/group/dir/file2", kMbInBytes, 120); mkdir("com.example/cache/atomic/tomb"); mkdir("com.example/cache/group/tomb"); touch("com.example/cache/atomic/tomb/file1", kMbInBytes, 120); touch("com.example/cache/group/tomb/file1", kMbInBytes, 120); touch("com.example/cache/atomic/tomb/file2", kMbInBytes, 120); touch("com.example/cache/group/tomb/file2", kMbInBytes, 120); mkdir("com.example/cache/atomic/tomb/dir"); mkdir("com.example/cache/group/tomb/dir"); touch("com.example/cache/atomic/tomb/dir/file1", kMbInBytes, 120); touch("com.example/cache/group/tomb/dir/file1", kMbInBytes, 120); touch("com.example/cache/atomic/tomb/dir/file2", kMbInBytes, 120); touch("com.example/cache/group/tomb/dir/file2", kMbInBytes, 120); mkdir("com.example/cache/tomb"); mkdir("com.example/cache/tomb"); touch("com.example/cache/tomb/file1", kMbInBytes, 240); touch("com.example/cache/tomb/file1", kMbInBytes, 240); Loading @@ -243,80 +252,80 @@ TEST_F(CacheTest, FreeCache_AtomicTombstone) { mkdir("com.example/cache/tomb/dir"); mkdir("com.example/cache/tomb/dir"); touch("com.example/cache/tomb/dir/file1", kMbInBytes, 240); touch("com.example/cache/tomb/dir/file1", kMbInBytes, 240); touch("com.example/cache/tomb/dir/file2", kMbInBytes, 240); touch("com.example/cache/tomb/dir/file2", kMbInBytes, 240); mkdir("com.example/cache/tomb/atomic"); mkdir("com.example/cache/tomb/group"); touch("com.example/cache/tomb/atomic/file1", kMbInBytes, 60); touch("com.example/cache/tomb/group/file1", kMbInBytes, 60); touch("com.example/cache/tomb/atomic/file2", kMbInBytes, 60); touch("com.example/cache/tomb/group/file2", kMbInBytes, 60); mkdir("com.example/cache/tomb/atomic/dir"); mkdir("com.example/cache/tomb/group/dir"); touch("com.example/cache/tomb/atomic/dir/file1", kMbInBytes, 60); touch("com.example/cache/tomb/group/dir/file1", kMbInBytes, 60); touch("com.example/cache/tomb/atomic/dir/file2", kMbInBytes, 60); touch("com.example/cache/tomb/group/dir/file2", kMbInBytes, 60); setxattr("com.example/cache/atomic", "user.cache_atomic"); setxattr("com.example/cache/group", "user.cache_group"); setxattr("com.example/cache/atomic/tomb", "user.cache_tombstone"); setxattr("com.example/cache/group/tomb", "user.cache_tombstone"); setxattr("com.example/cache/tomb", "user.cache_tombstone"); setxattr("com.example/cache/tomb", "user.cache_tombstone"); setxattr("com.example/cache/tomb/atomic", "user.cache_atomic"); setxattr("com.example/cache/tomb/group", "user.cache_group"); service->freeCache(testUuid, free() + kKbInBytes, service->freeCache(testUuid, free() + kKbInBytes, FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/dir/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/dir/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/dir/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/dir/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/tomb/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/tomb/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/tomb/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/tomb/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/tomb/dir/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/tomb/dir/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/tomb/dir/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/tomb/dir/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/group/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/group/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file2")); service->freeCache(testUuid, free() + kKbInBytes, service->freeCache(testUuid, free() + kKbInBytes, FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); EXPECT_EQ(-1, size("com.example/cache/atomic/file1")); EXPECT_EQ(-1, size("com.example/cache/group/file1")); EXPECT_EQ(-1, size("com.example/cache/atomic/file2")); EXPECT_EQ(-1, size("com.example/cache/group/file2")); EXPECT_EQ(-1, size("com.example/cache/atomic/dir/file1")); EXPECT_EQ(-1, size("com.example/cache/group/dir/file1")); EXPECT_EQ(-1, size("com.example/cache/atomic/dir/file2")); EXPECT_EQ(-1, size("com.example/cache/group/dir/file2")); EXPECT_EQ(0, size("com.example/cache/atomic/tomb/file1")); EXPECT_EQ(0, size("com.example/cache/group/tomb/file1")); EXPECT_EQ(0, size("com.example/cache/atomic/tomb/file2")); EXPECT_EQ(0, size("com.example/cache/group/tomb/file2")); EXPECT_EQ(0, size("com.example/cache/atomic/tomb/dir/file1")); EXPECT_EQ(0, size("com.example/cache/group/tomb/dir/file1")); EXPECT_EQ(0, size("com.example/cache/atomic/tomb/dir/file2")); EXPECT_EQ(0, size("com.example/cache/group/tomb/dir/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/group/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/group/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file2")); service->freeCache(testUuid, kTbInBytes, service->freeCache(testUuid, kTbInBytes, FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); EXPECT_EQ(-1, size("com.example/cache/atomic/file1")); EXPECT_EQ(-1, size("com.example/cache/group/file1")); EXPECT_EQ(-1, size("com.example/cache/atomic/file2")); EXPECT_EQ(-1, size("com.example/cache/group/file2")); EXPECT_EQ(-1, size("com.example/cache/atomic/dir/file1")); EXPECT_EQ(-1, size("com.example/cache/group/dir/file1")); EXPECT_EQ(-1, size("com.example/cache/atomic/dir/file2")); EXPECT_EQ(-1, size("com.example/cache/group/dir/file2")); EXPECT_EQ(0, size("com.example/cache/atomic/tomb/file1")); EXPECT_EQ(0, size("com.example/cache/group/tomb/file1")); EXPECT_EQ(0, size("com.example/cache/atomic/tomb/file2")); EXPECT_EQ(0, size("com.example/cache/group/tomb/file2")); EXPECT_EQ(0, size("com.example/cache/atomic/tomb/dir/file1")); EXPECT_EQ(0, size("com.example/cache/group/tomb/dir/file1")); EXPECT_EQ(0, size("com.example/cache/atomic/tomb/dir/file2")); EXPECT_EQ(0, size("com.example/cache/group/tomb/dir/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/dir/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/dir/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/group/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/group/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file2")); } } } // namespace installd } // namespace installd Loading Loading
cmds/installd/CacheItem.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -38,12 +38,12 @@ CacheItem::CacheItem(FTSENT* p) { mParent = static_cast<CacheItem*>(p->fts_parent->fts_pointer); mParent = static_cast<CacheItem*>(p->fts_parent->fts_pointer); if (mParent) { if (mParent) { atomic = mParent->atomic; group = mParent->group; tombstone = mParent->tombstone; tombstone = mParent->tombstone; mName = p->fts_name; mName = p->fts_name; mName.insert(0, "/"); mName.insert(0, "/"); } else { } else { atomic = false; group = false; tombstone = false; tombstone = false; mName = p->fts_path; mName = p->fts_path; } } Loading
cmds/installd/CacheItem.h +3 −3 Original line number Original line Diff line number Diff line Loading @@ -31,8 +31,8 @@ namespace installd { /** /** * Single cache item that can be purged to free up space. This may be an * Single cache item that can be purged to free up space. This may be an * isolated file, or an entire directory tree that should be atomically * isolated file, or an entire directory tree that should be deleted as a * deleted. * group. */ */ class CacheItem { class CacheItem { public: public: Loading @@ -46,7 +46,7 @@ public: short level; short level; bool directory; bool directory; bool atomic; bool group; bool tombstone; bool tombstone; int64_t size; int64_t size; time_t modified; time_t modified; Loading
cmds/installd/CacheTracker.cpp +3 −3 Original line number Original line Diff line number Diff line Loading @@ -106,11 +106,11 @@ void CacheTracker::loadItemsFrom(const std::string& path) { switch (p->fts_info) { switch (p->fts_info) { case FTS_D: { case FTS_D: { auto item = static_cast<CacheItem*>(p->fts_pointer); auto item = static_cast<CacheItem*>(p->fts_pointer); item->atomic |= (getxattr(p->fts_path, kXattrCacheAtomic, nullptr, 0) >= 0); item->group |= (getxattr(p->fts_path, kXattrCacheGroup, nullptr, 0) >= 0); item->tombstone |= (getxattr(p->fts_path, kXattrCacheTombstone, nullptr, 0) >= 0); item->tombstone |= (getxattr(p->fts_path, kXattrCacheTombstone, nullptr, 0) >= 0); // When atomic, immediately collect all files under tree // When group, immediately collect all files under tree if (item->atomic) { if (item->group) { while ((p = fts_read(fts)) != nullptr) { while ((p = fts_read(fts)) != nullptr) { if (p->fts_info == FTS_DP && p->fts_level == item->level) break; if (p->fts_info == FTS_DP && p->fts_level == item->level) break; switch (p->fts_info) { switch (p->fts_info) { Loading
cmds/installd/InstalldNativeService.cpp +9 −5 Original line number Original line Diff line number Diff line Loading @@ -768,15 +768,17 @@ binder::Status InstalldNativeService::freeCache(const std::unique_ptr<std::strin auto noop = (flags & FLAG_FREE_CACHE_NOOP); auto noop = (flags & FLAG_FREE_CACHE_NOOP); int64_t free = data_disk_free(data_path); int64_t free = data_disk_free(data_path); int64_t needed = freeStorageSize - free; if (free < 0) { if (free < 0) { return error("Failed to determine free space for " + data_path); return error("Failed to determine free space for " + data_path); } else if (free >= freeStorageSize) { return ok(); } } LOG(DEBUG) << "Found " << data_path << " with " << free << " free; caller requested " int64_t needed = freeStorageSize - free; << freeStorageSize; LOG(DEBUG) << "Device " << data_path << " has " << free << " free; requested " << freeStorageSize << "; needed " << needed; if (free >= freeStorageSize) { return ok(); } if (flags & FLAG_FREE_CACHE_V2) { if (flags & FLAG_FREE_CACHE_V2) { // This new cache strategy fairly removes files from UIDs by deleting // This new cache strategy fairly removes files from UIDs by deleting Loading Loading @@ -811,7 +813,9 @@ binder::Status InstalldNativeService::freeCache(const std::unique_ptr<std::strin tracker->cacheQuota = mCacheQuotas[uid]; tracker->cacheQuota = mCacheQuotas[uid]; } } if (tracker->cacheQuota == 0) { if (tracker->cacheQuota == 0) { #if MEASURE_DEBUG LOG(WARNING) << "UID " << uid << " has no cache quota; assuming 64MB"; LOG(WARNING) << "UID " << uid << " has no cache quota; assuming 64MB"; #endif tracker->cacheQuota = 67108864; tracker->cacheQuota = 67108864; } } trackers[uid] = tracker; trackers[uid] = tracker; Loading
cmds/installd/tests/installd_cache_test.cpp +71 −62 Original line number Original line Diff line number Diff line Loading @@ -101,6 +101,7 @@ static int64_t free() { if (!statvfs("/data/local/tmp", &buf)) { if (!statvfs("/data/local/tmp", &buf)) { return buf.f_bavail * buf.f_bsize; return buf.f_bavail * buf.f_bsize; } else { } else { PLOG(ERROR) << "Failed to statvfs"; return -1; return -1; } } } } Loading Loading @@ -132,6 +133,8 @@ protected: }; }; TEST_F(CacheTest, FreeCache_All) { TEST_F(CacheTest, FreeCache_All) { LOG(INFO) << "FreeCache_All"; mkdir("com.example"); mkdir("com.example"); touch("com.example/normal", 1 * kMbInBytes, 60); touch("com.example/normal", 1 * kMbInBytes, 60); mkdir("com.example/cache"); mkdir("com.example/cache"); Loading @@ -152,6 +155,8 @@ TEST_F(CacheTest, FreeCache_All) { } } TEST_F(CacheTest, FreeCache_Age) { TEST_F(CacheTest, FreeCache_Age) { LOG(INFO) << "FreeCache_Age"; mkdir("com.example"); mkdir("com.example"); mkdir("com.example/cache"); mkdir("com.example/cache"); mkdir("com.example/cache/foo"); mkdir("com.example/cache/foo"); Loading @@ -172,6 +177,8 @@ TEST_F(CacheTest, FreeCache_Age) { } } TEST_F(CacheTest, FreeCache_Tombstone) { TEST_F(CacheTest, FreeCache_Tombstone) { LOG(INFO) << "FreeCache_Tombstone"; mkdir("com.example"); mkdir("com.example"); mkdir("com.example/cache"); mkdir("com.example/cache"); mkdir("com.example/cache/foo"); mkdir("com.example/cache/foo"); Loading Loading @@ -201,14 +208,16 @@ TEST_F(CacheTest, FreeCache_Tombstone) { EXPECT_EQ(0, size("com.example/cache/bar/bar2")); EXPECT_EQ(0, size("com.example/cache/bar/bar2")); } } TEST_F(CacheTest, FreeCache_Atomic) { TEST_F(CacheTest, FreeCache_Group) { LOG(INFO) << "FreeCache_Group"; mkdir("com.example"); mkdir("com.example"); mkdir("com.example/cache"); mkdir("com.example/cache"); mkdir("com.example/cache/foo"); mkdir("com.example/cache/foo"); touch("com.example/cache/foo/foo1", 1 * kMbInBytes, 60); touch("com.example/cache/foo/foo1", 1 * kMbInBytes, 60); touch("com.example/cache/foo/foo2", 1 * kMbInBytes, 120); touch("com.example/cache/foo/foo2", 1 * kMbInBytes, 120); setxattr("com.example/cache/foo", "user.cache_atomic"); setxattr("com.example/cache/foo", "user.cache_group"); service->freeCache(testUuid, free() + kKbInBytes, service->freeCache(testUuid, free() + kKbInBytes, FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); Loading @@ -217,25 +226,25 @@ TEST_F(CacheTest, FreeCache_Atomic) { EXPECT_EQ(-1, exists("com.example/cache/foo/foo2")); EXPECT_EQ(-1, exists("com.example/cache/foo/foo2")); } } TEST_F(CacheTest, FreeCache_AtomicTombstone) { TEST_F(CacheTest, FreeCache_GroupTombstone) { LOG(INFO) << "FreeCache_AtomicTombstone"; LOG(INFO) << "FreeCache_GroupTombstone"; mkdir("com.example"); mkdir("com.example"); mkdir("com.example/cache"); mkdir("com.example/cache"); // this dir must look really old for some reason? // this dir must look really old for some reason? mkdir("com.example/cache/atomic"); mkdir("com.example/cache/group"); touch("com.example/cache/atomic/file1", kMbInBytes, 120); touch("com.example/cache/group/file1", kMbInBytes, 120); touch("com.example/cache/atomic/file2", kMbInBytes, 120); touch("com.example/cache/group/file2", kMbInBytes, 120); mkdir("com.example/cache/atomic/dir"); mkdir("com.example/cache/group/dir"); touch("com.example/cache/atomic/dir/file1", kMbInBytes, 120); touch("com.example/cache/group/dir/file1", kMbInBytes, 120); touch("com.example/cache/atomic/dir/file2", kMbInBytes, 120); touch("com.example/cache/group/dir/file2", kMbInBytes, 120); mkdir("com.example/cache/atomic/tomb"); mkdir("com.example/cache/group/tomb"); touch("com.example/cache/atomic/tomb/file1", kMbInBytes, 120); touch("com.example/cache/group/tomb/file1", kMbInBytes, 120); touch("com.example/cache/atomic/tomb/file2", kMbInBytes, 120); touch("com.example/cache/group/tomb/file2", kMbInBytes, 120); mkdir("com.example/cache/atomic/tomb/dir"); mkdir("com.example/cache/group/tomb/dir"); touch("com.example/cache/atomic/tomb/dir/file1", kMbInBytes, 120); touch("com.example/cache/group/tomb/dir/file1", kMbInBytes, 120); touch("com.example/cache/atomic/tomb/dir/file2", kMbInBytes, 120); touch("com.example/cache/group/tomb/dir/file2", kMbInBytes, 120); mkdir("com.example/cache/tomb"); mkdir("com.example/cache/tomb"); touch("com.example/cache/tomb/file1", kMbInBytes, 240); touch("com.example/cache/tomb/file1", kMbInBytes, 240); Loading @@ -243,80 +252,80 @@ TEST_F(CacheTest, FreeCache_AtomicTombstone) { mkdir("com.example/cache/tomb/dir"); mkdir("com.example/cache/tomb/dir"); touch("com.example/cache/tomb/dir/file1", kMbInBytes, 240); touch("com.example/cache/tomb/dir/file1", kMbInBytes, 240); touch("com.example/cache/tomb/dir/file2", kMbInBytes, 240); touch("com.example/cache/tomb/dir/file2", kMbInBytes, 240); mkdir("com.example/cache/tomb/atomic"); mkdir("com.example/cache/tomb/group"); touch("com.example/cache/tomb/atomic/file1", kMbInBytes, 60); touch("com.example/cache/tomb/group/file1", kMbInBytes, 60); touch("com.example/cache/tomb/atomic/file2", kMbInBytes, 60); touch("com.example/cache/tomb/group/file2", kMbInBytes, 60); mkdir("com.example/cache/tomb/atomic/dir"); mkdir("com.example/cache/tomb/group/dir"); touch("com.example/cache/tomb/atomic/dir/file1", kMbInBytes, 60); touch("com.example/cache/tomb/group/dir/file1", kMbInBytes, 60); touch("com.example/cache/tomb/atomic/dir/file2", kMbInBytes, 60); touch("com.example/cache/tomb/group/dir/file2", kMbInBytes, 60); setxattr("com.example/cache/atomic", "user.cache_atomic"); setxattr("com.example/cache/group", "user.cache_group"); setxattr("com.example/cache/atomic/tomb", "user.cache_tombstone"); setxattr("com.example/cache/group/tomb", "user.cache_tombstone"); setxattr("com.example/cache/tomb", "user.cache_tombstone"); setxattr("com.example/cache/tomb", "user.cache_tombstone"); setxattr("com.example/cache/tomb/atomic", "user.cache_atomic"); setxattr("com.example/cache/tomb/group", "user.cache_group"); service->freeCache(testUuid, free() + kKbInBytes, service->freeCache(testUuid, free() + kKbInBytes, FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/dir/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/dir/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/dir/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/dir/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/tomb/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/tomb/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/tomb/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/tomb/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/tomb/dir/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/tomb/dir/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/tomb/dir/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/group/tomb/dir/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/group/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/group/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file2")); service->freeCache(testUuid, free() + kKbInBytes, service->freeCache(testUuid, free() + kKbInBytes, FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); EXPECT_EQ(-1, size("com.example/cache/atomic/file1")); EXPECT_EQ(-1, size("com.example/cache/group/file1")); EXPECT_EQ(-1, size("com.example/cache/atomic/file2")); EXPECT_EQ(-1, size("com.example/cache/group/file2")); EXPECT_EQ(-1, size("com.example/cache/atomic/dir/file1")); EXPECT_EQ(-1, size("com.example/cache/group/dir/file1")); EXPECT_EQ(-1, size("com.example/cache/atomic/dir/file2")); EXPECT_EQ(-1, size("com.example/cache/group/dir/file2")); EXPECT_EQ(0, size("com.example/cache/atomic/tomb/file1")); EXPECT_EQ(0, size("com.example/cache/group/tomb/file1")); EXPECT_EQ(0, size("com.example/cache/atomic/tomb/file2")); EXPECT_EQ(0, size("com.example/cache/group/tomb/file2")); EXPECT_EQ(0, size("com.example/cache/atomic/tomb/dir/file1")); EXPECT_EQ(0, size("com.example/cache/group/tomb/dir/file1")); EXPECT_EQ(0, size("com.example/cache/atomic/tomb/dir/file2")); EXPECT_EQ(0, size("com.example/cache/group/tomb/dir/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file1")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file2")); EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/group/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/group/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file2")); service->freeCache(testUuid, kTbInBytes, service->freeCache(testUuid, kTbInBytes, FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA); EXPECT_EQ(-1, size("com.example/cache/atomic/file1")); EXPECT_EQ(-1, size("com.example/cache/group/file1")); EXPECT_EQ(-1, size("com.example/cache/atomic/file2")); EXPECT_EQ(-1, size("com.example/cache/group/file2")); EXPECT_EQ(-1, size("com.example/cache/atomic/dir/file1")); EXPECT_EQ(-1, size("com.example/cache/group/dir/file1")); EXPECT_EQ(-1, size("com.example/cache/atomic/dir/file2")); EXPECT_EQ(-1, size("com.example/cache/group/dir/file2")); EXPECT_EQ(0, size("com.example/cache/atomic/tomb/file1")); EXPECT_EQ(0, size("com.example/cache/group/tomb/file1")); EXPECT_EQ(0, size("com.example/cache/atomic/tomb/file2")); EXPECT_EQ(0, size("com.example/cache/group/tomb/file2")); EXPECT_EQ(0, size("com.example/cache/atomic/tomb/dir/file1")); EXPECT_EQ(0, size("com.example/cache/group/tomb/dir/file1")); EXPECT_EQ(0, size("com.example/cache/atomic/tomb/dir/file2")); EXPECT_EQ(0, size("com.example/cache/group/tomb/dir/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/dir/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/dir/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/group/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/group/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file1")); EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file2")); EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file2")); } } } // namespace installd } // namespace installd Loading