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

Commit 7bf5b953 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Measure external storage using new GIDs.

We just defined a new range of GIDs that will be used to mark per-app
data files stored on external storage, so start measuring them.

Also measure all OBB files using another new GID that was defined.

Note that we're relying on the per-app cache GIDs to track cache
usage on *both* internal and external storage, which means that stats
and extStats won't always add up.  (The framework already combines
these values together, and we didn't want to waste precious GID
space on explicitly tracking cache files on external storage.)

Test: builds, boots
Bug: 27948817, 34263266
Change-Id: Ife087df299ff8ee1a75fce1e39b4b737cf9375d5
parent 45270e18
Loading
Loading
Loading
Loading
+92 −21
Original line number Original line Diff line number Diff line
@@ -1028,7 +1028,7 @@ static std::string toString(std::vector<int64_t> values) {
#endif
#endif


static void collectQuotaStats(const std::string& device, int32_t userId,
static void collectQuotaStats(const std::string& device, int32_t userId,
        int32_t appId, struct stats* stats, struct stats* extStats ATTRIBUTE_UNUSED) {
        int32_t appId, struct stats* stats, struct stats* extStats) {
    if (device.empty()) return;
    if (device.empty()) return;


    struct dqblk dq;
    struct dqblk dq;
@@ -1061,7 +1061,22 @@ static void collectQuotaStats(const std::string& device, int32_t userId,
        }
        }
    }
    }


    int sharedGid = multiuser_get_shared_app_gid(uid);
    int extGid = multiuser_get_ext_gid(userId, appId);
    if (extGid != -1) {
        if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), extGid,
                reinterpret_cast<char*>(&dq)) != 0) {
            if (errno != ESRCH) {
                PLOG(ERROR) << "Failed to quotactl " << device << " for GID " << extGid;
            }
        } else {
#if MEASURE_DEBUG
            LOG(DEBUG) << "quotactl() for GID " << extGid << " " << dq.dqb_curspace;
#endif
            extStats->dataSize += dq.dqb_curspace;
        }
    }

    int sharedGid = multiuser_get_shared_gid(userId, appId);
    if (sharedGid != -1) {
    if (sharedGid != -1) {
        if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), sharedGid,
        if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), sharedGid,
                reinterpret_cast<char*>(&dq)) != 0) {
                reinterpret_cast<char*>(&dq)) != 0) {
@@ -1075,10 +1090,6 @@ static void collectQuotaStats(const std::string& device, int32_t userId,
            stats->codeSize += dq.dqb_curspace;
            stats->codeSize += dq.dqb_curspace;
        }
        }
    }
    }

#if MEASURE_EXTERNAL
    // TODO: measure using external GIDs
#endif
}
}


static void collectManualStats(const std::string& path, struct stats* stats) {
static void collectManualStats(const std::string& path, struct stats* stats) {
@@ -1164,6 +1175,40 @@ static void collectManualStatsForUser(const std::string& path, struct stats* sta
    closedir(d);
    closedir(d);
}
}


static void collectManualExternalStatsForUser(const std::string& path, struct stats* stats) {
    FTS *fts;
    FTSENT *p;
    char *argv[] = { (char*) path.c_str(), nullptr };
    if (!(fts = fts_open(argv, FTS_PHYSICAL | FTS_XDEV, NULL))) {
        PLOG(ERROR) << "Failed to fts_open " << path;
        return;
    }
    while ((p = fts_read(fts)) != NULL) {
        switch (p->fts_info) {
        case FTS_D:
            if (p->fts_level == 4
                    && !strcmp(p->fts_name, "cache")
                    && !strcmp(p->fts_parent->fts_parent->fts_name, "data")
                    && !strcmp(p->fts_parent->fts_parent->fts_parent->fts_name, "Android")) {
                p->fts_number = 1;
            }
            p->fts_number = p->fts_parent->fts_number;
            // Fall through to count the directory
        case FTS_DEFAULT:
        case FTS_F:
        case FTS_SL:
        case FTS_SLNONE:
            int64_t size = (p->fts_statp->st_blocks * 512);
            if (p->fts_number == 1) {
                stats->cacheSize += size;
            }
            stats->dataSize += size;
            break;
        }
    }
    fts_close(fts);
}

binder::Status InstalldNativeService::getAppSize(const std::unique_ptr<std::string>& uuid,
binder::Status InstalldNativeService::getAppSize(const std::unique_ptr<std::string>& uuid,
        const std::vector<std::string>& packageNames, int32_t userId, int32_t flags,
        const std::vector<std::string>& packageNames, int32_t userId, int32_t flags,
        int32_t appId, const std::vector<int64_t>& ceDataInodes,
        int32_t appId, const std::vector<int64_t>& ceDataInodes,
@@ -1250,14 +1295,12 @@ binder::Status InstalldNativeService::getAppSize(const std::unique_ptr<std::stri
            calculate_tree_size(refProfilePath, &stats.codeSize);
            calculate_tree_size(refProfilePath, &stats.codeSize);
            ATRACE_END();
            ATRACE_END();


#if MEASURE_EXTERNAL
            ATRACE_BEGIN("external");
            ATRACE_BEGIN("external");
            auto extPath = create_data_media_package_path(uuid_, userId, pkgname, "data");
            auto extPath = create_data_media_package_path(uuid_, userId, pkgname, "data");
            collectManualStats(extPath, &extStats);
            collectManualStats(extPath, &extStats);
            auto mediaPath = create_data_media_package_path(uuid_, userId, pkgname, "media");
            auto mediaPath = create_data_media_package_path(uuid_, userId, pkgname, "media");
            calculate_tree_size(mediaPath, &extStats.dataSize);
            calculate_tree_size(mediaPath, &extStats.dataSize);
            ATRACE_END();
            ATRACE_END();
#endif
        }
        }


        ATRACE_BEGIN("dalvik");
        ATRACE_BEGIN("dalvik");
@@ -1306,17 +1349,28 @@ binder::Status InstalldNativeService::getUserSize(const std::unique_ptr<std::str


    const char* uuid_ = uuid ? uuid->c_str() : nullptr;
    const char* uuid_ = uuid ? uuid->c_str() : nullptr;


    ATRACE_BEGIN("obb");
    auto obbPath = create_data_path(uuid_) + "/media/obb";
    calculate_tree_size(obbPath, &extStats.codeSize);
    ATRACE_END();

    auto device = findQuotaDeviceForUuid(uuid);
    auto device = findQuotaDeviceForUuid(uuid);
    if (device.empty()) {
    if (device.empty()) {
        flags &= ~FLAG_USE_QUOTA;
        flags &= ~FLAG_USE_QUOTA;
    }
    }


    if (flags & FLAG_USE_QUOTA) {
    if (flags & FLAG_USE_QUOTA) {
        struct dqblk dq;

        ATRACE_BEGIN("obb");
        if (quotactl(QCMD(Q_GETQUOTA, GRPQUOTA), device.c_str(), AID_MEDIA_OBB,
                reinterpret_cast<char*>(&dq)) != 0) {
            if (errno != ESRCH) {
                PLOG(ERROR) << "Failed to quotactl " << device << " for GID " << AID_MEDIA_OBB;
            }
        } else {
#if MEASURE_DEBUG
            LOG(DEBUG) << "quotactl() for GID " << AID_MEDIA_OBB << " " << dq.dqb_curspace;
#endif
            extStats.codeSize += dq.dqb_curspace;
        }
        ATRACE_END();

        ATRACE_BEGIN("code");
        ATRACE_BEGIN("code");
        calculate_tree_size(create_data_app_path(uuid_), &stats.codeSize, -1, -1, true);
        calculate_tree_size(create_data_app_path(uuid_), &stats.codeSize, -1, -1, true);
        ATRACE_END();
        ATRACE_END();
@@ -1335,11 +1389,20 @@ binder::Status InstalldNativeService::getUserSize(const std::unique_ptr<std::str
        calculate_tree_size(refProfilePath, &stats.codeSize, -1, -1, true);
        calculate_tree_size(refProfilePath, &stats.codeSize, -1, -1, true);
        ATRACE_END();
        ATRACE_END();


#if MEASURE_EXTERNAL
        ATRACE_BEGIN("external");
        ATRACE_BEGIN("external");
        // TODO: measure external storage paths
        uid_t uid = multiuser_get_uid(userId, AID_MEDIA_RW);
        ATRACE_END();
        if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), device.c_str(), uid,
                reinterpret_cast<char*>(&dq)) != 0) {
            if (errno != ESRCH) {
                PLOG(ERROR) << "Failed to quotactl " << device << " for UID " << uid;
            }
        } else {
#if MEASURE_DEBUG
            LOG(DEBUG) << "quotactl() for UID " << uid << " " << dq.dqb_curspace;
#endif
#endif
            extStats.dataSize += dq.dqb_curspace;
        }
        ATRACE_END();


        ATRACE_BEGIN("dalvik");
        ATRACE_BEGIN("dalvik");
        calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
        calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize,
@@ -1360,6 +1423,11 @@ binder::Status InstalldNativeService::getUserSize(const std::unique_ptr<std::str
        }
        }
        ATRACE_END();
        ATRACE_END();
    } else {
    } else {
        ATRACE_BEGIN("obb");
        auto obbPath = create_data_path(uuid_) + "/media/obb";
        calculate_tree_size(obbPath, &extStats.codeSize);
        ATRACE_END();

        ATRACE_BEGIN("code");
        ATRACE_BEGIN("code");
        calculate_tree_size(create_data_app_path(uuid_), &stats.codeSize);
        calculate_tree_size(create_data_app_path(uuid_), &stats.codeSize);
        ATRACE_END();
        ATRACE_END();
@@ -1378,11 +1446,14 @@ binder::Status InstalldNativeService::getUserSize(const std::unique_ptr<std::str
        calculate_tree_size(refProfilePath, &stats.codeSize);
        calculate_tree_size(refProfilePath, &stats.codeSize);
        ATRACE_END();
        ATRACE_END();


#if MEASURE_EXTERNAL
        ATRACE_BEGIN("external");
        ATRACE_BEGIN("external");
        // TODO: measure external storage paths
        auto dataMediaPath = create_data_media_path(uuid_, userId);
        ATRACE_END();
        collectManualExternalStatsForUser(dataMediaPath, &extStats);
#if MEASURE_DEBUG
        LOG(DEBUG) << "Measured external data " << extStats.dataSize << " cache "
                << extStats.cacheSize;
#endif
#endif
        ATRACE_END();


        ATRACE_BEGIN("dalvik");
        ATRACE_BEGIN("dalvik");
        calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize);
        calculate_tree_size(create_data_dalvik_cache_path(), &stats.codeSize);
+0 −1
Original line number Original line Diff line number Diff line
@@ -31,7 +31,6 @@
#include <installd_constants.h>
#include <installd_constants.h>


#define MEASURE_DEBUG 0
#define MEASURE_DEBUG 0
#define MEASURE_EXTERNAL 0


namespace android {
namespace android {
namespace installd {
namespace installd {