| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| #include "util/os-info.h" |
| |
| #include <stdlib.h> |
| #include <string.h> |
| #include <fstream> |
| #include <iostream> |
| #include <sstream> |
| |
| #include <unistd.h> |
| #include <boost/algorithm/string.hpp> |
| #include <sys/stat.h> |
| |
| #include "common/names.h" |
| |
| using boost::algorithm::is_any_of; |
| using boost::algorithm::split; |
| using boost::algorithm::token_compress_on; |
| |
| namespace impala { |
| |
| bool OsInfo::initialized_ = false; |
| string OsInfo::os_distribution_ = "Unknown"; |
| string OsInfo::os_version_ = "Unknown"; |
| clockid_t OsInfo::fast_clock_ = CLOCK_MONOTONIC; |
| std::string OsInfo::clock_name_ = |
| "Unknown clocksource, clockid_t defaulting to CLOCK_MONOTONIC"; |
| |
| // CLOCK_MONOTONIC_COARSE was added in Linux 2.6.32. For now we still want to support |
| // older kernels by falling back to CLOCK_MONOTONIC. |
| #ifdef CLOCK_MONOTONIC_COARSE |
| #define HAVE_CLOCK_MONOTONIC_COARSE true |
| #else |
| #define HAVE_CLOCK_MONOTONIC_COARSE false |
| #define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC |
| #endif |
| |
| void OsInfo::Init() { |
| DCHECK(!initialized_); |
| struct stat info; |
| // Read from /etc/os-release |
| if (stat("/etc/os-release", &info) == 0) { |
| ifstream os_distribution("/etc/os-release", ios::in); |
| string line; |
| while (os_distribution.good() && !os_distribution.eof()) { |
| getline(os_distribution, line); |
| vector<string> fields; |
| split(fields, line, is_any_of("="), token_compress_on); |
| if (fields[0].compare("PRETTY_NAME") == 0) { |
| os_distribution_ = fields[1].data(); |
| // remove quotes around os distribution |
| os_distribution_.erase( |
| remove(os_distribution_.begin(), os_distribution_.end(), '\"'), |
| os_distribution_.end()); |
| break; |
| } |
| } |
| if (os_distribution.is_open()) os_distribution.close(); |
| } else if (stat("/etc/redhat-release", &info) == 0) { |
| // Only old distributions like centos 6, redhat 6 |
| ifstream os_distribution("/etc/redhat-release", ios::in); |
| if (os_distribution.good()) getline(os_distribution, os_distribution_); |
| if (os_distribution.is_open()) os_distribution.close(); |
| } |
| |
| // Read from /proc/version |
| ifstream os_version("/proc/version", ios::in); |
| if (os_version.good()) getline(os_version, os_version_); |
| if (os_version.is_open()) os_version.close(); |
| |
| // Read the current clocksource to see if CLOCK_MONOTONIC is known to be fast. "tsc" is |
| // fast, while "xen" is slow (40 times slower than "tsc" on EC2). If CLOCK_MONOTONIC is |
| // known to be slow, we use CLOCK_MONOTONIC_COARSE, which uses jiffies, with a |
| // resolution measured in milliseconds, rather than nanoseconds. |
| std::ifstream clocksource_file( |
| "/sys/devices/system/clocksource/clocksource0/current_clocksource"); |
| if (clocksource_file.good()) { |
| std::string clocksource; |
| clocksource_file >> clocksource; |
| clock_name_ = "clocksource: '" + clocksource + "', clockid_t: "; |
| if (HAVE_CLOCK_MONOTONIC_COARSE && clocksource != "tsc") { |
| clock_name_ += "CLOCK_MONOTONIC_COARSE"; |
| fast_clock_ = CLOCK_MONOTONIC_COARSE; |
| } else { |
| clock_name_ += "CLOCK_MONOTONIC"; |
| fast_clock_ = CLOCK_MONOTONIC; |
| } |
| } |
| |
| initialized_ = true; |
| } |
| |
| string OsInfo::DebugString() { |
| DCHECK(initialized_); |
| stringstream stream; |
| stream << "OS distribution: " << os_distribution_ << endl |
| << "OS version: " << os_version_ << endl |
| << "Clock: " << clock_name_ << endl; |
| return stream.str(); |
| } |
| |
| } // namespace impala |