Apache Mesos
posix.hpp
Go to the documentation of this file.
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #ifndef __POSIX_ISOLATOR_HPP__
18 #define __POSIX_ISOLATOR_HPP__
19 
20 #include <process/future.hpp>
21 #include <process/id.hpp>
22 
23 #include <stout/hashmap.hpp>
24 #include <stout/os.hpp>
25 
26 #include <stout/os/pstree.hpp>
27 
28 #include "slave/flags.hpp"
29 
31 
32 #include "usage/usage.hpp"
33 
34 namespace mesos {
35 namespace internal {
36 namespace slave {
37 
38 // A basic MesosIsolatorProcess that keeps track of the pid but
39 // doesn't do any resource isolation. Subclasses must implement
40 // usage() for their appropriate resource(s).
42 {
43 public:
45  const std::vector<mesos::slave::ContainerState>& state,
46  const hashset<ContainerID>& orphans) override
47  {
48  foreach (const mesos::slave::ContainerState& run, state) {
49  // This should (almost) never occur: see comment in
50  // SubprocessLauncher::recover().
51  if (pids.contains(run.container_id())) {
52  return process::Failure("Container already recovered");
53  }
54 
55  pids.put(run.container_id(), static_cast<pid_t>(run.pid()));
56 
59  promises.put(run.container_id(), promise);
60  }
61 
62  return Nothing();
63  }
64 
66  const ContainerID& containerId,
67  const mesos::slave::ContainerConfig& containerConfig) override
68  {
69  if (promises.contains(containerId)) {
70  return process::Failure("Container " + stringify(containerId) +
71  " has already been prepared");
72  }
73 
76  promises.put(containerId, promise);
77 
78  return None();
79  }
80 
82  const ContainerID& containerId,
83  pid_t pid) override
84  {
85  if (!promises.contains(containerId)) {
86  return process::Failure("Unknown container: " + stringify(containerId));
87  }
88 
89  pids.put(containerId, pid);
90 
91  return Nothing();
92  }
93 
95  const ContainerID& containerId) override
96  {
97  if (!promises.contains(containerId)) {
98  return process::Failure("Unknown container: " + stringify(containerId));
99  }
100 
101  return promises[containerId]->future();
102  }
103 
105  const ContainerID& containerId,
106  const Resources& resourceRequests,
107  const google::protobuf::Map<
108  std::string, Value::Scalar>& resourceLimits = {}) override
109  {
110  if (!promises.contains(containerId)) {
111  return process::Failure("Unknown container: " + stringify(containerId));
112  }
113 
114  // No resources are actually isolated so nothing to do.
115  return Nothing();
116  }
117 
118  process::Future<Nothing> cleanup(const ContainerID& containerId) override
119  {
120  if (!promises.contains(containerId)) {
121  VLOG(1) << "Ignoring cleanup request for unknown container "
122  << containerId;
123 
124  return Nothing();
125  }
126 
127  // TODO(idownes): We should discard the container's promise here to signal
128  // to anyone that holds the future from watch().
129  promises.erase(containerId);
130 
131  pids.erase(containerId);
132 
133  return Nothing();
134  }
135 
136 protected:
138  hashmap<ContainerID,
141 };
142 
143 
145 {
146 public:
148  {
151 
152  return new MesosIsolator(process);
153  }
154 
156  const ContainerID& containerId) override
157  {
158  if (!pids.contains(containerId)) {
159  LOG(WARNING) << "No resource usage for unknown container '"
160  << containerId << "'";
161  return ResourceStatistics();
162  }
163 
164  // Use 'mesos-usage' but only request 'cpus_' values.
166  mesos::internal::usage(pids.at(containerId), false, true);
167  if (usage.isError()) {
168  return process::Failure(usage.error());
169  }
170  return usage.get();
171  }
172 
173 protected:
175  : ProcessBase(process::ID::generate("posix-cpu-isolator")) {}
176 };
177 
179 {
180 public:
182  {
185 
186  return new MesosIsolator(process);
187  }
188 
190  const ContainerID& containerId) override
191  {
192  if (!pids.contains(containerId)) {
193  LOG(WARNING) << "No resource usage for unknown container '"
194  << containerId << "'";
195  return ResourceStatistics();
196  }
197 
198  // Use 'mesos-usage' but only request 'mem_' values.
200  mesos::internal::usage(pids.at(containerId), true, false);
201  if (usage.isError()) {
202  return process::Failure(usage.error());
203  }
204  return usage.get();
205  }
206 
207 protected:
209  : ProcessBase(process::ID::generate("posix-mem-isolator")) {}
210 };
211 
212 } // namespace slave {
213 } // namespace internal {
214 } // namespace mesos {
215 
216 #endif // __POSIX_ISOLATOR_HPP__
std::string generate(const std::string &prefix="")
Returns &#39;prefix(N)&#39; where N represents the number of instances where the same prefix (wrt...
virtual process::Future< ResourceStatistics > usage(const ContainerID &containerId)
Definition: isolator.hpp:133
Definition: isolator.hpp:38
Definition: nothing.hpp:16
ProcessBase(const std::string &id="")
T & get()&
Definition: try.hpp:80
static Try< mesos::slave::Isolator * > create(const Flags &flags)
Definition: posix.hpp:147
Definition: check.hpp:33
Definition: future.hpp:668
PosixCpuIsolatorProcess()
Definition: posix.hpp:174
process::Future< Option< mesos::slave::ContainerLaunchInfo > > prepare(const ContainerID &containerId, const mesos::slave::ContainerConfig &containerConfig) override
Definition: posix.hpp:65
Definition: resources.hpp:83
process::Future< ResourceStatistics > usage(const ContainerID &containerId) override
Definition: posix.hpp:189
Definition: flags.hpp:39
hashmap< ContainerID, process::Owned< process::Promise< mesos::slave::ContainerLimitation > > > promises
Definition: posix.hpp:140
DWORD pid_t
Definition: windows.hpp:181
Try< ResourceStatistics > usage(pid_t pid, bool mem=true, bool cpus=true)
process::Future< Nothing > update(const ContainerID &containerId, const Resources &resourceRequests, const google::protobuf::Map< std::string, Value::Scalar > &resourceLimits={}) override
Definition: posix.hpp:104
process::Future< Nothing > recover(const std::vector< mesos::slave::ContainerState > &state, const hashset< ContainerID > &orphans) override
Definition: posix.hpp:44
Definition: agent.hpp:25
static Try< mesos::slave::Isolator * > create(const Flags &flags)
Definition: posix.hpp:181
Protocol< PromiseRequest, PromiseResponse > promise
process::Future< mesos::slave::ContainerLimitation > watch(const ContainerID &containerId) override
Definition: posix.hpp:94
static Try error(const E &e)
Definition: try.hpp:43
process::Future< Nothing > isolate(const ContainerID &containerId, pid_t pid) override
Definition: posix.hpp:81
void run(std::vector< C > &&callbacks, Arguments &&...arguments)
Definition: future.hpp:621
void put(const Key &key, Value &&value)
Definition: hashmap.hpp:104
Result< Process > process(pid_t pid)
Definition: freebsd.hpp:30
Definition: none.hpp:27
Definition: attributes.hpp:24
bool isError() const
Definition: try.hpp:78
PosixMemIsolatorProcess()
Definition: posix.hpp:208
Definition: executor.hpp:48
hashmap< ContainerID, pid_t > pids
Definition: posix.hpp:137
std::string stringify(int flags)
Definition: owned.hpp:36
process::Future< Nothing > cleanup(const ContainerID &containerId) override
Definition: posix.hpp:118
process::Future< ResourceStatistics > usage(const ContainerID &containerId) override
Definition: posix.hpp:155
bool contains(const Key &key) const
Definition: hashmap.hpp:86
Definition: parse.hpp:33