You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by ji...@apache.org on 2016/10/22 05:23:54 UTC

mesos git commit: Added abstractions for working with POSIX resource limits.

Repository: mesos
Updated Branches:
  refs/heads/master aea342dcd -> f64dbe606


Added abstractions for working with POSIX resource limits.

This commit adds high-level functions to set POSIX resource limits and
associated protobuf definitions.

This is intended to be used by the containerizer in later changes.

Review: https://reviews.apache.org/r/53061/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/f64dbe60
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/f64dbe60
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/f64dbe60

Branch: refs/heads/master
Commit: f64dbe6066dd65f37baea8bfa4257654bee80df8
Parents: aea342d
Author: Benjamin Bannier <be...@mesosphere.io>
Authored: Fri Oct 21 21:10:00 2016 -0700
Committer: Jie Yu <yu...@gmail.com>
Committed: Fri Oct 21 22:16:47 2016 -0700

----------------------------------------------------------------------
 include/mesos/mesos.proto    |  41 +++++++++++
 include/mesos/type_utils.hpp |   3 +
 include/mesos/v1/mesos.proto |  41 +++++++++++
 src/CMakeLists.txt           |   5 ++
 src/Makefile.am              |   2 +
 src/common/parse.hpp         |  11 +++
 src/common/type_utils.cpp    |   6 ++
 src/posix/rlimit.cpp         | 138 ++++++++++++++++++++++++++++++++++++++
 src/posix/rlimit.hpp         |  41 +++++++++++
 src/v1/mesos.cpp             |   6 ++
 src/v1/parse.hpp             |  12 ++++
 11 files changed, 306 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/f64dbe60/include/mesos/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/mesos.proto b/include/mesos/mesos.proto
index 22ce886..32533a1 100644
--- a/include/mesos/mesos.proto
+++ b/include/mesos/mesos.proto
@@ -2068,6 +2068,47 @@ message LinuxInfo {
 
 
 /**
+* Encapsulation for POSIX rlimits, see
+* http://pubs.opengroup.org/onlinepubs/009695399/functions/getrlimit.html.
+* Note that some types might only be defined for Linux.
+* We use a custom prefix to avoid conflict with existing system macros
+* (e.g., `RLIMIT_CPU` or `NOFILE`).
+*/
+message RLimitInfo {
+  message RLimit {
+    enum Type {
+      UNKNOWN = 0;
+      RLMT_AS = 1;
+      RLMT_CORE = 2;
+      RLMT_CPU = 3;
+      RLMT_DATA = 4;
+      RLMT_FSIZE = 5;
+      RLMT_LOCKS = 6;
+      RLMT_MEMLOCK = 7;
+      RLMT_MSGQUEUE = 8;
+      RLMT_NICE = 9;
+      RLMT_NOFILE = 10;
+      RLMT_NPROC = 11;
+      RLMT_RSS = 12;
+      RLMT_RTPRIO = 13;
+      RLMT_RTTIME = 14;
+      RLMT_SIGPENDING = 15;
+      RLMT_STACK = 16;
+    }
+    optional Type type = 1;
+
+    // Either both are set or both are not set.
+    // If both are not set, it represents unlimited.
+    // If both are set, we require `soft` <= `hard`.
+    optional uint64 hard = 2;
+    optional uint64 soft = 3;
+  }
+
+  repeated RLimit rlimits = 1;
+}
+
+
+/**
  * Describes a container configuration and allows extensible
  * configurations for different container implementations.
  */

http://git-wip-us.apache.org/repos/asf/mesos/blob/f64dbe60/include/mesos/type_utils.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/type_utils.hpp b/include/mesos/type_utils.hpp
index 88c7bcf..7824407 100644
--- a/include/mesos/type_utils.hpp
+++ b/include/mesos/type_utils.hpp
@@ -309,6 +309,9 @@ std::ostream& operator<<(
 std::ostream& operator<<(std::ostream& stream, const Image::Type& imageType);
 
 
+std::ostream& operator<<(std::ostream& stream, const RLimitInfo& rlimitInfo);
+
+
 template <typename T>
 inline std::ostream& operator<<(
     std::ostream& stream,

http://git-wip-us.apache.org/repos/asf/mesos/blob/f64dbe60/include/mesos/v1/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/v1/mesos.proto b/include/mesos/v1/mesos.proto
index d113283..a2df787 100644
--- a/include/mesos/v1/mesos.proto
+++ b/include/mesos/v1/mesos.proto
@@ -2067,6 +2067,47 @@ message LinuxInfo {
 
 
 /**
+* Encapsulation for POSIX rlimits, see
+* http://pubs.opengroup.org/onlinepubs/009695399/functions/getrlimit.html.
+* Note that some types might only be defined for Linux.
+* We use a custom prefix to avoid conflict with existing system macros
+* (e.g., `RLIMIT_CPU` or `NOFILE`).
+*/
+message RLimitInfo {
+  message RLimit {
+    enum Type {
+      UNKNOWN = 0;
+      RLMT_AS = 1;
+      RLMT_CORE = 2;
+      RLMT_CPU = 3;
+      RLMT_DATA = 4;
+      RLMT_FSIZE = 5;
+      RLMT_LOCKS = 6;
+      RLMT_MEMLOCK = 7;
+      RLMT_MSGQUEUE = 8;
+      RLMT_NICE = 9;
+      RLMT_NOFILE = 10;
+      RLMT_NPROC = 11;
+      RLMT_RSS = 12;
+      RLMT_RTPRIO = 13;
+      RLMT_RTTIME = 14;
+      RLMT_SIGPENDING = 15;
+      RLMT_STACK = 16;
+    }
+    optional Type type = 1;
+
+    // Either both are set or both are not set.
+    // If both are not set, it represents unlimited.
+    // If both are set, we require `soft` <= `hard`.
+    optional uint64 hard = 2;
+    optional uint64 soft = 3;
+  }
+
+  repeated RLimit rlimits = 1;
+}
+
+
+/**
  * Describes a container configuration and allows extensible
  * configurations for different container implementations.
  */

http://git-wip-us.apache.org/repos/asf/mesos/blob/f64dbe60/src/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e60d34c..22fdd85 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -377,6 +377,10 @@ if (NOT WIN32)
     )
 endif (NOT WIN32)
 
+set(POSIX_SRC
+  posix/rlimit.cpp
+  )
+
 set(USAGE_SRC
   usage/usage.cpp
   )
@@ -440,6 +444,7 @@ if (NOT WIN32)
     ${HDFS_SRC}
     ${LOCAL_SRC}
     ${LOG_SRC}
+    ${POSIX_SRC}
     ${SCHED_SRC}
     ${SCHEDULER_SRC}
     ${STATE_SRC}

http://git-wip-us.apache.org/repos/asf/mesos/blob/f64dbe60/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index d06a9fe..3d4196c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -801,6 +801,7 @@ libmesos_no_3rdparty_la_SOURCES +=					\
   master/detector/zookeeper.cpp						\
   messages/messages.cpp							\
   module/manager.cpp							\
+  posix/rlimit.cpp							\
   sched/sched.cpp							\
   scheduler/scheduler.cpp						\
   slave/constants.cpp							\
@@ -927,6 +928,7 @@ libmesos_no_3rdparty_la_SOURCES +=					\
   messages/flags.hpp							\
   messages/messages.hpp							\
   module/manager.hpp							\
+  posix/rlimit.hpp							\
   sched/constants.hpp							\
   sched/flags.hpp							\
   scheduler/constants.hpp						\

http://git-wip-us.apache.org/repos/asf/mesos/blob/f64dbe60/src/common/parse.hpp
----------------------------------------------------------------------
diff --git a/src/common/parse.hpp b/src/common/parse.hpp
index ee26717..0479a54 100644
--- a/src/common/parse.hpp
+++ b/src/common/parse.hpp
@@ -175,6 +175,17 @@ inline Try<mesos::CapabilityInfo> parse(const std::string& value)
 }
 
 
+template <>
+inline Try<mesos::RLimitInfo> parse(const std::string& value)
+{
+  Try<JSON::Object> json = parse<JSON::Object>(value);
+  if (json.isError()) {
+    return Error(json.error());
+  }
+
+  return protobuf::parse<mesos::RLimitInfo>(json.get());
+}
+
 } // namespace flags {
 
 #endif // __COMMON_PARSE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/f64dbe60/src/common/type_utils.cpp
----------------------------------------------------------------------
diff --git a/src/common/type_utils.cpp b/src/common/type_utils.cpp
index e249fae..8270f80 100644
--- a/src/common/type_utils.cpp
+++ b/src/common/type_utils.cpp
@@ -512,6 +512,12 @@ ostream& operator<<(ostream& stream, const RateLimits& limits)
 }
 
 
+ostream& operator<<(ostream& stream, const RLimitInfo& rlimitInfo)
+{
+  return stream << JSON::protobuf(rlimitInfo);
+}
+
+
 ostream& operator<<(ostream& stream, const SlaveID& slaveId)
 {
   return stream << slaveId.value();

http://git-wip-us.apache.org/repos/asf/mesos/blob/f64dbe60/src/posix/rlimit.cpp
----------------------------------------------------------------------
diff --git a/src/posix/rlimit.cpp b/src/posix/rlimit.cpp
new file mode 100644
index 0000000..15c86ed
--- /dev/null
+++ b/src/posix/rlimit.cpp
@@ -0,0 +1,138 @@
+// 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 "posix/rlimit.hpp"
+
+#include <sys/time.h>
+#include <sys/types.h>
+
+// Intentionally include `sys/resource.h` after `sys/time.h` and
+// `sys/types.h`. This is the suggested include pattern under e.g.,
+// BSD, https://www.freebsd.org/cgi/man.cgi?query=setrlimit.
+#include <sys/resource.h>
+
+#include <stout/os/strerror.hpp>
+
+#include <stout/unreachable.hpp>
+
+namespace mesos {
+namespace internal {
+namespace rlimit {
+
+Try<int> convert(RLimitInfo::RLimit::Type type)
+{
+  const Error error(
+      "Resource type '" + RLimitInfo_RLimit_Type_Name(type) +
+      "' not supported");
+
+  switch (type) {
+    // Resource types defined in XSI.
+    case RLimitInfo::RLimit::RLMT_AS:       return RLIMIT_AS;
+    case RLimitInfo::RLimit::RLMT_CORE:     return RLIMIT_CORE;
+    case RLimitInfo::RLimit::RLMT_CPU:      return RLIMIT_CPU;
+    case RLimitInfo::RLimit::RLMT_DATA:     return RLIMIT_DATA;
+    case RLimitInfo::RLimit::RLMT_FSIZE:    return RLIMIT_FSIZE;
+    case RLimitInfo::RLimit::RLMT_NOFILE:   return RLIMIT_NOFILE;
+    case RLimitInfo::RLimit::RLMT_STACK:    return RLIMIT_STACK;
+
+    // Resource types also defined on BSDs like e.g., OS X.
+    case RLimitInfo::RLimit::RLMT_MEMLOCK:  return RLIMIT_MEMLOCK;
+    case RLimitInfo::RLimit::RLMT_NPROC:    return RLIMIT_NPROC;
+    case RLimitInfo::RLimit::RLMT_RSS:      return RLIMIT_RSS;
+
+    // Resource types defined in >=Linux 2.6.36.
+    // NOTE: The resource limits defined for Linux are currently the
+    // maximal possible set of understood types. Here we explicitly
+    // list all types and in particular do not use a `default` case,
+    // see MESOS-3754.
+    case RLimitInfo::RLimit::RLMT_LOCKS:
+#ifdef RLIMIT_LOCKS
+      return RLIMIT_LOCKS;
+#else
+      return error;
+#endif
+
+    case RLimitInfo::RLimit::RLMT_MSGQUEUE:
+#ifdef RLIMIT_MSGQUEUE
+      return RLIMIT_MSGQUEUE;
+#else
+      return error;
+#endif
+
+    case RLimitInfo::RLimit::RLMT_NICE:
+#ifdef RLIMIT_NICE
+      return RLIMIT_NICE;
+#else
+      return error;
+#endif
+
+    case RLimitInfo::RLimit::RLMT_RTPRIO:
+#ifdef RLIMIT_RTPRIO
+      return RLIMIT_RTPRIO;
+#else
+      return error;
+#endif
+
+    case RLimitInfo::RLimit::RLMT_RTTIME:
+#ifdef RLIMIT_RTTIME
+      return RLIMIT_RTTIME;
+#else
+      return error;
+#endif
+
+    case RLimitInfo::RLimit::RLMT_SIGPENDING:
+#ifdef RLIMIT_SIGPENDING
+      return RLIMIT_SIGPENDING;
+#else
+      return error;
+#endif
+
+    case RLimitInfo::RLimit::UNKNOWN:
+      return Error("Unknown rlimit type");
+  }
+
+  UNREACHABLE();
+}
+
+
+Try<Nothing> set(const RLimitInfo::RLimit& limit)
+{
+  const Try<int> resource = convert(limit.type());
+  if (resource.isError()) {
+    return Error("Could not convert rlimit: " + resource.error());
+  }
+
+  ::rlimit resourceLimit;
+  if (limit.has_soft() && limit.has_hard()) {
+    resourceLimit.rlim_cur = limit.soft();
+    resourceLimit.rlim_max = limit.hard();
+  } else if (!limit.has_soft() && !limit.has_hard()) {
+    resourceLimit.rlim_cur = RLIM_INFINITY;
+    resourceLimit.rlim_max = RLIM_INFINITY;
+  } else {
+    return Error("Invalid rlimit values");
+  }
+
+  if (setrlimit(resource.get(), &resourceLimit) != 0) {
+    return Error("Failed to set rlimit: " + os::strerror(errno));
+  }
+
+  return Nothing();
+}
+
+} // namespace rlimit {
+} // namespace internal {
+} // namespace mesos {

http://git-wip-us.apache.org/repos/asf/mesos/blob/f64dbe60/src/posix/rlimit.hpp
----------------------------------------------------------------------
diff --git a/src/posix/rlimit.hpp b/src/posix/rlimit.hpp
new file mode 100644
index 0000000..eafb5e7
--- /dev/null
+++ b/src/posix/rlimit.hpp
@@ -0,0 +1,41 @@
+// 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 __POSIX_RLIMIT_HPP__
+#define __POSIX_RLIMIT_HPP__
+
+#include <stout/nothing.hpp>
+#include <stout/try.hpp>
+
+#include <mesos/mesos.hpp>
+
+namespace mesos {
+namespace internal {
+namespace rlimit {
+
+// Convert from Mesos RLimit types to system
+// resources (see e.g., `sys/resource.h`).
+Try<int> convert(RLimitInfo::RLimit::Type type);
+
+
+// Set the given resource limit for the calling process.
+Try<Nothing> set(const RLimitInfo::RLimit& limit);
+
+} // namespace rlimit {
+} // namespace internal {
+} // namespace mesos {
+
+#endif // __POSIX_RLIMIT_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/f64dbe60/src/v1/mesos.cpp
----------------------------------------------------------------------
diff --git a/src/v1/mesos.cpp b/src/v1/mesos.cpp
index 4c8ee91..5b89603 100644
--- a/src/v1/mesos.cpp
+++ b/src/v1/mesos.cpp
@@ -438,6 +438,12 @@ ostream& operator<<(ostream& stream, const RateLimits& limits)
 }
 
 
+ostream& operator<<(ostream& stream, const RLimitInfo& limits)
+{
+  return stream << JSON::protobuf(limits);
+}
+
+
 ostream& operator<<(ostream& stream, const AgentID& agentId)
 {
   return stream << agentId.value();

http://git-wip-us.apache.org/repos/asf/mesos/blob/f64dbe60/src/v1/parse.hpp
----------------------------------------------------------------------
diff --git a/src/v1/parse.hpp b/src/v1/parse.hpp
index 8882b32..86bd7e8 100644
--- a/src/v1/parse.hpp
+++ b/src/v1/parse.hpp
@@ -37,6 +37,18 @@ inline Try<mesos::v1::CapabilityInfo> parse(const std::string& value)
 
 
 template <>
+inline Try<mesos::v1::RLimitInfo> parse(const std::string& value)
+{
+  Try<JSON::Object> json = parse<JSON::Object>(value);
+  if (json.isError()) {
+    return Error(json.error());
+  }
+
+  return protobuf::parse<mesos::v1::RLimitInfo>(json.get());
+}
+
+
+template <>
 inline Try<mesos::v1::TaskGroupInfo> parse(const std::string& value)
 {
   // Convert from string or file to JSON.