IMPALA-8065: Add OS distribution name in OSInfo
Before this change OsInfo::DebugString() would print two lines:
- OS version: the long name of the Linux kernel from /proc/version
- Clock: the type of clock used
After this change OsInfo::DebugString() will print three lines:
- OS distribution: the short name of the OS release.
If Docker is being used this is the name of the Container OS.
- OS version: the long name of the Linux kernel from /proc/version.
If Docker is being used this is the description of the Host Kernel.
- Clock: the type of clock used.
Tested locally, the displayed OS Info in Ubuntu16 dev box is:
OS distribution: Ubuntu 16.04.6 LTS
OS version: Linux version 4.15.0-65-generic (buildd@lcy01-amd64-017)
(gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10))
Clock: clocksource: 'tsc', clockid_t: CLOCK_MONOTONIC
Also checked with diff OS in docker: centos, redhat, ubuntu, oracle,
debian to make sure /etc/os-release exists and PRETTY_NAME in that file.
Each OS picked one version to test.
Specially for centos6 and redhat6, which have redhat-release instead of
os-release, copied redhat-release into Ubuntu16 dev box and verified os
version in mini-cluster.
Added new backend test os-info-test.cc.
Change-Id: I848c9e53ee4e0bf8ae0874bb6da28e8efa7f7c8a
Reviewed-on: http://gerrit.cloudera.org:8080/14531
Reviewed-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
Tested-by: Impala Public Jenkins <impala-public-jenkins@cloudera.com>
diff --git a/be/src/util/CMakeLists.txt b/be/src/util/CMakeLists.txt
index e0bbda0..ef3fbb2 100644
--- a/be/src/util/CMakeLists.txt
+++ b/be/src/util/CMakeLists.txt
@@ -120,6 +120,7 @@
metrics-test.cc
min-max-filter-test.cc
openssl-util-test.cc
+ os-info-test.cc
os-util-test.cc
parse-util-test.cc
pretty-printer-test.cc
@@ -182,6 +183,7 @@
ADD_UNIFIED_BE_LSAN_TEST(metrics-test "MetricsTest.*")
ADD_UNIFIED_BE_LSAN_TEST(min-max-filter-test "MinMaxFilterTest.*")
ADD_UNIFIED_BE_LSAN_TEST(openssl-util-test "OpenSSLUtilTest.*")
+ADD_UNIFIED_BE_LSAN_TEST(os-info-test "OsInfo.*")
ADD_UNIFIED_BE_LSAN_TEST(os-util-test "OsUtil.*")
ADD_UNIFIED_BE_LSAN_TEST(parse-util-test "ParseMemSpecs.*")
ADD_UNIFIED_BE_LSAN_TEST(pretty-printer-test "PrettyPrinterTest.*")
diff --git a/be/src/util/os-info-test.cc b/be/src/util/os-info-test.cc
new file mode 100644
index 0000000..ebc5225
--- /dev/null
+++ b/be/src/util/os-info-test.cc
@@ -0,0 +1,28 @@
+// 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 "os-info.h"
+#include "testutil/gtest-util.h"
+
+using namespace impala;
+
+// Test OsInfo can extract os_distribution and os_version correctly from local machine.
+TEST(OsInfo, GetOsVersion) {
+ OsInfo osinfo;
+ ASSERT_NE(osinfo.os_distribution(), "Unknown");
+ ASSERT_NE(osinfo.os_version(), "Unknown");
+}
diff --git a/be/src/util/os-info.cc b/be/src/util/os-info.cc
index cf76b72..0103e76 100644
--- a/be/src/util/os-info.cc
+++ b/be/src/util/os-info.cc
@@ -17,19 +17,26 @@
#include "util/os-info.h"
-#include <iostream>
-#include <fstream>
-#include <sstream>
#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_ =
@@ -46,10 +53,36 @@
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 version("/proc/version", ios::in);
- if (version.good()) getline(version, os_version_);
- if (version.is_open()) version.close();
+ 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
@@ -76,9 +109,10 @@
string OsInfo::DebugString() {
DCHECK(initialized_);
stringstream stream;
- stream << "OS version: " << os_version_ << endl
+ stream << "OS distribution: " << os_distribution_ << endl
+ << "OS version: " << os_version_ << endl
<< "Clock: " << clock_name_ << endl;
return stream.str();
}
-}
+} // namespace impala
diff --git a/be/src/util/os-info.h b/be/src/util/os-info.h
index 295d0b2..6c9f404 100644
--- a/be/src/util/os-info.h
+++ b/be/src/util/os-info.h
@@ -32,6 +32,15 @@
/// Initialize OsInfo.
static void Init();
+ /// Simple name of the OS.
+ /// If Docker is used this is the name of Container OS.
+ static const std::string os_distribution() {
+ DCHECK(initialized_);
+ return os_distribution_;
+ }
+
+ /// The version of Linux kernel and the version of the compiler used to build it.
+ /// If Docker is used this is the host kernel.
static const std::string os_version() {
DCHECK(initialized_);
return os_version_;
@@ -48,6 +57,7 @@
private:
static bool initialized_;
+ static std::string os_distribution_;
static std::string os_version_;
static clockid_t fast_clock_;
static std::string clock_name_;