Follow "atomic" to "group" refactoring.
Remove noisy logging about UIDs that are relying on default cache
quota of 64MiB.
Move away from yucky old statfs() and use statvfs() instead.
Test: /data/nativetest/installd_cache_test/installd_cache_test
Bug: 35812899, 35684969, 36482620
Change-Id: I3d68da97eac2ebcda489bdf9d27061cac5b3f7cc
diff --git a/cmds/installd/CacheItem.cpp b/cmds/installd/CacheItem.cpp
index 0349b0f..17eb7ff 100644
--- a/cmds/installd/CacheItem.cpp
+++ b/cmds/installd/CacheItem.cpp
@@ -38,12 +38,12 @@
mParent = static_cast<CacheItem*>(p->fts_parent->fts_pointer);
if (mParent) {
- atomic = mParent->atomic;
+ group = mParent->group;
tombstone = mParent->tombstone;
mName = p->fts_name;
mName.insert(0, "/");
} else {
- atomic = false;
+ group = false;
tombstone = false;
mName = p->fts_path;
}
diff --git a/cmds/installd/CacheItem.h b/cmds/installd/CacheItem.h
index afbb15d..84b77aa 100644
--- a/cmds/installd/CacheItem.h
+++ b/cmds/installd/CacheItem.h
@@ -31,8 +31,8 @@
/**
* 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
- * deleted.
+ * isolated file, or an entire directory tree that should be deleted as a
+ * group.
*/
class CacheItem {
public:
@@ -46,7 +46,7 @@
short level;
bool directory;
- bool atomic;
+ bool group;
bool tombstone;
int64_t size;
time_t modified;
diff --git a/cmds/installd/CacheTracker.cpp b/cmds/installd/CacheTracker.cpp
index fada699..4bfc834 100644
--- a/cmds/installd/CacheTracker.cpp
+++ b/cmds/installd/CacheTracker.cpp
@@ -106,11 +106,11 @@
switch (p->fts_info) {
case FTS_D: {
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);
- // When atomic, immediately collect all files under tree
- if (item->atomic) {
+ // When group, immediately collect all files under tree
+ if (item->group) {
while ((p = fts_read(fts)) != nullptr) {
if (p->fts_info == FTS_DP && p->fts_level == item->level) break;
switch (p->fts_info) {
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 9006330..ca4be0a 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -768,15 +768,17 @@
auto noop = (flags & FLAG_FREE_CACHE_NOOP);
int64_t free = data_disk_free(data_path);
- int64_t needed = freeStorageSize - free;
if (free < 0) {
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 "
- << freeStorageSize;
+ int64_t needed = freeStorageSize - free;
+ LOG(DEBUG) << "Device " << data_path << " has " << free << " free; requested "
+ << freeStorageSize << "; needed " << needed;
+
+ if (free >= freeStorageSize) {
+ return ok();
+ }
if (flags & FLAG_FREE_CACHE_V2) {
// This new cache strategy fairly removes files from UIDs by deleting
@@ -811,7 +813,9 @@
tracker->cacheQuota = mCacheQuotas[uid];
}
if (tracker->cacheQuota == 0) {
+#if MEASURE_DEBUG
LOG(WARNING) << "UID " << uid << " has no cache quota; assuming 64MB";
+#endif
tracker->cacheQuota = 67108864;
}
trackers[uid] = tracker;
diff --git a/cmds/installd/tests/installd_cache_test.cpp b/cmds/installd/tests/installd_cache_test.cpp
index 50a47d2..360f71a 100644
--- a/cmds/installd/tests/installd_cache_test.cpp
+++ b/cmds/installd/tests/installd_cache_test.cpp
@@ -101,6 +101,7 @@
if (!statvfs("/data/local/tmp", &buf)) {
return buf.f_bavail * buf.f_bsize;
} else {
+ PLOG(ERROR) << "Failed to statvfs";
return -1;
}
}
@@ -132,6 +133,8 @@
};
TEST_F(CacheTest, FreeCache_All) {
+ LOG(INFO) << "FreeCache_All";
+
mkdir("com.example");
touch("com.example/normal", 1 * kMbInBytes, 60);
mkdir("com.example/cache");
@@ -152,6 +155,8 @@
}
TEST_F(CacheTest, FreeCache_Age) {
+ LOG(INFO) << "FreeCache_Age";
+
mkdir("com.example");
mkdir("com.example/cache");
mkdir("com.example/cache/foo");
@@ -172,6 +177,8 @@
}
TEST_F(CacheTest, FreeCache_Tombstone) {
+ LOG(INFO) << "FreeCache_Tombstone";
+
mkdir("com.example");
mkdir("com.example/cache");
mkdir("com.example/cache/foo");
@@ -201,14 +208,16 @@
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/cache");
mkdir("com.example/cache/foo");
touch("com.example/cache/foo/foo1", 1 * kMbInBytes, 60);
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,
FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA);
@@ -217,25 +226,25 @@
EXPECT_EQ(-1, exists("com.example/cache/foo/foo2"));
}
-TEST_F(CacheTest, FreeCache_AtomicTombstone) {
- LOG(INFO) << "FreeCache_AtomicTombstone";
+TEST_F(CacheTest, FreeCache_GroupTombstone) {
+ LOG(INFO) << "FreeCache_GroupTombstone";
mkdir("com.example");
mkdir("com.example/cache");
// this dir must look really old for some reason?
- mkdir("com.example/cache/atomic");
- touch("com.example/cache/atomic/file1", kMbInBytes, 120);
- touch("com.example/cache/atomic/file2", kMbInBytes, 120);
- mkdir("com.example/cache/atomic/dir");
- touch("com.example/cache/atomic/dir/file1", kMbInBytes, 120);
- touch("com.example/cache/atomic/dir/file2", kMbInBytes, 120);
- mkdir("com.example/cache/atomic/tomb");
- touch("com.example/cache/atomic/tomb/file1", kMbInBytes, 120);
- touch("com.example/cache/atomic/tomb/file2", kMbInBytes, 120);
- mkdir("com.example/cache/atomic/tomb/dir");
- touch("com.example/cache/atomic/tomb/dir/file1", kMbInBytes, 120);
- touch("com.example/cache/atomic/tomb/dir/file2", kMbInBytes, 120);
+ mkdir("com.example/cache/group");
+ touch("com.example/cache/group/file1", kMbInBytes, 120);
+ touch("com.example/cache/group/file2", kMbInBytes, 120);
+ mkdir("com.example/cache/group/dir");
+ touch("com.example/cache/group/dir/file1", kMbInBytes, 120);
+ touch("com.example/cache/group/dir/file2", kMbInBytes, 120);
+ mkdir("com.example/cache/group/tomb");
+ touch("com.example/cache/group/tomb/file1", kMbInBytes, 120);
+ touch("com.example/cache/group/tomb/file2", kMbInBytes, 120);
+ mkdir("com.example/cache/group/tomb/dir");
+ touch("com.example/cache/group/tomb/dir/file1", kMbInBytes, 120);
+ touch("com.example/cache/group/tomb/dir/file2", kMbInBytes, 120);
mkdir("com.example/cache/tomb");
touch("com.example/cache/tomb/file1", kMbInBytes, 240);
@@ -243,80 +252,80 @@
mkdir("com.example/cache/tomb/dir");
touch("com.example/cache/tomb/dir/file1", kMbInBytes, 240);
touch("com.example/cache/tomb/dir/file2", kMbInBytes, 240);
- mkdir("com.example/cache/tomb/atomic");
- touch("com.example/cache/tomb/atomic/file1", kMbInBytes, 60);
- touch("com.example/cache/tomb/atomic/file2", kMbInBytes, 60);
- mkdir("com.example/cache/tomb/atomic/dir");
- touch("com.example/cache/tomb/atomic/dir/file1", kMbInBytes, 60);
- touch("com.example/cache/tomb/atomic/dir/file2", kMbInBytes, 60);
+ mkdir("com.example/cache/tomb/group");
+ touch("com.example/cache/tomb/group/file1", kMbInBytes, 60);
+ touch("com.example/cache/tomb/group/file2", kMbInBytes, 60);
+ mkdir("com.example/cache/tomb/group/dir");
+ touch("com.example/cache/tomb/group/dir/file1", kMbInBytes, 60);
+ touch("com.example/cache/tomb/group/dir/file2", kMbInBytes, 60);
- setxattr("com.example/cache/atomic", "user.cache_atomic");
- setxattr("com.example/cache/atomic/tomb", "user.cache_tombstone");
+ setxattr("com.example/cache/group", "user.cache_group");
+ setxattr("com.example/cache/group/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,
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/atomic/file2"));
- EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/dir/file1"));
- EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/dir/file2"));
- EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/tomb/file1"));
- EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/tomb/file2"));
- EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/tomb/dir/file1"));
- EXPECT_EQ(kMbInBytes, size("com.example/cache/atomic/tomb/dir/file2"));
+ EXPECT_EQ(kMbInBytes, size("com.example/cache/group/file1"));
+ EXPECT_EQ(kMbInBytes, size("com.example/cache/group/file2"));
+ EXPECT_EQ(kMbInBytes, size("com.example/cache/group/dir/file1"));
+ EXPECT_EQ(kMbInBytes, size("com.example/cache/group/dir/file2"));
+ EXPECT_EQ(kMbInBytes, size("com.example/cache/group/tomb/file1"));
+ EXPECT_EQ(kMbInBytes, size("com.example/cache/group/tomb/file2"));
+ EXPECT_EQ(kMbInBytes, size("com.example/cache/group/tomb/dir/file1"));
+ 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/file2"));
EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file1"));
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/atomic/file2"));
- EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file1"));
- EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file2"));
+ EXPECT_EQ(0, size("com.example/cache/tomb/group/file1"));
+ EXPECT_EQ(0, size("com.example/cache/tomb/group/file2"));
+ 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,
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/atomic/file2"));
- EXPECT_EQ(-1, size("com.example/cache/atomic/dir/file1"));
- EXPECT_EQ(-1, size("com.example/cache/atomic/dir/file2"));
- EXPECT_EQ(0, size("com.example/cache/atomic/tomb/file1"));
- EXPECT_EQ(0, size("com.example/cache/atomic/tomb/file2"));
- EXPECT_EQ(0, size("com.example/cache/atomic/tomb/dir/file1"));
- EXPECT_EQ(0, size("com.example/cache/atomic/tomb/dir/file2"));
+ EXPECT_EQ(-1, size("com.example/cache/group/file1"));
+ EXPECT_EQ(-1, size("com.example/cache/group/file2"));
+ EXPECT_EQ(-1, size("com.example/cache/group/dir/file1"));
+ EXPECT_EQ(-1, size("com.example/cache/group/dir/file2"));
+ EXPECT_EQ(0, size("com.example/cache/group/tomb/file1"));
+ EXPECT_EQ(0, size("com.example/cache/group/tomb/file2"));
+ EXPECT_EQ(0, size("com.example/cache/group/tomb/dir/file1"));
+ 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/file2"));
EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file1"));
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/atomic/file2"));
- EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file1"));
- EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file2"));
+ EXPECT_EQ(0, size("com.example/cache/tomb/group/file1"));
+ EXPECT_EQ(0, size("com.example/cache/tomb/group/file2"));
+ 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,
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/atomic/file2"));
- EXPECT_EQ(-1, size("com.example/cache/atomic/dir/file1"));
- EXPECT_EQ(-1, size("com.example/cache/atomic/dir/file2"));
- EXPECT_EQ(0, size("com.example/cache/atomic/tomb/file1"));
- EXPECT_EQ(0, size("com.example/cache/atomic/tomb/file2"));
- EXPECT_EQ(0, size("com.example/cache/atomic/tomb/dir/file1"));
- EXPECT_EQ(0, size("com.example/cache/atomic/tomb/dir/file2"));
+ EXPECT_EQ(-1, size("com.example/cache/group/file1"));
+ EXPECT_EQ(-1, size("com.example/cache/group/file2"));
+ EXPECT_EQ(-1, size("com.example/cache/group/dir/file1"));
+ EXPECT_EQ(-1, size("com.example/cache/group/dir/file2"));
+ EXPECT_EQ(0, size("com.example/cache/group/tomb/file1"));
+ EXPECT_EQ(0, size("com.example/cache/group/tomb/file2"));
+ EXPECT_EQ(0, size("com.example/cache/group/tomb/dir/file1"));
+ 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/file2"));
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/atomic/file1"));
- EXPECT_EQ(0, size("com.example/cache/tomb/atomic/file2"));
- EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file1"));
- EXPECT_EQ(0, size("com.example/cache/tomb/atomic/dir/file2"));
+ EXPECT_EQ(0, size("com.example/cache/tomb/group/file1"));
+ EXPECT_EQ(0, size("com.example/cache/tomb/group/file2"));
+ EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file1"));
+ EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file2"));
}
} // namespace installd
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index 97298e5..03ee23f 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -23,12 +23,7 @@
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/xattr.h>
-
-#if defined(__APPLE__)
-#include <sys/mount.h>
-#else
-#include <sys/statfs.h>
-#endif
+#include <sys/statvfs.h>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
@@ -637,11 +632,11 @@
int64_t data_disk_free(const std::string& data_path)
{
- struct statfs sfs;
- if (statfs(data_path.c_str(), &sfs) == 0) {
+ struct statvfs sfs;
+ if (statvfs(data_path.c_str(), &sfs) == 0) {
return sfs.f_bavail * sfs.f_bsize;
} else {
- PLOG(ERROR) << "Couldn't statfs " << data_path;
+ PLOG(ERROR) << "Couldn't statvfs " << data_path;
return -1;
}
}
diff --git a/cmds/installd/utils.h b/cmds/installd/utils.h
index abe6830..a4eb1f6 100644
--- a/cmds/installd/utils.h
+++ b/cmds/installd/utils.h
@@ -66,7 +66,7 @@
constexpr const char* kXattrInodeCache = "user.inode_cache";
constexpr const char* kXattrInodeCodeCache = "user.inode_code_cache";
-constexpr const char* kXattrCacheAtomic = "user.cache_atomic";
+constexpr const char* kXattrCacheGroup = "user.cache_group";
constexpr const char* kXattrCacheTombstone = "user.cache_tombstone";
int create_pkg_path(char path[PKG_PATH_MAX],