You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2012/05/23 00:06:34 UTC

svn commit: r1341659 - in /incubator/mesos/trunk/src: Makefile.am linux/ linux/proc.cpp linux/proc.hpp tests/proc_tests.cpp

Author: benh
Date: Tue May 22 22:06:33 2012
New Revision: 1341659

URL: http://svn.apache.org/viewvc?rev=1341659&view=rev
Log:
Added an interface for getting information from the /proc filesystem (https://reviews.apache.org/r/5132).

Added:
    incubator/mesos/trunk/src/linux/
    incubator/mesos/trunk/src/linux/proc.cpp
    incubator/mesos/trunk/src/linux/proc.hpp
    incubator/mesos/trunk/src/tests/proc_tests.cpp
Modified:
    incubator/mesos/trunk/src/Makefile.am

Modified: incubator/mesos/trunk/src/Makefile.am
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/Makefile.am?rev=1341659&r1=1341658&r2=1341659&view=diff
==============================================================================
--- incubator/mesos/trunk/src/Makefile.am (original)
+++ incubator/mesos/trunk/src/Makefile.am Tue May 22 22:06:33 2012
@@ -172,8 +172,10 @@ nodist_pkginclude_HEADERS = ../include/m
 
 if OS_LINUX
   libmesos_no_third_party_la_SOURCES += slave/lxc_isolation_module.cpp
+  libmesos_no_third_party_la_SOURCES += linux/proc.cpp
 else
   EXTRA_DIST += slave/lxc_isolation_module.cpp
+  EXTRA_DIST += linux/proc.cpp
 endif
 
 EXTRA_DIST += slave/solaris_project_isolation_module.cpp
@@ -190,10 +192,10 @@ libmesos_no_third_party_la_SOURCES += co
 	common/strings.hpp common/values.hpp				\
 	configurator/configuration.hpp configurator/configurator.hpp	\
 	configurator/option.hpp detector/detector.hpp			\
-	launcher/launcher.hpp local/local.hpp master/allocator.hpp	\
-	master/allocator_factory.hpp master/constants.hpp		\
-	master/frameworks_manager.hpp master/http.hpp			\
-	master/master.hpp master/simple_allocator.hpp			\
+	launcher/launcher.hpp linux/proc.hpp local/local.hpp		\
+	master/allocator.hpp master/allocator_factory.hpp		\
+	master/constants.hpp master/frameworks_manager.hpp		\
+	master/http.hpp master/master.hpp master/simple_allocator.hpp	\
 	master/slaves_manager.hpp master/webui.hpp			\
 	messages/messages.hpp slave/constants.hpp slave/http.hpp	\
 	slave/isolation_module.hpp slave/isolation_module_factory.hpp	\
@@ -750,6 +752,10 @@ mesos_tests_LDADD = ../third_party/libgm
 
 mesos_tests_DEPENDENCIES = # Initialized to allow += below.
 
+if OS_LINUX
+  mesos_tests_SOURCES += tests/proc_tests.cpp
+endif
+
 if HAS_JAVA
   mesos_tests_SOURCES += tests/zookeeper_server.cpp		\
                          tests/base_zookeeper_test.cpp		\

Added: incubator/mesos/trunk/src/linux/proc.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/linux/proc.cpp?rev=1341659&view=auto
==============================================================================
--- incubator/mesos/trunk/src/linux/proc.cpp (added)
+++ incubator/mesos/trunk/src/linux/proc.cpp Tue May 22 22:06:33 2012
@@ -0,0 +1,158 @@
+#include <sys/types.h> // For pid_t.
+
+#include <fstream>
+#include <set>
+#include <string>
+
+#include "common/try.hpp"
+#include "common/utils.hpp"
+
+#include "linux/proc.hpp"
+
+using std::ifstream;
+using std::set;
+using std::string;
+
+namespace mesos {
+namespace internal {
+namespace proc {
+
+Try<set<pid_t> > pids()
+{
+  set<pid_t> pids;
+
+  foreach (const string& path, utils::os::listdir("/proc")) {
+    Try<pid_t> pid = utils::numify<pid_t>(path);
+
+    // Ignore paths that can't be numified.
+    if (pid.isSome()) {
+      pids.insert(pid.get());
+    }
+  }
+
+  if (!pids.empty()) {
+    return pids;
+  } else {
+    return Try<set<pid_t> >::error("Failed to determine pids from /proc");
+  }
+}
+
+
+Try<SystemStatistics> stat()
+{
+  unsigned long long btime;
+
+  ifstream file("/proc/stat");
+
+  if (!file.is_open()) {
+    return Try<SystemStatistics>::error("Failed to open /proc/stat");
+  }
+
+  while (!file.eof()) {
+    string line;
+    getline(file, line);
+    if (file.fail() && !file.eof()) {
+      file.close();
+      return Try<SystemStatistics>::error("Failed to read /proc/stat");
+    } else if (line.find("btime ") == 0) {
+      Try<unsigned long long> number =
+        utils::numify<unsigned long long>(line.substr(6));
+      if (number.isSome()) {
+        btime = number.get();
+      } else {
+        return Try<SystemStatistics>::error(number.error());
+      }
+    }
+  }
+
+  file.close();
+
+  return SystemStatistics(btime);
+}
+
+
+Try<ProcessStatistics> stat(pid_t pid)
+{
+  string path = "/proc/" + utils::stringify(pid) + "/stat";
+
+  ifstream file(path.c_str());
+
+  if (!file.is_open()) {
+    return Try<ProcessStatistics>::error("Failed to open " + path);
+  }
+
+  std::string comm;
+  char state;
+  int ppid;
+  int pgrp;
+  int session;
+  int tty_nr;
+  int tpgid;
+  unsigned int flags;
+  unsigned long minflt;
+  unsigned long cminflt;
+  unsigned long majflt;
+  unsigned long cmajflt;
+  unsigned long utime;
+  unsigned long stime;
+  long cutime;
+  long cstime;
+  long priority;
+  long nice;
+  long num_threads;
+  long itrealvalue;
+  unsigned long long starttime;
+  unsigned long vsize;
+  long rss;
+  unsigned long rsslim;
+  unsigned long startcode;
+  unsigned long endcode;
+  unsigned long startstack;
+  unsigned long kstkeip;
+  unsigned long signal;
+  unsigned long blocked;
+  unsigned long sigcatch;
+  unsigned long wchan;
+  unsigned long nswap;
+  unsigned long cnswap;
+  int exit_signal;
+  int processor;
+  unsigned int rt_priority;
+  unsigned int policy;
+  unsigned long long delayacct_blkio_ticks;
+  unsigned long guest_time;
+  unsigned int cguest_time;
+
+  string _; // For ignoring fields.
+
+  // Parse all fields from stat.
+  file >> _ >> comm >> state >> ppid >> pgrp >> session >> tty_nr
+       >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
+       >> utime >> stime >> cutime >> cstime >> priority >> nice
+       >> num_threads >> itrealvalue >> starttime >> vsize >> rss
+       >> rsslim >> startcode >> endcode >> startstack >> kstkeip
+       >> signal >> blocked >> sigcatch >> wchan >> nswap >> cnswap
+       >> exit_signal >> processor >> rt_priority >> policy
+       >> delayacct_blkio_ticks >> guest_time >> cguest_time;
+
+  // Check for any read/parse errors.
+  if (file.fail() && !file.eof()) {
+    file.close();
+    return Try<ProcessStatistics>::error("Failed to read/parse " + path);
+  }
+
+  file.close();
+
+  return ProcessStatistics(pid, comm, state, ppid, pgrp, session, tty_nr,
+                           tpgid, flags, minflt, cminflt, majflt, cmajflt,
+                           utime, stime, cutime, cstime, priority, nice,
+                           num_threads, itrealvalue, starttime, vsize, rss,
+                           rsslim, startcode, endcode, startstack, kstkeip,
+                           signal, blocked, sigcatch, wchan, nswap, cnswap,
+                           exit_signal, processor, rt_priority, policy,
+                           delayacct_blkio_ticks, guest_time, cguest_time);
+}
+
+} // namespace proc {
+} // namespace internal {
+} // namespace mesos {

Added: incubator/mesos/trunk/src/linux/proc.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/linux/proc.hpp?rev=1341659&view=auto
==============================================================================
--- incubator/mesos/trunk/src/linux/proc.hpp (added)
+++ incubator/mesos/trunk/src/linux/proc.hpp Tue May 22 22:06:33 2012
@@ -0,0 +1,204 @@
+/**
+ * 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.
+ */
+
+#ifndef __PROC_HPP__
+#define __PROC_HPP__
+
+#include <sys/types.h> // For pid_t.
+
+#include <linux/version.h>
+
+#include <set>
+#include <string>
+
+#include "common/try.hpp"
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+#error "Expecting Linux version >= 2.6.27"
+#endif
+
+namespace mesos {
+namespace internal {
+namespace proc {
+
+// Forward declarations.
+struct SystemStatistics;
+struct ProcessStatistics;
+
+
+// Reads from /proc and returns a list of all running processes.
+Try<std::set<pid_t> > pids();
+
+// Returns the system statistics from /proc/stat.
+Try<SystemStatistics> stat();
+
+// Returns the process statistics from /proc/[pid]/stat.
+Try<ProcessStatistics> stat(pid_t pid);
+
+
+// Snapshot of a system (modeled after /proc/stat).
+struct SystemStatistics
+{
+  SystemStatistics(unsigned long long _btime)
+    : btime(_btime)
+  {}
+
+  const unsigned long long btime; // Boot time.
+  // TODO(benh): Add more.
+};
+
+
+// Snapshot of a process (modeled after /proc/[pid]/stat).
+struct ProcessStatistics
+{
+  ProcessStatistics(
+      pid_t _pid,
+      const std::string& _comm,
+      char _state,
+      pid_t _ppid,
+      pid_t _pgrp,
+      pid_t _session,
+      int _tty_nr,
+      pid_t _tpgid,
+      unsigned int _flags,
+      unsigned long _minflt,
+      unsigned long _cminflt,
+      unsigned long _majflt,
+      unsigned long _cmajflt,
+      unsigned long _utime,
+      unsigned long _stime,
+      long _cutime,
+      long _cstime,
+      long _priority,
+      long _nice,
+      long _num_threads,
+      long _itrealvalue,
+      unsigned long long _starttime,
+      unsigned long _vsize,
+      long _rss,
+      unsigned long _rsslim,
+      unsigned long _startcode,
+      unsigned long _endcode,
+      unsigned long _startstack,
+      unsigned long _kstkeip,
+      unsigned long _signal,
+      unsigned long _blocked,
+      unsigned long _sigcatch,
+      unsigned long _wchan,
+      unsigned long _nswap,
+      unsigned long _cnswap,
+      int _exit_signal, // Since Linux 2.1.22.
+      int _processor, // Since Linux 2.2.8.
+      unsigned int _rt_priority, // Since Linux 2.5.19.
+      unsigned int _policy, // Since Linux 2.5.19.
+      unsigned long long _delayacct_blkio_ticks, // Since Linux 2.6.18.
+      unsigned long _guest_time, // Since Linux 2.6.24.
+      unsigned int _cguest_time) // Since Linux 2.6.24.
+  : pid(_pid),
+    comm(_comm),
+    state(_state),
+    ppid(_ppid),
+    pgrp(_pgrp),
+    session(_session),
+    tty_nr(_tty_nr),
+    tpgid(_tpgid),
+    flags(_flags),
+    minflt(_minflt),
+    cminflt(_cminflt),
+    majflt(_majflt),
+    cmajflt(_cmajflt),
+    utime(_utime),
+    stime(_stime),
+    cutime(_cutime),
+    cstime(_cstime),
+    priority(_priority),
+    nice(_nice),
+    num_threads(_num_threads),
+    itrealvalue(_itrealvalue),
+    starttime(_starttime),
+    vsize(_vsize),
+    rss(_rss),
+    rsslim(_rsslim),
+    startcode(_startcode),
+    endcode(_endcode),
+    startstack(_startstack),
+    kstkeip(_kstkeip),
+    signal(_signal),
+    blocked(_blocked),
+    sigcatch(_sigcatch),
+    wchan(_wchan),
+    nswap(_nswap),
+    cnswap(_cnswap),
+    exit_signal(_exit_signal),
+    processor(_processor),
+    rt_priority(_rt_priority),
+    policy(_policy),
+    delayacct_blkio_ticks(_delayacct_blkio_ticks),
+    guest_time(_guest_time),
+    cguest_time(_cguest_time)
+  {}
+
+  const pid_t pid;
+  const std::string comm;
+  const char state;
+  const int ppid;
+  const int pgrp;
+  const int session;
+  const int tty_nr;
+  const int tpgid;
+  const unsigned int flags;
+  const unsigned long minflt;
+  const unsigned long cminflt;
+  const unsigned long majflt;
+  const unsigned long cmajflt;
+  const unsigned long utime;
+  const unsigned long stime;
+  const long cutime;
+  const long cstime;
+  const long priority;
+  const long nice;
+  const long num_threads;
+  const long itrealvalue;
+  const unsigned long long starttime;
+  const unsigned long vsize;
+  const long rss;
+  const unsigned long rsslim;
+  const unsigned long startcode;
+  const unsigned long endcode;
+  const unsigned long startstack;
+  const unsigned long kstkeip;
+  const unsigned long signal;
+  const unsigned long blocked;
+  const unsigned long sigcatch;
+  const unsigned long wchan;
+  const unsigned long nswap;
+  const unsigned long cnswap;
+  const int exit_signal;
+  const int processor;
+  const unsigned int rt_priority;
+  const unsigned int policy;
+  const unsigned long long delayacct_blkio_ticks;
+  const unsigned long guest_time;
+  const unsigned int cguest_time;
+};
+
+} // namespace proc {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __PROC_HPP__

Added: incubator/mesos/trunk/src/tests/proc_tests.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/src/tests/proc_tests.cpp?rev=1341659&view=auto
==============================================================================
--- incubator/mesos/trunk/src/tests/proc_tests.cpp (added)
+++ incubator/mesos/trunk/src/tests/proc_tests.cpp Tue May 22 22:06:33 2012
@@ -0,0 +1,65 @@
+/**
+ * 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 <unistd.h> // For getpid, getppid.
+
+#include <gmock/gmock.h>
+
+#include <set>
+
+#include "common/try.hpp"
+
+#include "linux/proc.hpp"
+
+using namespace mesos;
+using namespace mesos::internal;
+
+using proc::SystemStatistics;
+using proc::ProcessStatistics;
+
+using std::set;
+
+
+TEST(ProcTest, Pids)
+{
+  Try<set<pid_t> > pids = proc::pids();
+
+  ASSERT_TRUE(pids.isSome());
+  EXPECT_NE(0, pids.get().size());
+  EXPECT_EQ(1, pids.get().count(getpid()));
+  EXPECT_EQ(1, pids.get().count(1));
+}
+
+
+TEST(ProcTest, SystemStatistics)
+{
+  Try<SystemStatistics> statistics = proc::stat();
+
+  ASSERT_TRUE(statistics.isSome());
+  EXPECT_NE(0, statistics.get().btime);
+}
+
+
+TEST(ProcTest, ProcessStatistics)
+{
+  Try<ProcessStatistics> statistics = proc::stat(getpid());
+
+  ASSERT_TRUE(statistics.isSome());
+  EXPECT_EQ(getpid(), statistics.get().pid);
+  EXPECT_EQ(getppid(), statistics.get().ppid);
+}