From 3dfae0c008576c873c4039bb4c2e54a6adf3720a Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Mon, 12 Dec 2016 17:32:56 -0700 Subject: Offer to measure disk stats using quotas. Now we're getting somewhere! This CL starts using quotactl() to read UID/GID quota statistics when called with FLAG_USE_QUOTA, otherwise it continues using the old heavy-weight traversal for calculation. We now set the recently defined per-app GID used for identifying cached data, and we use the sticky GID bit on cache directories to ensure that newly created data inherits the GID for tracking purposes. For any existing apps during an upgrade, an initial bootstrapping case will recursively set this new GID. This change also shuffles around a bunch of the tedious manual accounting logic so that we exactly match the new quota statistics. Test: builds, boots, quota stats match manual stats Bug: 27948817 Change-Id: I8512c3193ce698f197a3f446e625d6a1c74e7649 --- cmds/installd/utils.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'cmds/installd/utils.cpp') diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp index 37e303da97..e1a59d4d9a 100644 --- a/cmds/installd/utils.cpp +++ b/cmds/installd/utils.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -198,6 +199,12 @@ std::string create_data_media_path(const char* volume_uuid, userid_t userid) { return StringPrintf("%s/media/%u", create_data_path(volume_uuid).c_str(), userid); } +std::string create_data_media_package_path(const char* volume_uuid, userid_t userid, + const char* data_type, const char* package_name) { + return StringPrintf("%s/Android/%s/%s", create_data_media_path(volume_uuid, userid).c_str(), + data_type, package_name); +} + std::string create_data_misc_legacy_path(userid_t userid) { return StringPrintf("%s/misc/user/%u", create_data_path(nullptr).c_str(), userid); } @@ -216,6 +223,14 @@ std::string create_data_ref_profile_package_path(const char* package_name) { return StringPrintf("%s/ref/%s", android_profiles_dir.path, package_name); } +std::string create_data_dalvik_cache_path() { + return "/data/dalvik-cache"; +} + +std::string create_data_misc_foreign_dex_path(userid_t userid) { + return StringPrintf("/data/misc/profiles/cur/%d/foreign-dex", userid); +} + // Keep profile paths in sync with ActivityThread. constexpr const char* PRIMARY_PROFILE_NAME = "primary.prof"; @@ -255,6 +270,38 @@ std::vector get_known_users(const char* volume_uuid) { return users; } +int calculate_tree_size(const std::string& path, int64_t* size, + gid_t include_gid, gid_t exclude_gid) { + FTS *fts; + FTSENT *p; + char *argv[] = { (char*) path.c_str(), nullptr }; + if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_XDEV, NULL))) { + if (errno != ENOENT) { + PLOG(ERROR) << "Failed to fts_open " << path; + } + return -1; + } + while ((p = fts_read(fts)) != NULL) { + switch (p->fts_info) { + case FTS_D: + case FTS_DEFAULT: + case FTS_F: + case FTS_SL: + case FTS_SLNONE: + if (include_gid != 0 && p->fts_statp->st_gid != include_gid) { + break; + } + if (exclude_gid != 0 && p->fts_statp->st_gid == exclude_gid) { + break; + } + *size += (p->fts_statp->st_blocks * 512); + break; + } + } + fts_close(fts); + return 0; +} + int create_move_path(char path[PKG_PATH_MAX], const char* pkgname, const char* leaf, -- cgit v1.2.3-59-g8ed1b