From ecddb1dd24756b0049cf9d32fe49ae5d13f96b44 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Tue, 14 Jan 2020 16:47:41 +0800 Subject: [PATCH] common/util: use ifstream to read from /proc files refactor `collect_sys_info()` to use ifstream, getline and boost string helpers to read and parse the /proc/meminfo and /proc/cpuinfo. for better readability, and it's less error-prone. Related-To: https://tracker.ceph.com/issues/43306 Signed-off-by: Kefu Chai --- src/common/util.cc | 61 +++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/src/common/util.cc b/src/common/util.cc index 9678f607641..f816ff41db0 100644 --- a/src/common/util.cc +++ b/src/common/util.cc @@ -13,7 +13,8 @@ */ #include -#include +#include +#include #include "include/compat.h" #include "include/util.h" @@ -240,53 +241,41 @@ void collect_sys_info(map *m, CephContext *cct) } #else // memory - FILE *f = fopen(PROCPREFIX "/proc/meminfo", "r"); - if (f) { - char buf[100]; - while (!feof(f)) { - char *line = fgets(buf, sizeof(buf), f); - if (!line) - break; - char key[40]; - long long value; - int r = sscanf(line, "%39s %lld", key, &value); - if (r == 2) { - if (strcmp(key, "MemTotal:") == 0) - (*m)["mem_total_kb"] = boost::lexical_cast(value); - else if (strcmp(key, "SwapTotal:") == 0) - (*m)["mem_swap_kb"] = boost::lexical_cast(value); + if (std::ifstream f{PROCPREFIX "/proc/meminfo"}; !f.fail()) { + for (std::string line; std::getline(f, line); ) { + std::vector parts; + boost::split(parts, line, boost::is_any_of(":\t "), boost::token_compress_on); + if (parts.size() != 3) { + continue; + } + if (parts[0] == "MemTotal") { + (*m)["mem_total_kb"] = parts[1]; + } else if (parts[0] == "SwapTotal") { + (*m)["mem_swap_kb"] = parts[1]; } } - fclose(f); } uint64_t cgroup_limit; if (get_cgroup_memory_limit(&cgroup_limit) == 0 && cgroup_limit > 0) { - (*m)["mem_cgroup_limit"] = boost::lexical_cast(cgroup_limit); + (*m)["mem_cgroup_limit"] = std::to_string(cgroup_limit); } // processor - f = fopen(PROCPREFIX "/proc/cpuinfo", "r"); - if (f) { - char buf[1024]; - while (!feof(f)) { - char *line = fgets(buf, sizeof(buf), f); - if (!line) - break; - if (strncmp(line, "model name", 10) == 0) { - char *c = strchr(buf, ':'); - c++; - while (*c == ' ') - ++c; - char *nl = c; - while (*nl != '\n') - ++nl; - *nl = '\0'; - (*m)["cpu"] = c; + if (std::ifstream f{PROCPREFIX "/proc/cpuinfo"}; !f.fail()) { + for (std::string line; std::getline(f, line); ) { + std::vector parts; + boost::split(parts, line, boost::is_any_of(":")); + if (parts.size() != 2) { + continue; + } + boost::trim(parts[0]); + boost::trim(parts[1]); + if (parts[0] == "model name") { + (*m)["cpu"] = parts[1]; break; } } - fclose(f); } #endif // distro info