Apache Mesos
cgroups.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 __CGROUPS_HPP__
18 #define __CGROUPS_HPP__
19 
20 #include <stdint.h>
21 #include <stdlib.h>
22 
23 #include <set>
24 #include <string>
25 #include <vector>
26 
27 #include <sys/types.h>
28 
29 #include <process/future.hpp>
30 #include <process/timeout.hpp>
31 
32 #include <stout/bytes.hpp>
33 #include <stout/duration.hpp>
34 #include <stout/hashmap.hpp>
35 #include <stout/nothing.hpp>
36 #include <stout/option.hpp>
37 #include <stout/try.hpp>
38 
39 namespace cgroups {
40 
41 // Freezing a cgroup may get stuck (see MESOS-1689 for details). To
42 // workaround, we may want to thaw the cgroup and retry freezing it.
43 // This is the suggested retry interval.
45 
46 
47 // Default number of assign attempts when moving threads to a cgroup.
48 const unsigned int THREAD_ASSIGN_RETRIES = 100;
49 
50 // We use the following notations throughout the cgroups code. The notations
51 // here are derived from the kernel documentation. More details can be found in
52 // <kernel-source>/Documentation/cgroups/cgroups.txt.
53 //
54 // Hierarchy - A hierarchy contains a set of cgroups arranged in a tree such
55 // that every task in the system is in exactly one of the cgroups
56 // in the hierarchy. One or more subsystems can be attached to a
57 // hierarchy.
58 // Subsystem - A subsystem (e.g. cpu, memory, cpuset, etc) in the kernel. Each
59 // subsystem can be attached to only one hierarchy.
60 // Cgroup - A cgroup is just a set of tasks with a set of controls for one
61 // or more subsystems.
62 // Control - A control file in a cgroup (e.g. tasks, cpu.shares).
63 
64 
65 // TODO(idownes): Rework all functions in this file to better support
66 // separately mounted subsystems.
67 
68 // Prepare a hierarchy which has the specified subsystem (and only that
69 // subsystem) mounted and also has the specified cgroup created. Returns the
70 // hierarchy. Checks are made to ensure that cgroups are supported and that
71 // nested cgroups can be created.
73  const std::string& baseHierarchy,
74  const std::string& subsystem,
75  const std::string& cgroup);
76 
77 
78 // Returns error if any of the following is true:
79 // (a) hierarchy is not mounted,
80 // (b) cgroup does not exist
81 // (c) control file does not exist.
83  const std::string& hierarchy,
84  const std::string& cgroup = "",
85  const std::string& control = "");
86 
87 
88 // Check whether cgroups module is enabled on the current machine.
89 // @return True if cgroups module is enabled.
90 // False if cgroups module is not available.
91 bool enabled();
92 
93 
94 // Return the currently active hierarchies.
95 // @return A set of active hierarchy paths (e.g., '/cgroup').
96 // Error if unexpected happens.
98 
99 
100 // Get an already mounted hierarchy that has 'subsystems' attached.
101 // This function will return an error if we are unable to find the
102 // hierarchies or if we are unable to find if the subsystems are
103 // mounted at a given hierarchy.
104 // @param subsystems Comma-separated subsystem names.
105 // @return Path to the hierarchy root, if a hierarchy with all the
106 // given subsystems mounted exists.
107 // None, if no such hierarchy exists.
108 // Error, if the operation fails.
109 Result<std::string> hierarchy(const std::string& subsystems);
110 
111 
112 // Check whether all the given subsystems are enabled on the current machine.
113 // @param subsystems Comma-separated subsystem names.
114 // @return True if all the given subsystems are enabled.
115 // False if any of the given subsystems is not enabled.
116 // Error if something unexpected happens.
117 Try<bool> enabled(const std::string& subsystems);
118 
119 
120 // Return true if any of the given subsystems is currently attached to a
121 // hierarchy.
122 // @param subsystems Comma-separated subsystem names.
123 // @return True if any of the given subsystems is being attached.
124 // False if non of the given subsystems is being attached.
125 // Error if something unexpected happens.
126 Try<bool> busy(const std::string& subsystems);
127 
128 
129 // Return the currently enabled subsystems.
130 // @return A set of enabled subsystem names if succeeds.
131 // Error if unexpected happens.
133 
134 
135 // Return a set of subsystems that are attached to a given hierarchy. An error
136 // will be returned if the given hierarchy is not currently mounted with a
137 // cgroups virtual file system. As a result, this function can be used to check
138 // whether a hierarchy is indeed a cgroups hierarchy root.
139 // @param hierarchy Path to the hierarchy root.
140 // @return A set of attached subsystem names.
141 // Error otherwise, (e.g., hierarchy does not exist or is not mounted).
142 Try<std::set<std::string>> subsystems(const std::string& hierarchy);
143 
144 
145 // Mount a cgroups hierarchy and attach the given subsystems to
146 // it. This function will return error if the path given for the
147 // hierarchy already exists. Also, the function will return error if
148 // a subsystem in the given subsystem list has already been attached
149 // to another hierarchy. On success, the cgroups virtual file system
150 // will be mounted with the proper subsystems attached. On failure,
151 // mount will be retried the specified number of times.
152 // @param hierarchy Path to the hierarchy root.
153 // @param subsystems Comma-separated subsystem names.
154 // @param retry Number of times to retry mount.
155 // @return Some if the operation succeeds.
156 // Error if the operation fails.
158  const std::string& hierarchy,
159  const std::string& subsystems,
160  int retry = 0);
161 
162 
163 // Unmount the cgroups virtual file system from the given hierarchy
164 // root. The caller must make sure to remove all cgroups in the
165 // hierarchy before unmount. This function assumes the given hierarchy
166 // is currently mounted with a cgroups virtual file system. It will
167 // return error if the given hierarchy has any cgroups.
168 // @param hierarchy Path to the hierarchy root.
169 // @return Some if the operation succeeds.
170 // Error if the operation fails.
171 Try<Nothing> unmount(const std::string& hierarchy);
172 
173 
174 // Returns true if the given hierarchy root is mounted as a cgroups
175 // virtual file system with the specified subsystems attached.
176 // @param hierarchy Path to the hierarchy root.
177 // @return True if the given directory is a hierarchy root and all of the
178 // specified subsystems are attached.
179 // False if the directory is not a hierarchy (or doesn't exist)
180 // or some of the specified subsystems are not attached.
181 // Error if the operation fails.
183  const std::string& hierarchy,
184  const std::string& subsystems = "");
185 
186 
187 // Create a cgroup in a given hierarchy. To create a cgroup, one just
188 // needs to create a directory in the cgroups virtual file system. The
189 // given cgroup is a relative path to the given hierarchy. This
190 // function assumes the given hierarchy is valid and is currently
191 // mounted with a cgroup virtual file system. The function also
192 // assumes the given cgroup is valid.
193 // @param hierarchy Path to the hierarchy root.
194 // @param cgroup Path to the cgroup relative to the hierarchy root.
195 // @param recursive Will create nested cgroups
196 // @return Some if the operation succeeds.
197 // Error if the operation fails.
199  const std::string& hierarchy,
200  const std::string& cgroup,
201  bool recursive = false);
202 
203 
204 // Remove a cgroup in a given hierarchy. To remove a cgroup, one needs
205 // to remove the corresponding directory in the cgroups virtual file
206 // system. A cgroup cannot be removed if it has processes or
207 // sub-cgroups inside. This function does nothing but tries to remove
208 // the corresponding directory of the given cgroup. It will return
209 // error if the remove operation fails because it has either processes
210 // or sub-cgroups inside. The cgroup will NOT be removed recursively.
211 // This function assumes that the given hierarchy and cgroup are
212 // valid.
213 // @param hierarchy Path to the hierarchy root.
214 // @param cgroup Path to the cgroup relative to the hierarchy root.
215 Try<Nothing> remove(const std::string& hierarchy, const std::string& cgroup);
216 
217 
218 // Returns true if the given cgroup under a given hierarchy exists.
219 // @param hierarchy Path to the hierarchy root.
220 // @param cgroup Path to the cgroup relative to the hierarchy root.
221 // @return True if the cgroup exists.
222 // False if the cgroup does not exist.
223 bool exists(const std::string& hierarchy, const std::string& cgroup);
224 
225 
226 // Return all the cgroups under the given cgroup of a given hierarchy.
227 // By default, it returns all the cgroups under the given hierarchy.
228 // This function assumes that the given hierarchy and cgroup are
229 // valid. We use a post-order walk here to ease the removal of
230 // cgroups.
231 // @param hierarchy Path to the hierarchy root.
232 // @return A vector of cgroup names.
234  const std::string& hierarchy,
235  const std::string& cgroup = "/");
236 
237 
238 // Send the specified signal to all process in a cgroup. This function
239 // assumes that the given hierarchy and cgroup are valid.
240 // @param hierarchy Path to the hierarchy root.
241 // @param cgroup Path to the cgroup relative to the hierarchy root.
242 // @param signal The signal to send to all tasks within the cgroup.
243 // @return Some on success.
244 // Error if something unexpected happens.
246  const std::string& hierarchy,
247  const std::string& cgroup,
248  int signal);
249 
250 
251 // Read a control file. Control files are the gateway to monitor and
252 // control cgroups. This function assumes the cgroups virtual file
253 // systems are properly mounted on the given hierarchy, and the given
254 // cgroup has been already created properly. The given control file
255 // name should also be valid.
256 // @param hierarchy Path to the hierarchy root.
257 // @param cgroup Path to the cgroup relative to the hierarchy root.
258 // @param control Name of the control file.
259 // @return The value read from the control file.
261  const std::string& hierarchy,
262  const std::string& cgroup,
263  const std::string& control);
264 
265 
266 // Write a control file. This function assumes the cgroups virtual
267 // file systems are properly mounted on the given hierarchy, and the
268 // given cgroup has been already created properly. The given control
269 // file name should also be valid.
270 // @param hierarchy Path to the hierarchy root.
271 // @param cgroup Path to the cgroup relative to the hierarchy root.
272 // @param control Name of the control file.
273 // @param value Value to be written.
274 // @return Some if the operation succeeds.
275 // Error if the operation fails.
277  const std::string& hierarchy,
278  const std::string& cgroup,
279  const std::string& control,
280  const std::string& value);
281 
282 
283 // Check whether a control file is valid under a given cgroup and a
284 // given hierarchy. This function will return error if the given
285 // hierarchy is not properly mounted with appropriate subsystems, or
286 // the given cgroup does not exist, or the control file does not
287 // exist.
288 // @param hierarchy Path to the hierarchy root.
289 // @param cgroup Path to the cgroup relative to the hierarchy root.
290 // @param control Name of the control file.
291 // @return True if the check succeeds.
292 // False if the check fails.
293 bool exists(
294  const std::string& hierarchy,
295  const std::string& cgroup,
296  const std::string& control);
297 
298 
299 // Return the set of process IDs in a given cgroup under a given
300 // hierarchy. It assumes the given hierarchy and cgroup are valid.
301 // @param hierarchy Path to the hierarchy root.
302 // @param cgroup Path to the cgroup relative to the hierarchy root.
303 // @return The set of process ids.
305  const std::string& hierarchy,
306  const std::string& cgroup);
307 
308 
309 // Return the set of thread IDs in a given cgroup under a given
310 // hierarchy. It assumes the given hierarchy and cgroup are valid.
311 // @param hierarchy Path to the hierarchy root.
312 // @param cgroup Path to the cgroup relative to the hierarchy root.
313 // @return The set of thread ids.
315  const std::string& hierarchy,
316  const std::string& cgroup);
317 
318 
319 // Assign a given process specified by its pid to a given cgroup. All
320 // threads in the pid's threadgroup will also be moved to the cgroup.
321 // This function assumes the given hierarchy and cgroup are valid. It
322 // will return error if the pid has no process associated with it.
323 // @param hierarchy Path to the hierarchy root.
324 // @param cgroup Path to the cgroup relative to the hierarchy root.
325 // @param pid The pid of the given process.
326 // @return Some if the operation succeeds.
327 // Error if the operation fails.
329  const std::string& hierarchy,
330  const std::string& cgroup,
331  pid_t pid);
332 
333 
334 // Isolate a given process specified by its 'pid' to a given cgroup by
335 // both creating the cgroup (recursively) if it doesn't exist and then
336 // assigning the process to that cgroup. It assumes the hierarchy is
337 // valid.
338 // @param hierarchy Path to the hierarchy root.
339 // @param cgroup Path to the cgroup relative to the hierarchy root.
340 // @param pid The pid of the given process.
341 // @return Nothing if the operation succeeds.
342 // Error if the operation fails.
344  const std::string& hierarchy,
345  const std::string& cgroup,
346  pid_t pid);
347 
348 
349 namespace event {
350 
351 // Listen on an event notifier and return a future which will become
352 // ready when the certain event happens. This function assumes the
353 // given hierarchy, cgroup and control file are valid.
354 // @param hierarchy Path to the hierarchy root.
355 // @param cgroup Path to the cgroup relative to the hierarchy root.
356 // @param control Name of the control file.
357 // @param args Control specific arguments.
358 // @return A future which contains the value read from the file when ready.
359 // Error if something unexpected happens.
361  const std::string& hierarchy,
362  const std::string& cgroup,
363  const std::string& control,
365 
366 } // namespace event {
367 
368 
369 // Destroy a cgroup under a given hierarchy. It will also recursively
370 // destroy any sub-cgroups. If the freezer subsystem is attached to
371 // the hierarchy, we attempt to kill all tasks in a given cgroup,
372 // before removing it. Otherwise, we just attempt to remove the
373 // cgroup. This function assumes the given hierarchy and cgroup are
374 // valid. It returns error if we failed to destroy any of the cgroups.
375 // NOTE: If cgroup is "/" (default), all cgroups under the
376 // hierarchy are destroyed.
377 // TODO(vinod): Add support for killing tasks when freezer subsystem
378 // is not present.
379 // @param hierarchy Path to the hierarchy root.
380 // @param cgroup Path to the cgroup relative to the hierarchy root.
381 // @return A future which will become ready when the operation is done.
382 // Error if something unexpected happens.
384  const std::string& hierarchy,
385  const std::string& cgroup = "/");
386 
387 
388 // Destroy a cgroup under a given hierarchy. This is a convenience
389 // function which wraps the cgroups::destroy() to add a timeout: if
390 // the cgroup(s) cannot be destroyed after timeout the operation will
391 // be discarded.
393  const std::string& hierarchy,
394  const std::string& cgroup,
395  const Duration& timeout);
396 
397 
398 // Cleanup the hierarchy, by first destroying all the underlying
399 // cgroups, unmounting the hierarchy and deleting the mount point.
400 // @param hierarchy Path to the hierarchy root.
401 // @return A future which will become ready when the operation is done.
402 // Error if something unexpected happens.
403 process::Future<bool> cleanup(const std::string& hierarchy);
404 
405 
406 // Returns the stat information from the given file. This function
407 // assumes the given hierarchy and cgroup are valid.
408 // @param hierarchy Path to the hierarchy root.
409 // @param cgroup Path to the cgroup relative to the hierarchy root.
410 // @param file The stat file to read from. (Ex: "memory.stat").
411 // @return The stat information parsed from the file.
412 // Error if reading or parsing fails.
413 // TODO(bmahler): Consider namespacing stat for each subsystem (e.g.
414 // cgroups::memory::stat and cgroups::cpuacct::stat).
416  const std::string& hierarchy,
417  const std::string& cgroup,
418  const std::string& file);
419 
420 
421 // Blkio subsystem.
422 namespace blkio {
423 
424 // Returns the cgroup that the specified pid is a member of within the
425 // hierarchy that the 'blkio' subsystem is mounted, or None if the subsystem
426 // is not mounted or the pid is not a member of a cgroup.
428 
429 
430 // Wrapper class for dev_t.
431 class Device
432 {
433 public:
434  constexpr Device(dev_t device) : value(device) {}
435  unsigned int getMajor() const;
436  unsigned int getMinor() const;
437 
438  inline bool operator==(const Device& that) const
439  {
440  return value == that.value;
441  }
442 
443  inline bool operator!=(const Device& that) const
444  {
445  return value != that.value;
446  }
447 
448  inline operator dev_t() const { return value; }
449 
450 public:
451  static Try<Device> parse(const std::string& s);
452 
453 private:
454  dev_t value;
455 };
456 
457 
458 enum class Operation {
459  TOTAL,
460  READ,
461  WRITE,
462  SYNC,
463  ASYNC,
464 };
465 
466 
467 // Entry for a blkio file. The format of each entry can either be:
468 // 1. <value>
469 // 2. <dev> <value>
470 // 3. <dev> <op> <value>
471 // 4. <op> <value>
472 //
473 // For details:
474 // https://www.kernel.org/doc/Documentation/cgroup-v1/blkio-controller.txt
475 struct Value
476 {
479  uint64_t value;
480 
481  static Try<Value> parse(const std::string& s);
482 };
483 
484 
485 namespace cfq {
486 
488  const std::string& hierarchy,
489  const std::string& cgroup);
490 
491 
493  const std::string& hierarchy,
494  const std::string& cgroup);
495 
496 
498  const std::string& hierarchy,
499  const std::string& cgroup);
500 
501 
503  const std::string& hierarchy,
504  const std::string& cgroup);
505 
506 
507 // Returns the total number of bios/requests merged into requests
508 // belonging to the given cgroup from blkio.io_merged. This function
509 // assumes the given hierarchy and cgroup are valid.
511  const std::string& hierarchy,
512  const std::string& cgroup);
513 
514 
515 // Returns the total number of bios/requests merged into requests
516 // belonging to the given cgroup and all its descendants from
517 // blkio.io_merged_recursive. This function assumes the given
518 // hierarchy and cgroup are valid.
520  const std::string& hierarchy,
521  const std::string& cgroup);
522 
523 
524 // Returns the total number of requests queued up in the given
525 // cgroup from blkio.io_queued. This function assumes the given
526 // hierarchy and cgroup are valid.
528  const std::string& hierarchy,
529  const std::string& cgroup);
530 
531 
532 // Returns the total number of requests queued up in the given
533 // cgroup and all its descendants from blkio.io_queued_recursive.
534 // This function assumes the given hierarchy and cgroup are valid.
536  const std::string& hierarchy,
537  const std::string& cgroup);
538 
539 
540 // Returns the number of bytes transferred to/from the disk by the
541 // given cgroup from blkio.io_service_bytes. This function assumes the
542 // given hierarchy and cgroup are valid.
544  const std::string& hierarchy,
545  const std::string& cgroup);
546 
547 
548 // Returns the number of bytes transferred to/from the disk by the
549 // given cgroup and all its descendants from
550 // blkio.io_service_bytes_recursive. This function assumes the given
551 // hierarchy and cgroup are valid.
553  const std::string& hierarchy,
554  const std::string& cgroup);
555 
556 
557 // Returns the total amount of time between request dispatch and
558 // completion by the IOs done by the given cgroup from
559 // blkio.io_service_time. This function assumes the given hierarchy
560 // and cgroup are valid.
562  const std::string& hierarchy,
563  const std::string& cgroup);
564 
565 
566 // Returns the total amount of time between request dispatch and
567 // completion by the IOs done by the given cgroup and all its
568 // descendants from blkio.io_service_time_recursive. This function
569 // assumes the given hierarchy and cgroup are valid.
571  const std::string& hierarchy,
572  const std::string& cgroup);
573 
574 
575 // Returns the number of IOs (bio) issued to the disk by the given
576 // cgroup from blkio.io_serviced. This function assumes the given
577 // hierarchy and cgroup are valid.
579  const std::string& hierarchy,
580  const std::string& cgroup);
581 
582 
583 // Returns the number of IOs (bio) issued to the disk by the given
584 // cgroup and all its descendants from blkio.io_serviced_recursive.
585 // This function assumes the given hierarchy and cgroup are valid.
587  const std::string& hierarchy,
588  const std::string& cgroup);
589 
590 
591 // Returns the total amount of time the IOs for the given cgroup spent
592 // waiting in the schedule queues for service from blkio.io_wait_time.
593 // This function assumes the given hierarchy and cgroup are valid.
595  const std::string& hierarchy,
596  const std::string& cgroup);
597 
598 
599 // Returns the total amount of time the IOs for the given cgroup and
600 // all its descendants spent waiting in the scheduler queues for
601 // service from blkio.io_wait_time_recursive. This function assumes
602 // the given hierarchy and cgroup are valid.
604  const std::string& hierarchy,
605  const std::string& cgroup);
606 
607 } // namespace cfq {
608 
609 
610 namespace throttle {
611 
612 // Returns the numbers of bytes transferred to/from the disk for the
613 // given cgroup from blkio.throttle.io_service_bytes. This function
614 // assumes the given hierarchy and cgroup are valid.
616  const std::string& hierarchy,
617  const std::string& cgroup);
618 
619 
620 // Returns the numbers of IOs (bio) issued to the disk for the given
621 // cgroup from blkio.throttle.io_serviced. This function assumes the
622 // given hierarchy and cgroup are valid.
624  const std::string& hierarchy,
625  const std::string& cgroup);
626 
627 } // namespace throttle {
628 
629 
630 inline std::ostream& operator<<(std::ostream& stream, const Device& device)
631 {
632  return stream << device.getMajor() << ':' << device.getMinor();
633 }
634 
635 
636 inline std::ostream& operator<<(std::ostream& stream, const Operation op)
637 {
638  switch (op) {
639  case Operation::TOTAL:
640  return stream << "Total";
641  case Operation::READ:
642  return stream << "Read";
643  case Operation::WRITE:
644  return stream << "Write";
645  case Operation::SYNC:
646  return stream << "Sync";
647  case Operation::ASYNC:
648  return stream << "Async";
649  }
650 
651  UNREACHABLE();
652 }
653 
654 
655 inline std::ostream& operator<<(std::ostream& stream, const Value& value)
656 {
657  if (value.device.isSome()) {
658  stream << value.device.get() << ' ';
659  }
660 
661  if (value.op.isSome()) {
662  stream << value.op.get() << ' ';
663  }
664 
665  return stream << value.value;
666 }
667 
668 } // namespace blkio {
669 
670 
671 // Cpu controls.
672 namespace cpu {
673 
674 // Returns the cgroup that the specified pid is a member of within the
675 // hierarchy that the 'cpu' subsystem is mounted or None if the
676 // subsystem is not mounted or the pid is not a member of a cgroup.
678 
679 
680 // Sets the cpu shares using cpu.shares. This function assumes the
681 // given hierarchy and cgroup are valid.
683  const std::string& hierarchy,
684  const std::string& cgroup,
685  uint64_t shares);
686 
687 
688 // Returns the cpu shares from cpu.shares. This function assumes the
689 // given hierarchy and cgroup are valid.
691  const std::string& hierarchy,
692  const std::string& cgroup);
693 
694 
695 // Sets the cfs period using cpu.cfs_period_us. This function assumes
696 // the given hierarchy and cgroup are valid.
698  const std::string& hierarchy,
699  const std::string& cgroup,
700  const Duration& duration);
701 
702 
703 // Returns the cfs quota from cpu.cfs_quota_us. This function assumes
704 // the given hierarchy and cgroup are valid.
706  const std::string& hierarchy,
707  const std::string& cgroup);
708 
709 
710 // Sets the cfs quota using cpu.cfs_quota_us. This function assumes
711 // the given hierarchy and cgroup are valid.
713  const std::string& hierarchy,
714  const std::string& cgroup,
715  const Duration& duration);
716 
717 } // namespace cpu {
718 
719 
720 // Cpuacct subsystem.
721 namespace cpuacct {
722 
723 // Returns the cgroup that the specified pid is a member of within the
724 // hierarchy that the 'cpuacct' subsytem is mounted or None if the
725 // subsystem is not mounted or the pid is not a member of a cgroup.
726 //
727 // @param pid process id for which cgroup is queried within the cpuacct
728 // subsytem.
729 // @return Some cgroup in case there was a valid cgroup found for the pid.
730 // Error if there was any error in processing.
732 
733 
734 // Encapsulates the 'stat' information exposed by the cpuacct subsystem.
735 struct Stats
736 {
737  const Duration user;
739 };
740 
741 
742 // Returns 'Stats' for a given hierarchy and cgroup. This function
743 // assumes the given hierarchy and cgroup are valid.
744 //
745 // @param hierarchy hierarchy for the 'cpuacct' subsystem.
746 // @param cgroup cgroup for a given process.
747 // @return Some<Stats> if successful.
748 // Error in case of any error during processing.
750  const std::string& hierarchy,
751  const std::string& cgroup);
752 
753 } // namespace cpuacct {
754 
755 
756 // Memory controls.
757 namespace memory {
758 
759 // Returns the cgroup that the specified pid is a member of within the
760 // hierarchy that the 'memory' subsytem is mounted or None if the
761 // subsystem is not mounted or the pid is not a member of a cgroup.
763 
764 
765 // Returns the memory limit from memory.limit_in_bytes. This function
766 // assumes the given hierarchy and cgroup are valid.
768  const std::string& hierarchy,
769  const std::string& cgroup);
770 
771 
772 // Sets the memory limit using memory.limit_in_bytes. This function
773 // assumes the given hierarchy and cgroup are valid.
775  const std::string& hierarchy,
776  const std::string& cgroup,
777  const Bytes& limit);
778 
779 
780 // Returns the memory limit from memory.memsw.limit_in_bytes. Returns
781 // none if memory.memsw.limit_in_bytes is not supported (e.g., when
782 // swap is turned off). This function assumes the given hierarchy and
783 // cgroup are valid.
785  const std::string& hierarchy,
786  const std::string& cgroup);
787 
788 
789 // Sets the memory limit using memory.memsw.limit_in_bytes. Returns
790 // false if memory.memsw.limit_in_bytes is not supported (e.g., when
791 // swap is turned off). This function assumes the given hierarchy and
792 // cgroup are valid.
794  const std::string& hierarchy,
795  const std::string& cgroup,
796  const Bytes& limit);
797 
798 
799 // Returns the soft memory limit from memory.soft_limit_in_bytes. This
800 // function assumes the given hierarchy and cgroup are valid.
802  const std::string& hierarchy,
803  const std::string& cgroup);
804 
805 
806 // Sets the soft memory limit using memory.soft_limit_in_bytes. This
807 // function assumes the given hierarchy and cgroup are valid.
809  const std::string& hierarchy,
810  const std::string& cgroup,
811  const Bytes& limit);
812 
813 
814 // Returns the memory usage from memory.usage_in_bytes. This function
815 // assumes the given hierarchy and cgroup are valid.
817  const std::string& hierarchy,
818  const std::string& cgroup);
819 
820 
821 // Returns the memory + swap usage from memory.memsw.usage_in_bytes.
822 // This function assumes the given hierarchy and cgroup are valid.
824  const std::string& hierarchy,
825  const std::string& cgroup);
826 
827 
828 // Returns the max memory usage from memory.max_usage_in_bytes. This
829 // function assumes the given hierarchy and cgroup are valid.
831  const std::string& hierarchy,
832  const std::string& cgroup);
833 
834 
835 // Out-of-memory (OOM) controls.
836 namespace oom {
837 
838 // Listen for an OOM event for the cgroup. This function assumes the
839 // given hierarchy and cgroup are valid.
841  const std::string& hierarchy,
842  const std::string& cgroup);
843 
844 // OOM killer controls.
845 namespace killer {
846 
847 // Return whether the kernel OOM killer is enabled for the cgroup.
848 // This function assumes the given hierarchy and cgroup are valid.
850  const std::string& hierarchy,
851  const std::string& cgroup);
852 
853 // Enable the kernel OOM killer for the cgroup. The control file will
854 // only be written to if necessary. This function assumes the given
855 // hierarchy and cgroup are valid.
857  const std::string& hierarchy,
858  const std::string& cgroup);
859 
860 // Disable the kernel OOM killer. The control file will only be
861 // written to if necessary. This function assumes the given hierarchy
862 // and cgroup are valid.
864  const std::string& hierarchy,
865  const std::string& cgroup);
866 
867 } // namespace killer {
868 
869 } // namespace oom {
870 
871 
872 // Memory pressure counters.
873 namespace pressure {
874 
875 enum Level
876 {
880 };
881 
882 
883 std::ostream& operator<<(std::ostream& stream, Level level);
884 
885 
886 // Forward declaration.
887 class CounterProcess;
888 
889 
890 // Counter is a primitive to listen on events of a given memory
891 // pressure level for a cgroup and keep track of the number of
892 // occurrence of that event. Use the public 'create' function to
893 // create a new counter; see 'value' for how to use.
894 class Counter
895 {
896 public:
897  // Create a memory pressure counter for the given cgroup on the
898  // specified level. This function assumes the given hierarchy and
899  // cgroup are valid.
901  const std::string& hierarchy,
902  const std::string& cgroup,
903  Level level);
904 
905  virtual ~Counter();
906 
907  // Returns the current accumulated number of occurrences of the
908  // pressure event. Returns a failure if any error occurs while
909  // monitoring the pressure events, and any subsequent calls to
910  // 'value' will return the same failure. In such case, the user
911  // should consider creating a new Counter.
912  process::Future<uint64_t> value() const;
913 
914 private:
915  Counter(const std::string& hierarchy,
916  const std::string& cgroup,
917  Level level);
918 
920 };
921 
922 } // namespace pressure {
923 
924 } // namespace memory {
925 
926 
927 // Device controls.
928 namespace devices {
929 
930 struct Entry
931 {
932  static Try<Entry> parse(const std::string& s);
933 
934  struct Selector
935  {
936  enum class Type
937  {
938  ALL,
939  BLOCK,
940  CHARACTER,
941  };
942 
944  Option<unsigned int> major; // Matches all `major` numbers if None.
945  Option<unsigned int> minor; // Matches all `minor` numbers if None.
946  };
947 
948  struct Access
949  {
950  bool read;
951  bool write;
952  bool mknod;
953  };
954 
957 };
958 
959 std::ostream& operator<<(
960  std::ostream& stream,
961  const Entry::Selector::Type& type);
962 
963 std::ostream& operator<<(
964  std::ostream& stream,
965  const Entry::Selector& selector);
966 
967 std::ostream& operator<<(
968  std::ostream& stream,
969  const Entry::Access& access);
970 
971 std::ostream& operator<<(
972  std::ostream& stream,
973  const Entry& entry);
974 
975 
976 bool operator==(
977  const Entry::Selector& left,
978  const Entry::Selector& right);
979 
980 bool operator==(
981  const Entry::Access& left,
982  const Entry::Access& right);
983 
984 bool operator==(
985  const Entry& left,
986  const Entry& right);
987 
988 
989 // Returns the entries within devices.list. This function assumes the
990 // given hierarchy and cgroup are valid.
992  const std::string& hierarchy,
993  const std::string& cgroup);
994 
995 // Writes the provided `entry` into devices.allow. This function
996 // assumes the given hierarchy and cgroup are valid.
998  const std::string& hierarchy,
999  const std::string& cgroup,
1000  const Entry& entry);
1001 
1002 // Writes the provided `entry` into devices.deny. This function
1003 // assumes the given hierarchy and cgroup are valid.
1005  const std::string& hierarchy,
1006  const std::string& cgroup,
1007  const Entry& entry);
1008 
1009 } // namespace devices {
1010 
1011 
1012 // Freezer controls.
1013 // The freezer can be in one of three states:
1014 // 1. THAWED : No process in the cgroup is frozen.
1015 // 2. FREEZING : Freezing is in progress but not all processes are frozen.
1016 // 3. FROZEN : All processes are frozen.
1017 namespace freezer {
1018 
1019 // Freeze all processes in the given cgroup. This function will return
1020 // a future which will become ready when all processes have been
1021 // frozen (cgroup is in the FROZEN state). This function assumes the
1022 // given hierarchy and cgroup are valid.
1024  const std::string& hierarchy,
1025  const std::string& cgroup);
1026 
1027 
1028 // Thaw all processes in the given cgroup. This is a revert operation
1029 // of freezer::freeze. This function will return a future which will
1030 // become ready when all processes have been thawed (cgroup is in the
1031 // THAWED state). This function assumes the given hierarchy and cgroup
1032 // are valid.
1034  const std::string& hierarchy,
1035  const std::string& cgroup);
1036 
1037 } // namespace freezer {
1038 
1039 
1040 // Net_cls subsystem.
1041 namespace net_cls {
1042 
1043 // Read the uint32_t handle set in `net_cls.classid`. This function
1044 // assumes the given hierarchy and cgroup are valid.
1046  const std::string& hierarchy,
1047  const std::string& cgroup);
1048 
1049 
1050 // Write the uint32_t handle to the `net_cls.classid`. This function
1051 // assumes the given hierarchy and cgroup are valid.
1053  const std::string& hierarchy,
1054  const std::string& cgroup,
1055  const uint32_t handle);
1056 
1057 } // namespace net_cls {
1058 
1059 
1060 // Named hierarchy.
1061 namespace named {
1062 
1063 // Returns the cgroup that the specified pid is a member of within the
1064 // given named hierarchy is mounted or None if the named hierarchy is
1065 // not mounted or the pid is not a member of a cgroup.
1066 Result<std::string> cgroup(const std::string& hierarchyName, pid_t pid);
1067 
1068 } // namespace named {
1069 
1070 
1071 } // namespace cgroups {
1072 
1073 namespace std {
1074 
1075 template <>
1077 {
1078  typedef size_t result_type;
1079 
1081 
1082  result_type operator()(const argument_type& level) const
1083  {
1084  // Use the underlying type of the enum as hash value.
1085  return static_cast<size_t>(level);
1086  }
1087 };
1088 
1089 } // namespace std {
1090 
1091 #endif // __CGROUPS_HPP__
const short READ
A possible event while polling.
Definition: io.hpp:35
Try< Nothing > isolate(const std::string &hierarchy, const std::string &cgroup, pid_t pid)
Try< std::vector< Value > > sectors(const std::string &hierarchy, const std::string &cgroup)
std::ostream & operator<<(std::ostream &stream, const Entry &entry)
bool mknod
Definition: cgroups.hpp:952
Try< Nothing > enable(const std::string &hierarchy, const std::string &cgroup)
Try< bool > memsw_limit_in_bytes(const std::string &hierarchy, const std::string &cgroup, const Bytes &limit)
Definition: cgroups.hpp:930
Option< unsigned int > minor
Definition: cgroups.hpp:945
Try< std::vector< Value > > io_serviced(const std::string &hierarchy, const std::string &cgroup)
Definition: check.hpp:33
Try< bool > busy(const std::string &subsystems)
Try< std::vector< Value > > io_wait_time(const std::string &hierarchy, const std::string &cgroup)
Definition: cgroups.hpp:934
const int ALL
Definition: diagnosis.hpp:52
Option< Operation > op
Definition: cgroups.hpp:478
Try< Bytes > max_usage_in_bytes(const std::string &hierarchy, const std::string &cgroup)
process::Future< bool > cleanup(const std::string &hierarchy)
Try< std::vector< Value > > io_queued_recursive(const std::string &hierarchy, const std::string &cgroup)
Try< Bytes > memsw_usage_in_bytes(const std::string &hierarchy, const std::string &cgroup)
Try< std::vector< Value > > time_recursive(const std::string &hierarchy, const std::string &cgroup)
Definition: cgroups.hpp:39
Definition: type_utils.hpp:510
bool write
Definition: cgroups.hpp:951
result_type operator()(const argument_type &level) const
Definition: cgroups.hpp:1082
Operation
Definition: cgroups.hpp:458
uint64_t value
Definition: cgroups.hpp:479
cgroups::memory::pressure::Level argument_type
Definition: cgroups.hpp:1080
const Duration system
Definition: cgroups.hpp:738
const unsigned int THREAD_ASSIGN_RETRIES
Definition: cgroups.hpp:48
unsigned int getMinor() const
Definition: duration.hpp:32
Definition: check.hpp:30
Definition: cgroups.hpp:879
process::Future< uint64_t > listen(const std::string &hierarchy, const std::string &cgroup, const std::string &control, const Option< std::string > &args=Option< std::string >::none())
Try< bool > access(const std::string &path, int how)
Definition: access.hpp:28
bool isSome() const
Definition: option.hpp:115
Try< std::vector< Value > > io_queued(const std::string &hierarchy, const std::string &cgroup)
Definition: cgroups.hpp:948
Try< std::vector< Value > > sectors_recursive(const std::string &hierarchy, const std::string &cgroup)
Try< std::vector< Value > > io_service_bytes(const std::string &hierarchy, const std::string &cgroup)
DWORD pid_t
Definition: windows.hpp:181
Definition: cgroups.hpp:877
Definition: cgroups.hpp:878
Try< std::vector< Value > > io_service_time(const std::string &hierarchy, const std::string &cgroup)
URI file(const std::string &path)
Creates a file URI with the given path on the local host.
Definition: file.hpp:33
Type
Definition: cgroups.hpp:936
Definition: cgroups.hpp:431
Try< Nothing > unmount(const std::string &hierarchy)
Try< Nothing > disable(const std::string &hierarchy, const std::string &cgroup)
Definition: duration.hpp:207
Try< Nothing > verify(const std::string &hierarchy, const std::string &cgroup="", const std::string &control="")
const short WRITE
A possible event while polling.
Definition: io.hpp:40
Try< Nothing > cfs_period_us(const std::string &hierarchy, const std::string &cgroup, const Duration &duration)
Selector selector
Definition: cgroups.hpp:955
Try< std::vector< Value > > io_service_bytes_recursive(const std::string &hierarchy, const std::string &cgroup)
Try< Nothing > limit_in_bytes(const std::string &hierarchy, const std::string &cgroup, const Bytes &limit)
Result< std::string > cgroup(const std::string &hierarchyName, pid_t pid)
Try< ImageManifest > parse(const std::string &value)
Definition: parse.hpp:36
const Duration FREEZE_RETRY_INTERVAL
Definition: cgroups.hpp:44
const T & get() const &
Definition: option.hpp:118
process::Future< Nothing > destroy(const std::string &hierarchy, const std::string &cgroup="/")
Definition: cgroups.hpp:475
Try< hashmap< std::string, uint64_t > > stat(const std::string &hierarchy, const std::string &cgroup, const std::string &file)
Try< std::vector< Value > > io_merged(const std::string &hierarchy, const std::string &cgroup)
Try< std::vector< Value > > io_wait_time_recursive(const std::string &hierarchy, const std::string &cgroup)
#define UNREACHABLE()
Definition: unreachable.hpp:22
Try< std::vector< Entry > > list(const std::string &hierarchy, const std::string &cgroup)
Try< bool > mounted(const std::string &hierarchy, const std::string &subsystems="")
Option< unsigned int > major
Definition: cgroups.hpp:944
Try< Nothing > cfs_quota_us(const std::string &hierarchy, const std::string &cgroup, const Duration &duration)
Result< Process > process(pid_t pid)
Definition: freebsd.hpp:30
Try< std::vector< Value > > io_serviced_recursive(const std::string &hierarchy, const std::string &cgroup)
bool operator==(const Path &left, const Path &right)
Definition: path.hpp:331
constexpr Device(dev_t device)
Definition: cgroups.hpp:434
Try< Nothing > mount(const std::string &hierarchy, const std::string &subsystems, int retry=0)
bool read
Definition: cgroups.hpp:950
bool operator!=(const Device &that) const
Definition: cgroups.hpp:443
Access access
Definition: cgroups.hpp:956
Try< std::set< pid_t > > processes(const std::string &hierarchy, const std::string &cgroup)
Try< Bytes > usage_in_bytes(const std::string &hierarchy, const std::string &cgroup)
Definition: cgroups.hpp:894
Try< Nothing > classid(const std::string &hierarchy, const std::string &cgroup, const uint32_t handle)
process::Future< Nothing > freeze(const std::string &hierarchy, const std::string &cgroup)
Try< uint32_t > type(const std::string &path)
Try< Nothing > allow(const std::string &hierarchy, const std::string &cgroup, const Entry &entry)
Level
Definition: cgroups.hpp:875
Try< std::vector< Value > > io_merged_recursive(const std::string &hierarchy, const std::string &cgroup)
Option< Device > device
Definition: cgroups.hpp:477
Try< std::set< std::string > > hierarchies()
Definition: cgroups.hpp:735
bool enabled()
Try< std::string > prepare(const std::string &baseHierarchy, const std::string &subsystem, const std::string &cgroup)
Try< Nothing > create(const std::string &hierarchy, const std::string &cgroup, bool recursive=false)
Try< Nothing > kill(const std::string &hierarchy, const std::string &cgroup, int signal)
Definition: bytes.hpp:30
size_t result_type
Definition: cgroups.hpp:1078
Result< std::string > hierarchy(const std::string &subsystems)
Try< Memory > memory()
Definition: freebsd.hpp:78
const Duration user
Definition: cgroups.hpp:737
bool exists(const std::string &hierarchy, const std::string &cgroup)
Try< Nothing > assign(const std::string &hierarchy, const std::string &cgroup, pid_t pid)
Type type
Definition: cgroups.hpp:943
Try< Nothing > write(const std::string &hierarchy, const std::string &cgroup, const std::string &control, const std::string &value)
Try< std::set< pid_t > > threads(const std::string &hierarchy, const std::string &cgroup)
Try< Nothing > deny(const std::string &hierarchy, const std::string &cgroup, const Entry &entry)
Try< std::vector< Value > > io_service_time_recursive(const std::string &hierarchy, const std::string &cgroup)
Try< Nothing > soft_limit_in_bytes(const std::string &hierarchy, const std::string &cgroup, const Bytes &limit)
Try< std::vector< Value > > time(const std::string &hierarchy, const std::string &cgroup)
Try< std::set< std::string > > subsystems()
Try< std::string > read(const std::string &hierarchy, const std::string &cgroup, const std::string &control)
bool operator==(const Device &that) const
Definition: cgroups.hpp:438
unsigned int getMajor() const
Try< uint64_t > shares(const std::string &hierarchy, const std::string &cgroup)
Definition: future.hpp:58
process::Future< Nothing > thaw(const std::string &hierarchy, const std::string &cgroup)