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);
+}