Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ed909ae8 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

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
parent 7459281f
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -38,12 +38,12 @@ CacheItem::CacheItem(FTSENT* p) {

    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;
    }
+3 −3
Original line number Diff line number Diff line
@@ -31,8 +31,8 @@ namespace installd {

/**
 * 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 @@ public:

    short level;
    bool directory;
    bool atomic;
    bool group;
    bool tombstone;
    int64_t size;
    time_t modified;
+3 −3
Original line number Diff line number Diff line
@@ -106,11 +106,11 @@ void CacheTracker::loadItemsFrom(const std::string& path) {
        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) {
+9 −5
Original line number Diff line number Diff line
@@ -768,15 +768,17 @@ binder::Status InstalldNativeService::freeCache(const std::unique_ptr<std::strin
    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 @@ binder::Status InstalldNativeService::freeCache(const std::unique_ptr<std::strin
                            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;
+71 −62
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ static int64_t free() {
    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 @@ protected:
};

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_All) {
}

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_Age) {
}

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 @@ TEST_F(CacheTest, FreeCache_Tombstone) {
    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 @@ TEST_F(CacheTest, FreeCache_Atomic) {
    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 @@ TEST_F(CacheTest, FreeCache_AtomicTombstone) {
    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);

    setxattr("com.example/cache/atomic", "user.cache_atomic");
    setxattr("com.example/cache/atomic/tomb", "user.cache_tombstone");
    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/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
Loading