diff options
Diffstat (limited to 'src/mongo/util/processinfo_linux.cpp')
-rw-r--r-- | src/mongo/util/processinfo_linux.cpp | 799 |
1 files changed, 405 insertions, 394 deletions
diff --git a/src/mongo/util/processinfo_linux.cpp b/src/mongo/util/processinfo_linux.cpp index d02d9cc764d..9709d22bbbb 100644 --- a/src/mongo/util/processinfo_linux.cpp +++ b/src/mongo/util/processinfo_linux.cpp @@ -53,472 +53,483 @@ using namespace std; namespace mongo { - class LinuxProc { - public: - LinuxProc( ProcessId pid ) { - char name[128]; - sprintf( name , "/proc/%d/stat" , pid.asUInt32() ); - - FILE * f = fopen( name , "r"); - if ( ! f ) { - stringstream ss; - ss << "couldn't open [" << name << "] " << errnoWithDescription(); - string s = ss.str(); - msgassertedNoTrace( 13538 , s.c_str() ); - } - int found = fscanf(f, - "%d %127s %c " - "%d %d %d %d %d " - "%lu %lu %lu %lu %lu " - "%lu %lu %ld %ld " /* utime stime cutime cstime */ - "%ld %ld " - "%ld " - "%ld " - "%lu " /* start_time */ - "%lu " - "%ld " // rss - "%lu %" KLF "u %" KLF "u %" KLF "u %" KLF "u %" KLF "u " - /* - "%*s %*s %*s %*s " - "%"KLF"u %*lu %*lu " - "%d %d " - "%lu %lu" - */ - - , - - &_pid, - _comm, - &_state, - &_ppid, &_pgrp, &_session, &_tty, &_tpgid, - &_flags, &_min_flt, &_cmin_flt, &_maj_flt, &_cmaj_flt, - &_utime, &_stime, &_cutime, &_cstime, - &_priority, &_nice, - &_nlwp, - &_alarm, - &_start_time, - &_vsize, - &_rss, - &_rss_rlim, &_start_code, &_end_code, &_start_stack, &_kstk_esp, &_kstk_eip - - /* - &_wchan, - &_exit_signal, &_processor, - &_rtprio, &_sched - */ - ); - if ( found == 0 ) { - cout << "system error: reading proc info" << endl; - } - fclose( f ); +class LinuxProc { +public: + LinuxProc(ProcessId pid) { + char name[128]; + sprintf(name, "/proc/%d/stat", pid.asUInt32()); + + FILE* f = fopen(name, "r"); + if (!f) { + stringstream ss; + ss << "couldn't open [" << name << "] " << errnoWithDescription(); + string s = ss.str(); + msgassertedNoTrace(13538, s.c_str()); } - - unsigned long getVirtualMemorySize() { - return _vsize; - } - - unsigned long getResidentSize() { - return (unsigned long)_rss * 4 * 1024; + int found = fscanf(f, + "%d %127s %c " + "%d %d %d %d %d " + "%lu %lu %lu %lu %lu " + "%lu %lu %ld %ld " /* utime stime cutime cstime */ + "%ld %ld " + "%ld " + "%ld " + "%lu " /* start_time */ + "%lu " + "%ld " // rss + "%lu %" KLF "u %" KLF "u %" KLF "u %" KLF "u %" KLF "u " + /* + "%*s %*s %*s %*s " + "%"KLF"u %*lu %*lu " + "%d %d " + "%lu %lu" + */ + + , + + &_pid, + _comm, + &_state, + &_ppid, + &_pgrp, + &_session, + &_tty, + &_tpgid, + &_flags, + &_min_flt, + &_cmin_flt, + &_maj_flt, + &_cmaj_flt, + &_utime, + &_stime, + &_cutime, + &_cstime, + &_priority, + &_nice, + &_nlwp, + &_alarm, + &_start_time, + &_vsize, + &_rss, + &_rss_rlim, + &_start_code, + &_end_code, + &_start_stack, + &_kstk_esp, + &_kstk_eip + + /* + &_wchan, + &_exit_signal, &_processor, + &_rtprio, &_sched + */ + ); + if (found == 0) { + cout << "system error: reading proc info" << endl; } + fclose(f); + } - int _pid; - // The process ID. - - char _comm[128]; - // The filename of the executable, in parentheses. This is visible whether or not the executable is swapped out. - - char _state; - //One character from the string "RSDZTW" where R is running, S is sleeping in an interruptible wait, D is waiting in uninterruptible - // disk sleep, Z is zombie, T is traced or stopped (on a signal), and W is paging. + unsigned long getVirtualMemorySize() { + return _vsize; + } - int _ppid; - // The PID of the parent. + unsigned long getResidentSize() { + return (unsigned long)_rss * 4 * 1024; + } - int _pgrp; - // The process group ID of the process. + int _pid; + // The process ID. - int _session; - // The session ID of the process. + char _comm[128]; + // The filename of the executable, in parentheses. This is visible whether or not the executable is swapped out. - int _tty; - // The tty the process uses. + char _state; + // One character from the string "RSDZTW" where R is running, S is sleeping in an interruptible wait, D is waiting in uninterruptible + // disk sleep, Z is zombie, T is traced or stopped (on a signal), and W is paging. - int _tpgid; - // The process group ID of the process which currently owns the tty that the process is connected to. + int _ppid; + // The PID of the parent. - unsigned long _flags; // %lu - // The kernel flags word of the process. For bit meanings, see the PF_* defines in <linux/sched.h>. Details depend on the kernel version. + int _pgrp; + // The process group ID of the process. - unsigned long _min_flt; // %lu - // The number of minor faults the process has made which have not required loading a memory page from disk. + int _session; + // The session ID of the process. - unsigned long _cmin_flt; // %lu - // The number of minor faults that the process + int _tty; + // The tty the process uses. - unsigned long _maj_flt; // %lu - // The number of major faults the process has made which have required loading a memory page from disk. + int _tpgid; + // The process group ID of the process which currently owns the tty that the process is connected to. - unsigned long _cmaj_flt; // %lu - // The number of major faults that the process + unsigned long _flags; // %lu + // The kernel flags word of the process. For bit meanings, see the PF_* defines in <linux/sched.h>. Details depend on the kernel version. - unsigned long _utime; // %lu - // The number of jiffies that this process has been scheduled in user mode. + unsigned long _min_flt; // %lu + // The number of minor faults the process has made which have not required loading a memory page from disk. - unsigned long _stime; // %lu - // The number of jiffies that this process has been scheduled in kernel mode. + unsigned long _cmin_flt; // %lu + // The number of minor faults that the process - long _cutime; // %ld - // The number of jiffies that this removed field. + unsigned long _maj_flt; // %lu + // The number of major faults the process has made which have required loading a memory page from disk. - long _cstime; // %ld + unsigned long _cmaj_flt; // %lu + // The number of major faults that the process - long _priority; - long _nice; + unsigned long _utime; // %lu + // The number of jiffies that this process has been scheduled in user mode. - long _nlwp; // %ld - // number of threads + unsigned long _stime; // %lu + // The number of jiffies that this process has been scheduled in kernel mode. - unsigned long _alarm; - // The time in jiffies before the next SIGALRM is sent to the process due to an interval timer. (unused since 2.6.17) + long _cutime; // %ld + // The number of jiffies that this removed field. - unsigned long _start_time; // %lu - // The time in jiffies the process started after system boot. + long _cstime; // %ld - unsigned long _vsize; // %lu - // Virtual memory size in bytes. + long _priority; + long _nice; - long _rss; // %ld - // Resident Set Size: number of pages the process has in real memory, minus 3 for administrative purposes. This is just the pages which - // count towards text, data, or stack space. This does not include pages which have not been demand-loaded in, or which are swapped out + long _nlwp; // %ld + // number of threads - unsigned long _rss_rlim; // %lu - // Current limit in bytes on the rss of the process (usually 4294967295 on i386). + unsigned long _alarm; + // The time in jiffies before the next SIGALRM is sent to the process due to an interval timer. (unused since 2.6.17) - unsigned long _start_code; // %lu - // The address above which program text can run. + unsigned long _start_time; // %lu + // The time in jiffies the process started after system boot. - unsigned long _end_code; // %lu - // The address below which program text can run. + unsigned long _vsize; // %lu + // Virtual memory size in bytes. - unsigned long _start_stack; // %lu - // The address of the start of the stack. + long _rss; // %ld + // Resident Set Size: number of pages the process has in real memory, minus 3 for administrative purposes. This is just the pages which + // count towards text, data, or stack space. This does not include pages which have not been demand-loaded in, or which are swapped out - unsigned long _kstk_esp; // %lu - // The current value of esp (stack pointer), as found in the kernel stack page for the process. + unsigned long _rss_rlim; // %lu + // Current limit in bytes on the rss of the process (usually 4294967295 on i386). - unsigned long _kstk_eip; // %lu - // The current EIP (instruction pointer). + unsigned long _start_code; // %lu + // The address above which program text can run. + unsigned long _end_code; // %lu + // The address below which program text can run. + unsigned long _start_stack; // %lu + // The address of the start of the stack. - }; + unsigned long _kstk_esp; // %lu + // The current value of esp (stack pointer), as found in the kernel stack page for the process. + unsigned long _kstk_eip; // %lu + // The current EIP (instruction pointer). +}; - class LinuxSysHelper { - public: - /** - * Read the first 1023 bytes from a file - */ - static string readLineFromFile( const char* fname ) { - FILE* f; - char fstr[1024] = { 0 }; +class LinuxSysHelper { +public: + /** + * Read the first 1023 bytes from a file + */ + static string readLineFromFile(const char* fname) { + FILE* f; + char fstr[1024] = {0}; + + f = fopen(fname, "r"); + if (f != NULL) { + if (fgets(fstr, 1023, f) != NULL) + fstr[strlen(fstr) < 1 ? 0 : strlen(fstr) - 1] = '\0'; + fclose(f); + } + return fstr; + } - f = fopen( fname, "r" ); - if ( f != NULL ) { - if ( fgets( fstr, 1023, f ) != NULL ) - fstr[strlen( fstr ) < 1 ? 0 : strlen( fstr ) - 1] = '\0'; - fclose( f ); - } - return fstr; + /** + * Get some details about the CPU + */ + static void getCpuInfo(int& procCount, string& freq, string& features) { + FILE* f; + char fstr[1024] = {0}; + procCount = 0; + + f = fopen("/proc/cpuinfo", "r"); + if (f == NULL) + return; + + while (fgets(fstr, 1023, f) != NULL && !feof(f)) { + // until the end of the file + fstr[strlen(fstr) < 1 ? 0 : strlen(fstr) - 1] = '\0'; + if (strncmp(fstr, "processor\t:", 11) == 0) + ++procCount; + if (strncmp(fstr, "cpu MHz\t\t:", 10) == 0) + freq = fstr + 11; + if (strncmp(fstr, "flags\t\t:", 8) == 0) + features = fstr + 9; } - /** - * Get some details about the CPU - */ - static void getCpuInfo(int& procCount, string& freq, string& features) { - FILE* f; - char fstr[1024] = { 0 }; - procCount = 0; + fclose(f); + } - f = fopen( "/proc/cpuinfo", "r" ); - if ( f == NULL ) + /** + * Determine linux distro and version + */ + static void getLinuxDistro(string& name, string& version) { + char buf[4096] = {0}; + + // try lsb file first + if (boost::filesystem::exists("/etc/lsb-release")) { + File f; + f.open("/etc/lsb-release", true); + if (!f.is_open() || f.bad()) + return; + f.read(0, buf, f.len() > 4095 ? 4095 : f.len()); + + // find the distribution name and version in the contents. + // format: KEY=VAL\n + string contents = buf; + unsigned lineCnt = 0; + try { + while (lineCnt < contents.length() - 1 && + contents.substr(lineCnt).find('\n') != string::npos) { + // until we hit the last newline or eof + string line = contents.substr(lineCnt, contents.substr(lineCnt).find('\n')); + lineCnt += contents.substr(lineCnt).find('\n') + 1; + size_t delim = line.find('='); + string key = line.substr(0, delim); + string val = line.substr(delim + 1); // 0-based offset of delim + if (key.compare("DISTRIB_ID") == 0) + name = val; + if (string(key).compare("DISTRIB_RELEASE") == 0) + version = val; + } + } catch (const std::out_of_range& e) { + // attempted to get invalid substr + } + // return with lsb-release data if we found both the name and version + if (!name.empty() && !version.empty()) { return; - - while ( fgets( fstr, 1023, f ) != NULL && !feof(f) ) { - // until the end of the file - fstr[strlen( fstr ) < 1 ? 0 : strlen( fstr ) - 1] = '\0'; - if (strncmp(fstr, "processor\t:", 11) == 0) - ++procCount; - if (strncmp(fstr, "cpu MHz\t\t:", 10) == 0) - freq = fstr + 11; - if (strncmp(fstr, "flags\t\t:", 8) == 0) - features = fstr + 9; } - - fclose( f ); } - /** - * Determine linux distro and version - */ - static void getLinuxDistro( string& name, string& version ) { - char buf[4096] = { 0 }; - - // try lsb file first - if ( boost::filesystem::exists( "/etc/lsb-release" ) ) { - File f; - f.open( "/etc/lsb-release", true ); - if ( ! f.is_open() || f.bad() ) - return; - f.read( 0, buf, f.len() > 4095 ? 4095 : f.len() ); - - // find the distribution name and version in the contents. - // format: KEY=VAL\n - string contents = buf; - unsigned lineCnt = 0; - try { - while ( lineCnt < contents.length() - 1 && contents.substr( lineCnt ).find( '\n' ) != string::npos ) { - // until we hit the last newline or eof - string line = contents.substr( lineCnt, contents.substr( lineCnt ).find( '\n' ) ); - lineCnt += contents.substr( lineCnt ).find( '\n' ) + 1; - size_t delim = line.find( '=' ); - string key = line.substr( 0, delim ); - string val = line.substr( delim + 1 ); // 0-based offset of delim - if ( key.compare( "DISTRIB_ID" ) == 0 ) - name = val; - if ( string(key).compare( "DISTRIB_RELEASE" ) == 0 ) - version = val; - } - } - catch (const std::out_of_range &e) { - // attempted to get invalid substr - } - // return with lsb-release data if we found both the name and version - if ( !name.empty() && !version.empty() ) { - return; - } + // try known flat-text file locations + // format: Slackware-x86_64 13.0, Red Hat Enterprise Linux Server release 5.6 (Tikanga), etc. + typedef vector<string> pathvec; + pathvec paths; + pathvec::const_iterator i; + bool found = false; + paths.push_back("/etc/system-release"); + paths.push_back("/etc/redhat-release"); + paths.push_back("/etc/gentoo-release"); + paths.push_back("/etc/novell-release"); + paths.push_back("/etc/gentoo-release"); + paths.push_back("/etc/SuSE-release"); + paths.push_back("/etc/SUSE-release"); + paths.push_back("/etc/sles-release"); + paths.push_back("/etc/debian_release"); + paths.push_back("/etc/slackware-version"); + paths.push_back("/etc/centos-release"); + paths.push_back("/etc/os-release"); + + for (i = paths.begin(); i != paths.end(); ++i) { + // for each path + if (boost::filesystem::exists(*i)) { + // if the file exists, break + found = true; + break; } + } - // try known flat-text file locations - // format: Slackware-x86_64 13.0, Red Hat Enterprise Linux Server release 5.6 (Tikanga), etc. - typedef vector <string> pathvec; - pathvec paths; - pathvec::const_iterator i; - bool found = false; - paths.push_back( "/etc/system-release" ); - paths.push_back( "/etc/redhat-release" ); - paths.push_back( "/etc/gentoo-release" ); - paths.push_back( "/etc/novell-release" ); - paths.push_back( "/etc/gentoo-release" ); - paths.push_back( "/etc/SuSE-release" ); - paths.push_back( "/etc/SUSE-release" ); - paths.push_back( "/etc/sles-release" ); - paths.push_back( "/etc/debian_release" ); - paths.push_back( "/etc/slackware-version" ); - paths.push_back( "/etc/centos-release" ); - paths.push_back( "/etc/os-release" ); - - for ( i = paths.begin(); i != paths.end(); ++i ) { - // for each path - if ( boost::filesystem::exists( *i ) ) { - // if the file exists, break - found = true; - break; - } - } + if (found) { + // found a file + File f; + f.open(i->c_str(), true); + if (!f.is_open() || f.bad()) + // file exists but can't be opened + return; - if ( found ) { - // found a file - File f; - f.open( i->c_str(), true ); - if ( ! f.is_open() || f.bad() ) - // file exists but can't be opened - return; - - // read up to 512 bytes - int len = f.len() > 512 ? 512 : f.len(); - f.read( 0, buf, len ); - buf[ len ] = '\0'; - name = buf; - size_t nl = 0; - if ( ( nl = name.find( '\n', nl ) ) != string::npos ) - // stop at first newline - name.erase( nl ); - // no standard format for name and version. use kernel version - version = "Kernel "; - version += LinuxSysHelper::readLineFromFile("/proc/sys/kernel/osrelease"); - } + // read up to 512 bytes + int len = f.len() > 512 ? 512 : f.len(); + f.read(0, buf, len); + buf[len] = '\0'; + name = buf; + size_t nl = 0; + if ((nl = name.find('\n', nl)) != string::npos) + // stop at first newline + name.erase(nl); + // no standard format for name and version. use kernel version + version = "Kernel "; + version += LinuxSysHelper::readLineFromFile("/proc/sys/kernel/osrelease"); } + } - /** - * Get system memory total - */ - static unsigned long long getSystemMemorySize() { - string meminfo = readLineFromFile( "/proc/meminfo" ); - size_t lineOff= 0; - if ( !meminfo.empty() && ( lineOff = meminfo.find( "MemTotal" ) ) != string::npos ) { - // found MemTotal line. capture everything between 'MemTotal:' and ' kB'. - lineOff = meminfo.substr( lineOff ).find( ':' ) + 1; - meminfo = meminfo.substr( lineOff, meminfo.substr( lineOff ).find( "kB" ) - 1); - lineOff = 0; - - // trim whitespace and append 000 to replace kB. - while ( isspace( meminfo.at( lineOff ) ) ) lineOff++; - meminfo = meminfo.substr( lineOff ); - - unsigned long long systemMem = 0; - if ( mongo::parseNumberFromString( meminfo, &systemMem ).isOK() ) { - return systemMem * 1024; // convert from kB to bytes - } - else - log() << "Unable to collect system memory information" << endl; - } - return 0; + /** + * Get system memory total + */ + static unsigned long long getSystemMemorySize() { + string meminfo = readLineFromFile("/proc/meminfo"); + size_t lineOff = 0; + if (!meminfo.empty() && (lineOff = meminfo.find("MemTotal")) != string::npos) { + // found MemTotal line. capture everything between 'MemTotal:' and ' kB'. + lineOff = meminfo.substr(lineOff).find(':') + 1; + meminfo = meminfo.substr(lineOff, meminfo.substr(lineOff).find("kB") - 1); + lineOff = 0; + + // trim whitespace and append 000 to replace kB. + while (isspace(meminfo.at(lineOff))) + lineOff++; + meminfo = meminfo.substr(lineOff); + + unsigned long long systemMem = 0; + if (mongo::parseNumberFromString(meminfo, &systemMem).isOK()) { + return systemMem * 1024; // convert from kB to bytes + } else + log() << "Unable to collect system memory information" << endl; } + return 0; + } +}; - }; +ProcessInfo::ProcessInfo(ProcessId pid) : _pid(pid) {} - ProcessInfo::ProcessInfo( ProcessId pid ) : _pid( pid ) { - } +ProcessInfo::~ProcessInfo() {} - ProcessInfo::~ProcessInfo() { - } +bool ProcessInfo::supported() { + return true; +} - bool ProcessInfo::supported() { - return true; - } +int ProcessInfo::getVirtualMemorySize() { + LinuxProc p(_pid); + return (int)(p.getVirtualMemorySize() / (1024.0 * 1024)); +} - int ProcessInfo::getVirtualMemorySize() { - LinuxProc p(_pid); - return (int)( p.getVirtualMemorySize() / ( 1024.0 * 1024 ) ); - } +int ProcessInfo::getResidentSize() { + LinuxProc p(_pid); + return (int)(p.getResidentSize() / (1024.0 * 1024)); +} - int ProcessInfo::getResidentSize() { - LinuxProc p(_pid); - return (int)( p.getResidentSize() / ( 1024.0 * 1024 ) ); - } +double ProcessInfo::getSystemMemoryPressurePercentage() { + return 0.0; +} - double ProcessInfo::getSystemMemoryPressurePercentage() { - return 0.0; - } +void ProcessInfo::getExtraInfo(BSONObjBuilder& info) { + // [dm] i don't think mallinfo works. (64 bit.) ?? + struct mallinfo malloc_info = + mallinfo(); // structure has same name as function that returns it. (see malloc.h) + info.append("heap_usage_bytes", + malloc_info.uordblks /*main arena*/ + malloc_info.hblkhd /*mmap blocks*/); + // docs claim hblkhd is included in uordblks but it isn't - void ProcessInfo::getExtraInfo( BSONObjBuilder& info ) { - // [dm] i don't think mallinfo works. (64 bit.) ?? - struct mallinfo malloc_info = mallinfo(); // structure has same name as function that returns it. (see malloc.h) - info.append("heap_usage_bytes", malloc_info.uordblks/*main arena*/ + malloc_info.hblkhd/*mmap blocks*/); - //docs claim hblkhd is included in uordblks but it isn't + LinuxProc p(_pid); + info.appendNumber("page_faults", static_cast<long long>(p._maj_flt)); +} - LinuxProc p(_pid); - info.appendNumber("page_faults", static_cast<long long>(p._maj_flt) ); +/** +* Save a BSON obj representing the host system's details +*/ +void ProcessInfo::SystemInfo::collectSystemInfo() { + utsname unameData; + string distroName, distroVersion; + string cpuFreq, cpuFeatures; + int cpuCount; + + string verSig = LinuxSysHelper::readLineFromFile("/proc/version_signature"); + LinuxSysHelper::getCpuInfo(cpuCount, cpuFreq, cpuFeatures); + LinuxSysHelper::getLinuxDistro(distroName, distroVersion); + + if (uname(&unameData) == -1) { + log() << "Unable to collect detailed system information: " << strerror(errno) << endl; } - /** - * Save a BSON obj representing the host system's details - */ - void ProcessInfo::SystemInfo::collectSystemInfo() { - utsname unameData; - string distroName, distroVersion; - string cpuFreq, cpuFeatures; - int cpuCount; - - string verSig = LinuxSysHelper::readLineFromFile( "/proc/version_signature" ); - LinuxSysHelper::getCpuInfo(cpuCount, cpuFreq, cpuFeatures); - LinuxSysHelper::getLinuxDistro( distroName, distroVersion ); - - if ( uname( &unameData ) == -1 ) { - log() << "Unable to collect detailed system information: " << strerror( errno ) << endl; - } - - osType = "Linux"; - osName = distroName; - osVersion = distroVersion; - memSize = LinuxSysHelper::getSystemMemorySize(); - addrSize = (string( unameData.machine ).find( "x86_64" ) != string::npos ? 64 : 32); - numCores = cpuCount; - pageSize = static_cast<unsigned long long>(sysconf( _SC_PAGESIZE )); - cpuArch = unameData.machine; - hasNuma = checkNumaEnabled(); - - BSONObjBuilder bExtra; - bExtra.append( "versionString", LinuxSysHelper::readLineFromFile( "/proc/version" ) ); + osType = "Linux"; + osName = distroName; + osVersion = distroVersion; + memSize = LinuxSysHelper::getSystemMemorySize(); + addrSize = (string(unameData.machine).find("x86_64") != string::npos ? 64 : 32); + numCores = cpuCount; + pageSize = static_cast<unsigned long long>(sysconf(_SC_PAGESIZE)); + cpuArch = unameData.machine; + hasNuma = checkNumaEnabled(); + + BSONObjBuilder bExtra; + bExtra.append("versionString", LinuxSysHelper::readLineFromFile("/proc/version")); #ifdef __UCLIBC__ - stringstream ss; - ss << "uClibc-" << __UCLIBC_MAJOR__ << "." << __UCLIBC_MINOR__ << "." << __UCLIBC_SUBLEVEL__; - bExtra.append( "libcVersion", ss.str() ); + stringstream ss; + ss << "uClibc-" << __UCLIBC_MAJOR__ << "." << __UCLIBC_MINOR__ << "." << __UCLIBC_SUBLEVEL__; + bExtra.append("libcVersion", ss.str()); #else - bExtra.append( "libcVersion", gnu_get_libc_version() ); + bExtra.append("libcVersion", gnu_get_libc_version()); #endif - if (!verSig.empty()) - // optional - bExtra.append( "versionSignature", verSig ); - - bExtra.append( "kernelVersion", unameData.release ); - bExtra.append( "cpuFrequencyMHz", cpuFreq); - bExtra.append( "cpuFeatures", cpuFeatures); - bExtra.append( "pageSize", static_cast<long long>(pageSize) ); - bExtra.append( "numPages", static_cast< int >(sysconf( _SC_PHYS_PAGES ) ) ); - bExtra.append( "maxOpenFiles", static_cast< int >(sysconf( _SC_OPEN_MAX ) ) ); - - _extraStats = bExtra.obj(); + if (!verSig.empty()) + // optional + bExtra.append("versionSignature", verSig); + + bExtra.append("kernelVersion", unameData.release); + bExtra.append("cpuFrequencyMHz", cpuFreq); + bExtra.append("cpuFeatures", cpuFeatures); + bExtra.append("pageSize", static_cast<long long>(pageSize)); + bExtra.append("numPages", static_cast<int>(sysconf(_SC_PHYS_PAGES))); + bExtra.append("maxOpenFiles", static_cast<int>(sysconf(_SC_OPEN_MAX))); + + _extraStats = bExtra.obj(); +} +/** +* Determine if the process is running with (cc)NUMA +*/ +bool ProcessInfo::checkNumaEnabled() { + bool hasMultipleNodes = false; + bool hasNumaMaps = false; + + try { + hasMultipleNodes = boost::filesystem::exists("/sys/devices/system/node/node1"); + hasNumaMaps = boost::filesystem::exists("/proc/self/numa_maps"); + } catch (boost::filesystem::filesystem_error& e) { + log() << "WARNING: Cannot detect if NUMA interleaving is enabled. " + << "Failed to probe \"" << e.path1().string() << "\": " << e.code().message(); + return false; } - /** - * Determine if the process is running with (cc)NUMA - */ - bool ProcessInfo::checkNumaEnabled() { - bool hasMultipleNodes = false; - bool hasNumaMaps = false; - - try { - hasMultipleNodes = boost::filesystem::exists("/sys/devices/system/node/node1"); - hasNumaMaps = boost::filesystem::exists("/proc/self/numa_maps"); - } catch(boost::filesystem::filesystem_error& e) { - log() << "WARNING: Cannot detect if NUMA interleaving is enabled. " << - "Failed to probe \"" << e.path1().string() << "\": " << e.code().message(); - return false; - } - - if ( hasMultipleNodes && hasNumaMaps ) { - // proc is populated with numa entries + if (hasMultipleNodes && hasNumaMaps) { + // proc is populated with numa entries - // read the second column of first line to determine numa state - // ('default' = enabled, 'interleave' = disabled). Logic from version.cpp's warnings. - string line = LinuxSysHelper::readLineFromFile( "/proc/self/numa_maps" ).append( " \0" ); - size_t pos = line.find(' '); - if ( pos != string::npos && line.substr( pos+1, 10 ).find( "interleave" ) == string::npos ) - // interleave not found; - return true; - } - return false; + // read the second column of first line to determine numa state + // ('default' = enabled, 'interleave' = disabled). Logic from version.cpp's warnings. + string line = LinuxSysHelper::readLineFromFile("/proc/self/numa_maps").append(" \0"); + size_t pos = line.find(' '); + if (pos != string::npos && line.substr(pos + 1, 10).find("interleave") == string::npos) + // interleave not found; + return true; } + return false; +} - bool ProcessInfo::blockCheckSupported() { - return true; - } +bool ProcessInfo::blockCheckSupported() { + return true; +} - bool ProcessInfo::blockInMemory(const void* start) { - unsigned char x = 0; - if (mincore(const_cast<void*>(alignToStartOfPage(start)), getPageSize(), &x)) { - log() << "mincore failed: " << errnoWithDescription() << endl; - return 1; - } - return x & 0x1; +bool ProcessInfo::blockInMemory(const void* start) { + unsigned char x = 0; + if (mincore(const_cast<void*>(alignToStartOfPage(start)), getPageSize(), &x)) { + log() << "mincore failed: " << errnoWithDescription() << endl; + return 1; } + return x & 0x1; +} - bool ProcessInfo::pagesInMemory(const void* start, size_t numPages, vector<char>* out) { - out->resize(numPages); - if (mincore(const_cast<void*>(alignToStartOfPage(start)), numPages * getPageSize(), - reinterpret_cast<unsigned char*>(&out->front()))) { - log() << "mincore failed: " << errnoWithDescription() << endl; - return false; - } - for (size_t i = 0; i < numPages; ++i) { - (*out)[i] &= 0x1; - } - return true; +bool ProcessInfo::pagesInMemory(const void* start, size_t numPages, vector<char>* out) { + out->resize(numPages); + if (mincore(const_cast<void*>(alignToStartOfPage(start)), + numPages * getPageSize(), + reinterpret_cast<unsigned char*>(&out->front()))) { + log() << "mincore failed: " << errnoWithDescription() << endl; + return false; } - + for (size_t i = 0; i < numPages; ++i) { + (*out)[i] &= 0x1; + } + return true; +} } |