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

Commit a32913f0 authored by Howard Ro's avatar Howard Ro Committed by Android (Google) Code Review
Browse files

Merge "Add a check for duplicate configuration on statsd" into pi-dev

parents feb9daff 4490765d
Loading
Loading
Loading
Loading
+22 −10
Original line number Diff line number Diff line
@@ -68,12 +68,25 @@ void ConfigManager::UpdateConfig(const ConfigKey& key, const StatsdConfig& confi
    {
        lock_guard <mutex> lock(mMutex);

        auto it = mConfigs.find(key);

        const int numBytes = config.ByteSize();
        vector<uint8_t> buffer(numBytes);
        config.SerializeToArray(&buffer[0], numBytes);

        const bool isDuplicate =
            it != mConfigs.end() &&
            StorageManager::hasIdenticalConfig(key, buffer);

        // Update saved file on disk. We still update timestamp of file when
        // there exists a duplicate configuration to avoid garbage collection.
        update_saved_configs_locked(key, buffer, numBytes);

        if (isDuplicate) return;

        // Add to set
        mConfigs.insert(key);

        // Save to disk
        update_saved_configs_locked(key, config);

        for (sp<ConfigListener> listener : mListeners) {
            broadcastList.push_back(listener);
        }
@@ -137,7 +150,6 @@ void ConfigManager::RemoveConfigs(int uid) {
    {
        lock_guard <mutex> lock(mMutex);


        for (auto it = mConfigs.begin(); it != mConfigs.end();) {
            // Remove from map
            if (it->GetUid() == uid) {
@@ -230,16 +242,16 @@ void ConfigManager::Dump(FILE* out) {
    }
}

void ConfigManager::update_saved_configs_locked(const ConfigKey& key, const StatsdConfig& config) {
void ConfigManager::update_saved_configs_locked(const ConfigKey& key,
                                                const vector<uint8_t>& buffer,
                                                const int numBytes) {
    // If there is a pre-existing config with same key we should first delete it.
    remove_saved_configs(key);

    // Then we save the latest config.
    string file_name = StringPrintf("%s/%ld_%d_%lld", STATS_SERVICE_DIR, time(nullptr),
    string file_name =
        StringPrintf("%s/%ld_%d_%lld", STATS_SERVICE_DIR, time(nullptr),
                     key.GetUid(), (long long)key.GetId());
    const int numBytes = config.ByteSize();
    vector<uint8_t> buffer(numBytes);
    config.SerializeToArray(&buffer[0], numBytes);
    StorageManager::writeFile(file_name.c_str(), &buffer[0], numBytes);
}

+4 −2
Original line number Diff line number Diff line
@@ -115,7 +115,9 @@ private:
    /**
     * Save the configs to disk.
     */
    void update_saved_configs_locked(const ConfigKey& key, const StatsdConfig& config);
    void update_saved_configs_locked(const ConfigKey& key,
                                     const std::vector<uint8_t>& buffer,
                                     const int numBytes);

    /**
     * Remove saved configs from disk.
@@ -123,7 +125,7 @@ private:
    void remove_saved_configs(const ConfigKey& key);

    /**
     * The Configs that have been set. Each config should
     * Config keys that have been set.
     */
    std::set<ConfigKey> mConfigs;

+39 −0
Original line number Diff line number Diff line
@@ -245,6 +245,45 @@ void StorageManager::readConfigFromDisk(map<ConfigKey, StatsdConfig>& configsMap
    }
}

bool StorageManager::hasIdenticalConfig(const ConfigKey& key,
                                        const vector<uint8_t>& config) {
    unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_SERVICE_DIR),
                                             closedir);
    if (dir == NULL) {
        VLOG("Directory does not exist: %s", STATS_SERVICE_DIR);
        return false;
    }

    const char* suffix =
            StringPrintf("%d_%lld", key.GetUid(), (long long)key.GetId()).c_str();

    dirent* de;
    while ((de = readdir(dir.get()))) {
        char* name = de->d_name;
        if (name[0] == '.') {
            continue;
        }
        size_t nameLen = strlen(name);
        size_t suffixLen = strlen(suffix);
        // There can be at most one file that matches this suffix (config key).
        if (suffixLen <= nameLen &&
                strncmp(name + nameLen - suffixLen, suffix, suffixLen) == 0) {
            int fd = open(StringPrintf("%s/%s", STATS_SERVICE_DIR, name).c_str(),
                                  O_RDONLY | O_CLOEXEC);
            if (fd != -1) {
                string content;
                if (android::base::ReadFdToString(fd, &content)) {
                    vector<uint8_t> vec(content.begin(), content.end());
                    if (vec == config) {
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

void StorageManager::trimToFit(const char* path) {
    unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
    if (dir == NULL) {
+6 −0
Original line number Diff line number Diff line
@@ -78,6 +78,12 @@ public:
     * files, accumulation of outdated files.
     */
    static void trimToFit(const char* dir);

    /**
     * Returns true if there already exists identical configuration on device.
     */
    static bool hasIdenticalConfig(const ConfigKey& key,
                                   const vector<uint8_t>& config);
};

}  // namespace statsd