summaryrefslogtreecommitdiff
path: root/cmds/installd/CacheTracker.cpp
diff options
context:
space:
mode:
author Jeff Sharkey <jsharkey@android.com> 2017-02-21 18:30:28 -0700
committer Jeff Sharkey <jsharkey@android.com> 2017-02-22 11:44:00 -0700
commit871a8f236ef2a055b9955b47a342b2c44c020ef7 (patch)
tree5a244a3f593ac20f0fd771a8ae8ca37b7fb90aeb /cmds/installd/CacheTracker.cpp
parent42714ad63c08899719bc1a6fe7fb3966fd66f0a8 (diff)
Logic for atmoic/tombstone behavior; split mode.
Flesh out logic for cache directories that request new atomic and/or tombstone clearing behaviors. Atomic directories are considered for deletion as a single all-or-nothing unit, and tombstone directories truncate any removed files instead of unlinking them. Since these behaviors can be mixed together, add local tests that quickly verify several different permutations. Reduce memory footprint of CacheItem objects by only storing name and pointer to parent (instead of full path). Fix ordering bug by switching to std::stable_sort. Add "V2_DEFY_QUOTA" flag so we can split clearing into two distinct phases: clearing data for apps above their quotas, and then pushing deeper by clearing data for apps below their quotas. Test: adb shell /data/nativetest64/installd_cache_test/installd_cache_test Bug: 34692014, 33811826 Change-Id: I156897de1d1d1c371b2b837128b2e286bf33d40d
Diffstat (limited to 'cmds/installd/CacheTracker.cpp')
-rw-r--r--cmds/installd/CacheTracker.cpp68
1 files changed, 49 insertions, 19 deletions
diff --git a/cmds/installd/CacheTracker.cpp b/cmds/installd/CacheTracker.cpp
index 23c4330ca2..9377836ad6 100644
--- a/cmds/installd/CacheTracker.cpp
+++ b/cmds/installd/CacheTracker.cpp
@@ -20,6 +20,7 @@
#include <fts.h>
#include <sys/quota.h>
+#include <sys/xattr.h>
#include <utils/Trace.h>
#include <android-base/logging.h>
@@ -86,30 +87,59 @@ void CacheTracker::loadItemsFrom(const std::string& path) {
PLOG(WARNING) << "Failed to fts_open " << path;
return;
}
- // TODO: add support for "user.atomic" and "user.tombstone" xattrs
- while ((p = fts_read(fts)) != NULL) {
+ while ((p = fts_read(fts)) != nullptr) {
+ if (p->fts_level == 0) continue;
+
+ // Create tracking nodes for everything we encounter
switch (p->fts_info) {
case FTS_D:
- // Track the newest mtime of anything inside so we consider
- // deleting the directory last
- p->fts_number = p->fts_statp->st_mtime;
- break;
- case FTS_DP:
- p->fts_statp->st_mtime = p->fts_number;
+ case FTS_DEFAULT:
+ case FTS_F:
+ case FTS_SL:
+ case FTS_SLNONE: {
+ auto item = std::shared_ptr<CacheItem>(new CacheItem(p));
+ p->fts_pointer = static_cast<void*>(item.get());
+ items.push_back(item);
+ }
+ }
+
+ 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->tombstone |= (getxattr(p->fts_path, kXattrCacheTombstone, nullptr, 0) >= 0);
+
+ // When atomic, immediately collect all files under tree
+ if (item->atomic) {
+ while ((p = fts_read(fts)) != nullptr) {
+ if (p->fts_info == FTS_DP && p->fts_level == item->level) break;
+ switch (p->fts_info) {
+ case FTS_D:
+ case FTS_DEFAULT:
+ case FTS_F:
+ case FTS_SL:
+ case FTS_SLNONE:
+ item->size += p->fts_statp->st_blocks * 512;
+ item->modified = std::max(item->modified, p->fts_statp->st_mtime);
+ }
+ }
+ }
+ }
+ }
- // Ignore the actual top-level cache directories
- if (p->fts_level == 0) break;
+ // Bubble up modified time to parent
+ switch (p->fts_info) {
+ case FTS_DP:
case FTS_DEFAULT:
case FTS_F:
case FTS_SL:
- case FTS_SLNONE:
- // TODO: optimize path memory footprint
- items.push_back(std::shared_ptr<CacheItem>(new CacheItem(nullptr, p)));
-
- // Track the newest modified item under this tree
- p->fts_parent->fts_number =
- std::max(p->fts_parent->fts_number, p->fts_statp->st_mtime);
- break;
+ case FTS_SLNONE: {
+ auto item = static_cast<CacheItem*>(p->fts_pointer);
+ auto parent = static_cast<CacheItem*>(p->fts_parent->fts_pointer);
+ if (parent) {
+ parent->modified = std::max(parent->modified, item->modified);
+ }
+ }
}
}
fts_close(fts);
@@ -137,7 +167,7 @@ void CacheTracker::loadItems() {
}
return left->directory;
};
- std::sort(items.begin(), items.end(), cmp);
+ std::stable_sort(items.begin(), items.end(), cmp);
ATRACE_END();
}