int ProcFamily::aggregate_usage_cgroup_blockio_io_serviced(ProcFamilyUsage* usage) { if (!m_cm.isMounted(CgroupManager::BLOCK_CONTROLLER) || !m_cgroup.isValid()) return 1; int ret; void *handle; char line_contents[BLOCK_STATS_LINE_MAX], sep[]=" ", *tok_handle, *word, *info[3]; char blkio_stats_name[] = "blkio.io_serviced"; short ctr; int64_t reads=0, writes=0; ret = cgroup_read_value_begin(BLOCK_CONTROLLER_STR, m_cgroup_string.c_str(), blkio_stats_name, &handle, line_contents, BLOCK_STATS_LINE_MAX); while (ret == 0) { ctr = 0; word = strtok_r(line_contents, sep, &tok_handle); while (word && ctr < 3) { info[ctr++] = word; word = strtok_r(NULL, sep, &tok_handle); } if (ctr == 3) { errno = 0; int64_t ctrval = strtoll(info[2], NULL, 10); if (errno) { dprintf(D_FULLDEBUG, "Error parsing kernel value to a long: %s; %s\n", info[2], strerror(errno)); break; } if (strcmp(info[1], "Read") == 0) { reads += ctrval; } else if (strcmp(info[1], "Write") == 0) { writes += ctrval; } } ret = cgroup_read_value_next(&handle, line_contents, BLOCK_STATS_LINE_MAX); } if (handle != NULL) { cgroup_read_value_end(&handle); } if (ret != ECGEOF) { dprintf(D_ALWAYS, "Internal cgroup error when retrieving block statistics: %s\n", cgroup_strerror(ret)); return 1; } usage->block_reads = reads; usage->block_writes = writes; return 0; }
/* * Read the memory statistics information of given group name. * * IN: * @group_name : The given group name. * @stats: The memory statistics information. * * RETURN * 0 Success. * -1 Failed. */ static int read_mem_stats(const char*group_name, struct mem_stats* stats) { void *handle = NULL; char line[FN_LEN] = { 0 }; /** Clear the history information.*/ memset(stats, 0, sizeof(struct mem_stats)); /** Start the reading of the variable value */ if (cgroup_read_value_begin(CG_MEMORY, group_name, MEMORY_STATS, &handle, line, FN_LEN)) { #ifdef DEBUG fprintf(stderr, "rd_stats: read the %s value of %s in '%s failed'\n", CG_MEMORY, MEMORY_STATS, group_name); #endif return -1; } /** Read the device number and the value, then store the value.*/ do { /** Store the value of the parameter.*/ if (!strncmp(line, CACHE, CACHE_LEN)) sscanf(line + CACHE_LEN + 1, "%ll", &(stats->cache)); else if (!strncmp(line, RSS, RSS_LEN)) sscanf(line + RSS_LEN + 1, "%llu", &(stats->rss)); else if (!strncmp(line, MAPPED_FILE, MAPPED_FILE_LEN)) sscanf(line + MAPPED_FILE_LEN + 1, "%llu", &(stats->mapped_file)); else if (!strncmp(line, PGPGIN, PGPGIN_LEN)) sscanf(line + PGPGIN_LEN + 1, "%llu", &(stats->pgpgin)); else if (!strncmp(line, PGPGOUT, PGPGOUT_LEN)) sscanf(line + PGPGOUT_LEN + 1, "%llu", &(stats->pgpgout)); else if (!strncmp(line, SWAP, SWAP_LEN)) sscanf(line + SWAP_LEN + 1, "%llu", &(stats->swap)); else if (!strncmp(line, INACTIVE_ANON, INACTIVE_ANON_LEN)) sscanf(line + INACTIVE_ANON_LEN + 1, "%llu", &(stats->inactive_anon)); else if (!strncmp(line, ACTIVE_ANON, ACTIVE_ANON_LEN)) sscanf(line + ACTIVE_ANON_LEN + 1, "%llu", &(stats->active_anon)); else if (!strncmp(line, INACTIVE_FILE, INACTIVE_FILE_LEN)) sscanf(line + INACTIVE_FILE_LEN + 1, "%llu", &(stats->inactive_file)); else if (!strncmp(line, ACTIVE_FILE, ACTIVE_FILE_LEN)) sscanf(line + ACTIVE_FILE_LEN + 1, "%llu", &(stats->active_file)); else if (!strncmp(line, UNEVICTABLE, UNEVICTABLE_LEN)) sscanf(line + UNEVICTABLE_LEN + 1, "%llu", &(stats->unevictable)); else if (!strncmp(line, HIERARCHICAL_MEMORY_LIMIT, HIERARCHICAL_MEMORY_LIMIT_LEN)) sscanf(line + HIERARCHICAL_MEMORY_LIMIT_LEN + 1, "%llu", &(stats->hierarchical_memory_limit)); else if (!strncmp(line, HIERARCHICAL_MEMSW_LIMIT, HIERARCHICAL_MEMSW_LIMIT_LEN)) sscanf(line + HIERARCHICAL_MEMSW_LIMIT_LEN + 1, "%llu", &(stats->hierarchical_memsw_limit)); else if (!strncmp(line, TOTAL_CACHE, TOTAL_CACHE_LEN)) sscanf(line + TOTAL_CACHE_LEN + 1, "%llu", &(stats->total_cache)); else if (!strncmp(line, TOTAL_RSS, TOTAL_RSS_LEN)) sscanf(line + TOTAL_RSS_LEN + 1, "%llu", &(stats->total_rss)); else if (!strncmp(line, TOTAL_MAPPED_FILE, TOTAL_MAPPED_FILE_LEN)) sscanf(line + TOTAL_MAPPED_FILE_LEN + 1, "%llu", &(stats->total_mapped_file)); else if (!strncmp(line, TOTAL_PGPGIN, TOTAL_PGPGIN_LEN)) sscanf(line + TOTAL_PGPGIN_LEN + 1, "%llu", &(stats->total_pgpgin)); else if (!strncmp(line, TOTAL_PGPGOUT, TOTAL_PGPGOUT_LEN)) sscanf(line + TOTAL_PGPGOUT_LEN + 1, "%llu", &(stats->total_pgpgout)); else if (!strncmp(line, TOTAL_SWAP, TOTAL_SWAP_LEN)) sscanf(line + TOTAL_SWAP_LEN + 1, "%llu", &(stats->total_swap)); else if (!strncmp(line, TOTAL_INACTIVE_ANON, TOTAL_INACTIVE_ANON_LEN)) sscanf(line + TOTAL_INACTIVE_ANON_LEN + 1, "%llu", &(stats->total_inactive_anon)); else if (!strncmp(line, TOTAL_ACTIVE_ANON, TOTAL_ACTIVE_ANON_LEN)) sscanf(line + TOTAL_ACTIVE_ANON_LEN + 1, "%llu", &(stats->total_active_anon)); else if (!strncmp(line, TOTAL_INACTIVE_FILE, TOTAL_INACTIVE_FILE_LEN)) sscanf(line + TOTAL_INACTIVE_FILE_LEN + 1, "%llu", &(stats->total_inactive_file)); else if (!strncmp(line, TOTAL_ACTIVE_FILE, TOTAL_ACTIVE_FILE_LEN)) sscanf(line + TOTAL_ACTIVE_FILE_LEN + 1, "%llu", &(stats->total_active_file)); else if (!strncmp(line, TOTAL_UNEVICTABLE, TOTAL_UNEVICTABLE_LEN)) sscanf(line + TOTAL_UNEVICTABLE_LEN + 1, "%llu", &(stats->total_unevictable)); } while (!cgroup_read_value_next(&handle, line, FN_LEN)); /** Skip the keyword of the parameter.*/ /** End the reading.*/ cgroup_read_value_end(&handle); return 0; }
/* * Read the device values. * * IN: * @device_name: The given device name. * @group_name: The given group name. * @param: The parameter. * @cg_value_lists: The lists of device values. * * RETURN * 0: Success. * -1: Failed. */ static int read_device_value(const char* device_name, const char* group_name, const char* param, cg_device_value_lists* cg_value_lists) { void* handle; char line[FN_LEN]; int dev = 0, idx = 0; long long value = -1; int len = 0; cg_device_value* cg_value = NULL; if (!device_name || !group_name || !param || !cg_value_lists) { fprintf(stderr, "rd_stats: the input parameters is invalid.\n"); return -1; } /** Clear the history information.*/ clear_device_value(cg_value_lists); /** Start the reading of the variable value */ if (cgroup_read_value_begin(device_name, group_name, param, &handle, line, FN_LEN)) { #ifdef DEBUG fprintf(stderr, "rd_stats: read the %s value of %s in '%s failed'\n", device_name, param, group_name); #endif return -1; } /** Read the device number and the value, then store the value.*/ do { sscanf(line, "%d:%d %llu", &dev, &idx, &value); if (value < 0) break; /** If the device number is not exists, initialized the device value and * add the device value into the lists.*/ if (get_device_value(cg_value_lists, &cg_value, dev, idx)) { if (init_device_value(&cg_value, dev, idx)) { #ifdef DEBUG fprintf(stderr, "rd_stats: initialized the device value of %s %s in '%s failed'\n", device_name, param, group_name); #endif goto err; } if (add_device_value(cg_value_lists, cg_value)) { #ifdef DEBUG fprintf(stderr, "rd_stats: add the device value into the lists of %s %s in '%s failed'\n", device_name, param, group_name); #endif goto err; } } cg_value->value = value; } while (!cgroup_read_value_next(&handle, line, FN_LEN)); /** Skip the keyword of the parameter.*/ /** End the reading.*/ cgroup_read_value_end(&handle); return 0; err: if (cg_value_lists && !TAILQ_EMPTY(cg_value_lists)) clear_device_value(cg_value_lists); /** End the reading.*/ cgroup_read_value_end(&handle); return 1; }
/* * Read the device statistics information. * * IN: * @device_name: The given device name. * @group_name: The given group name. * @param: The parameter. * @cg_stats_lists: The lists of device statistics information. * * RETURN * 0: Success. * -1: Failed. */ static int read_device_stats(const char* device_name, const char* group_name, const char* param, cg_device_stats_lists* cg_stats_lists) { void* handle; char line[FN_LEN]; int dev = 0, idx = 0; char key[LINE_LEN] = { 0 }; long long value = -1; int len = 0; cg_device_stats* cg_stats = NULL; if (!device_name || !group_name || !param || !cg_stats_lists) { #ifdef DEBUG fprintf(stderr, "rd_stats: the input parameters is invalid.\n"); #endif return -1; } /** Clear the history information.*/ clear_device_stats(cg_stats_lists); /** Start the reading of the variable value */ if (cgroup_read_value_begin(device_name, group_name, param, &handle, line, FN_LEN)) { #ifdef DEBUG fprintf(stderr, "rd_stats: read the %s value of %s in '%s failed'\n", device_name, param, group_name); #endif return -1; } /** Read the device number, key and the value, and then set the value to the parameter.*/ do { sscanf(line, "%d:%d %s %llu", &dev, &idx, &key, &value); if (value < 0) break; /** If the device number is not exists, initialized the device statistics information * and add the device statistics information into the lists.*/ if (get_device_stats(cg_stats_lists, &cg_stats, dev, idx)) { if (init_device_stats(&cg_stats, dev, idx)) { #ifdef DEBUG fprintf(stderr, "rd_stats: initialized the device stats of %s %s in '%s failed'\n", device_name, param, group_name); #endif goto err; } if (add_device_stats(cg_stats_lists, cg_stats)) { #ifdef DEBUG fprintf(stderr, "rd_stats: add the device stats into the lists of %s %s in '%s failed'\n", device_name, param, group_name); #endif goto err; } } len = strlen(key); /** Set the value to the corresponding parameter.*/ if (!strncmp(key, BLKIO_READ, max(len,BLKIO_READ_LEN))) cg_stats->stats->read = value; else if (!strncmp(key, BLKIO_WRITE, max(len,BLKIO_WRITE_LEN))) cg_stats->stats->write = value; else if (!strncmp(key, BLKIO_SYNC, max(len,BLKIO_SYNC_LEN))) cg_stats->stats->sync = value; else if (!strncmp(key, BLKIO_ASYNC, max(len,BLKIO_ASYNC_LEN))) cg_stats->stats->async = value; else if (!strncmp(key, BLKIO_TOTAL, max(len,BLKIO_TOTAL_LEN))) cg_stats->stats->total = value; } while (!cgroup_read_value_next(&handle, line, FN_LEN)); /** End the reading.*/ cgroup_read_value_end(&handle); return 0; err: if (cg_stats_lists && !TAILQ_EMPTY(cg_stats_lists)) clear_device_stats(cg_stats_lists); /** End the reading.*/ cgroup_read_value_end(&handle); return 1; }