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::list<mesos::slave::ContainerState>& state,
46  const hashset<ContainerID>& orphans)
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)
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)
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)
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& resources)
107  {
108  if (!promises.contains(containerId)) {
109  return process::Failure("Unknown container: " + stringify(containerId));
110  }
111 
112  // No resources are actually isolated so nothing to do.
113  return Nothing();
114  }
115 
116  virtual process::Future<Nothing> cleanup(const ContainerID& containerId)
117  {
118  if (!promises.contains(containerId)) {
119  VLOG(1) << "Ignoring cleanup request for unknown container "
120  << containerId;
121 
122  return Nothing();
123  }
124 
125  // TODO(idownes): We should discard the container's promise here to signal
126  // to anyone that holds the future from watch().
127  promises.erase(containerId);
128 
129  pids.erase(containerId);
130 
131  return Nothing();
132  }
133 
134 protected:
136  hashmap<ContainerID,
139 };
140 
141 
143 {
144 public:
146  {
149 
150  return new MesosIsolator(process);
151  }
152 
154  const ContainerID& containerId)
155  {
156  if (!pids.contains(containerId)) {
157  LOG(WARNING) << "No resource usage for unknown container '"
158  << containerId << "'";
159  return ResourceStatistics();
160  }
161 
162  // Use 'mesos-usage' but only request 'cpus_' values.
164  mesos::internal::usage(pids.get(containerId).get(), false, true);
165  if (usage.isError()) {
166  return process::Failure(usage.error());
167  }
168  return usage.get();
169  }
170 
171 protected:
173  : ProcessBase(process::ID::generate("posix-cpu-isolator")) {}
174 };
175 
177 {
178 public:
180  {
183 
184  return new MesosIsolator(process);
185  }
186 
188  const ContainerID& containerId)
189  {
190  if (!pids.contains(containerId)) {
191  LOG(WARNING) << "No resource usage for unknown container '"
192  << containerId << "'";
193  return ResourceStatistics();
194  }
195 
196  // Use 'mesos-usage' but only request 'mem_' values.
198  mesos::internal::usage(pids.get(containerId).get(), true, false);
199  if (usage.isError()) {
200  return process::Failure(usage.error());
201  }
202  return usage.get();
203  }
204 
205 protected:
207  : ProcessBase(process::ID::generate("posix-mem-isolator")) {}
208 };
209 
210 } // namespace slave {
211 } // namespace internal {
212 } // namespace mesos {
213 
214 #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:129
virtual process::Future< Option< mesos::slave::ContainerLaunchInfo > > prepare(const ContainerID &containerId, const mesos::slave::ContainerConfig &containerConfig)
Definition: posix.hpp:65
Definition: isolator.hpp:38
Definition: nothing.hpp:16
ProcessBase(const std::string &id="")
T & get()&
Definition: try.hpp:73
static Try< mesos::slave::Isolator * > create(const Flags &flags)
Definition: posix.hpp:145
Definition: check.hpp:33
Definition: future.hpp:665
PosixCpuIsolatorProcess()
Definition: posix.hpp:172
Definition: resources.hpp:79
Definition: flags.hpp:39
virtual process::Future< ResourceStatistics > usage(const ContainerID &containerId)
Definition: posix.hpp:153
virtual process::Future< Nothing > update(const ContainerID &containerId, const Resources &resources)
Definition: posix.hpp:104
hashmap< ContainerID, process::Owned< process::Promise< mesos::slave::ContainerLimitation > > > promises
Definition: posix.hpp:138
DWORD pid_t
Definition: windows.hpp:187
Try< ResourceStatistics > usage(pid_t pid, bool mem=true, bool cpus=true)
virtual process::Future< Nothing > isolate(const ContainerID &containerId, pid_t pid)
Definition: posix.hpp:81
Definition: spec.hpp:30
static Try< mesos::slave::Isolator * > create(const Flags &flags)
Definition: posix.hpp:179
void put(const Key &key, const Value &value)
Definition: hashmap.hpp:104
const T & get() const &
Definition: option.hpp:118
Protocol< PromiseRequest, PromiseResponse > promise
static Try error(const E &e)
Definition: try.hpp:42
void run(std::vector< C > &&callbacks, Arguments &&...arguments)
Definition: future.hpp:618
Result< Process > process(pid_t pid)
Definition: freebsd.hpp:30
Definition: none.hpp:27
Definition: attributes.hpp:24
bool isError() const
Definition: try.hpp:71
PosixMemIsolatorProcess()
Definition: posix.hpp:206
Definition: executor.hpp:47
hashmap< ContainerID, pid_t > pids
Definition: posix.hpp:135
virtual process::Future< mesos::slave::ContainerLimitation > watch(const ContainerID &containerId)
Definition: posix.hpp:94
virtual process::Future< Nothing > cleanup(const ContainerID &containerId)
Definition: posix.hpp:116
virtual process::Future< ResourceStatistics > usage(const ContainerID &containerId)
Definition: posix.hpp:187
virtual process::Future< Nothing > recover(const std::list< mesos::slave::ContainerState > &state, const hashset< ContainerID > &orphans)
Definition: posix.hpp:44
std::string stringify(int flags)
Definition: owned.hpp:36
bool contains(const Key &key) const
Definition: hashmap.hpp:86
Definition: parse.hpp:33
Option< Value > get(const Key &key) const
Definition: hashmap.hpp:112