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  DISCARD,
465 };
466 
467 
468 // Entry for a blkio file. The format of each entry can either be:
469 // 1. <value>
470 // 2. <dev> <value>
471 // 3. <dev> <op> <value>
472 // 4. <op> <value>
473 //
474 // For details:
475 // https://www.kernel.org/doc/Documentation/cgroup-v1/blkio-controller.txt
476 struct Value
477 {
480  uint64_t value;
481 
482  static Try<Value> parse(const std::string& s);
483 };
484 
485 
486 namespace cfq {
487 
489  const std::string& hierarchy,
490  const std::string& cgroup);
491 
492 
494  const std::string& hierarchy,
495  const std::string& cgroup);
496 
497 
499  const std::string& hierarchy,
500  const std::string& cgroup);
501 
502 
504  const std::string& hierarchy,
505  const std::string& cgroup);
506 
507 
508 // Returns the total number of bios/requests merged into requests
509 // belonging to the given cgroup from blkio.io_merged. This function
510 // assumes the given hierarchy and cgroup are valid.
512  const std::string& hierarchy,
513  const std::string& cgroup);
514 
515 
516 // Returns the total number of bios/requests merged into requests
517 // belonging to the given cgroup and all its descendants from
518 // blkio.io_merged_recursive. This function assumes the given
519 // hierarchy and cgroup are valid.
521  const std::string& hierarchy,
522  const std::string& cgroup);
523 
524 
525 // Returns the total number of requests queued up in the given
526 // cgroup from blkio.io_queued. This function assumes the given
527 // hierarchy and cgroup are valid.
529  const std::string& hierarchy,
530  const std::string& cgroup);
531 
532 
533 // Returns the total number of requests queued up in the given
534 // cgroup and all its descendants from blkio.io_queued_recursive.
535 // This function assumes the given hierarchy and cgroup are valid.
537  const std::string& hierarchy,
538  const std::string& cgroup);
539 
540 
541 // Returns the number of bytes transferred to/from the disk by the
542 // given cgroup from blkio.io_service_bytes. This function assumes the
543 // given hierarchy and cgroup are valid.
545  const std::string& hierarchy,
546  const std::string& cgroup);
547 
548 
549 // Returns the number of bytes transferred to/from the disk by the
550 // given cgroup and all its descendants from
551 // blkio.io_service_bytes_recursive. This function assumes the given
552 // hierarchy and cgroup are valid.
554  const std::string& hierarchy,
555  const std::string& cgroup);
556 
557 
558 // Returns the total amount of time between request dispatch and
559 // completion by the IOs done by the given cgroup from
560 // blkio.io_service_time. This function assumes the given hierarchy
561 // and cgroup are valid.
563  const std::string& hierarchy,
564  const std::string& cgroup);
565 
566 
567 // Returns the total amount of time between request dispatch and
568 // completion by the IOs done by the given cgroup and all its
569 // descendants from blkio.io_service_time_recursive. This function
570 // assumes the given hierarchy and cgroup are valid.
572  const std::string& hierarchy,
573  const std::string& cgroup);
574 
575 
576 // Returns the number of IOs (bio) issued to the disk by the given
577 // cgroup from blkio.io_serviced. This function assumes the given
578 // hierarchy and cgroup are valid.
580  const std::string& hierarchy,
581  const std::string& cgroup);
582 
583 
584 // Returns the number of IOs (bio) issued to the disk by the given
585 // cgroup and all its descendants from blkio.io_serviced_recursive.
586 // This function assumes the given hierarchy and cgroup are valid.
588  const std::string& hierarchy,
589  const std::string& cgroup);
590 
591 
592 // Returns the total amount of time the IOs for the given cgroup spent
593 // waiting in the schedule queues for service from blkio.io_wait_time.
594 // This function assumes the given hierarchy and cgroup are valid.
596  const std::string& hierarchy,
597  const std::string& cgroup);
598 
599 
600 // Returns the total amount of time the IOs for the given cgroup and
601 // all its descendants spent waiting in the scheduler queues for
602 // service from blkio.io_wait_time_recursive. This function assumes
603 // the given hierarchy and cgroup are valid.
605  const std::string& hierarchy,
606  const std::string& cgroup);
607 
608 } // namespace cfq {
609 
610 
611 namespace throttle {
612 
613 // Returns the numbers of bytes transferred to/from the disk for the
614 // given cgroup from blkio.throttle.io_service_bytes. This function
615 // assumes the given hierarchy and cgroup are valid.
617  const std::string& hierarchy,
618  const std::string& cgroup);
619 
620 
621 // Returns the numbers of IOs (bio) issued to the disk for the given
622 // cgroup from blkio.throttle.io_serviced. This function assumes the
623 // given hierarchy and cgroup are valid.
625  const std::string& hierarchy,
626  const std::string& cgroup);
627 
628 } // namespace throttle {
629 
630 
631 inline std::ostream& operator<<(std::ostream& stream, const Device& device)
632 {
633  return stream << device.getMajor() << ':' << device.getMinor();
634 }
635 
636 
637 inline std::ostream& operator<<(std::ostream& stream, const Operation op)
638 {
639  switch (op) {
640  case Operation::TOTAL:
641  return stream << "Total";
642  case Operation::READ:
643  return stream << "Read";
644  case Operation::WRITE:
645  return stream << "Write";
646  case Operation::SYNC:
647  return stream << "Sync";
648  case Operation::ASYNC:
649  return stream << "Async";
650  case Operation::DISCARD:
651  return stream << "Discard";
652  }
653 
654  UNREACHABLE();
655 }
656 
657 
658 inline std::ostream& operator<<(std::ostream& stream, const Value& value)
659 {
660  if (value.device.isSome()) {
661  stream << value.device.get() << ' ';
662  }
663 
664  if (value.op.isSome()) {
665  stream << value.op.get() << ' ';
666  }
667 
668  return stream << value.value;
669 }
670 
671 } // namespace blkio {
672 
673 
674 // Cpu controls.
675 namespace cpu {
676 
677 // Returns the cgroup that the specified pid is a member of within the
678 // hierarchy that the 'cpu' subsystem is mounted or None if the
679 // subsystem is not mounted or the pid is not a member of a cgroup.
681 
682 
683 // Sets the cpu shares using cpu.shares. This function assumes the
684 // given hierarchy and cgroup are valid.
686  const std::string& hierarchy,
687  const std::string& cgroup,
688  uint64_t shares);
689 
690 
691 // Returns the cpu shares from cpu.shares. This function assumes the
692 // given hierarchy and cgroup are valid.
694  const std::string& hierarchy,
695  const std::string& cgroup);
696 
697 
698 // Sets the cfs period using cpu.cfs_period_us. This function assumes
699 // the given hierarchy and cgroup are valid.
701  const std::string& hierarchy,
702  const std::string& cgroup,
703  const Duration& duration);
704 
705 
706 // Returns the cfs quota from cpu.cfs_quota_us. This function assumes
707 // the given hierarchy and cgroup are valid.
709  const std::string& hierarchy,
710  const std::string& cgroup);
711 
712 
713 // Sets the cfs quota using cpu.cfs_quota_us. This function assumes
714 // the given hierarchy and cgroup are valid.
716  const std::string& hierarchy,
717  const std::string& cgroup,
718  const Duration& duration);
719 
720 } // namespace cpu {
721 
722 
723 // Cpuacct subsystem.
724 namespace cpuacct {
725 
726 // Returns the cgroup that the specified pid is a member of within the
727 // hierarchy that the 'cpuacct' subsytem is mounted or None if the
728 // subsystem is not mounted or the pid is not a member of a cgroup.
729 //
730 // @param pid process id for which cgroup is queried within the cpuacct
731 // subsytem.
732 // @return Some cgroup in case there was a valid cgroup found for the pid.
733 // Error if there was any error in processing.
735 
736 
737 // Encapsulates the 'stat' information exposed by the cpuacct subsystem.
738 struct Stats
739 {
740  const Duration user;
742 };
743 
744 
745 // Returns 'Stats' for a given hierarchy and cgroup. This function
746 // assumes the given hierarchy and cgroup are valid.
747 //
748 // @param hierarchy hierarchy for the 'cpuacct' subsystem.
749 // @param cgroup cgroup for a given process.
750 // @return Some<Stats> if successful.
751 // Error in case of any error during processing.
753  const std::string& hierarchy,
754  const std::string& cgroup);
755 
756 } // namespace cpuacct {
757 
758 
759 // Memory controls.
760 namespace memory {
761 
762 // Returns the cgroup that the specified pid is a member of within the
763 // hierarchy that the 'memory' subsytem is mounted or None if the
764 // subsystem is not mounted or the pid is not a member of a cgroup.
766 
767 
768 // Returns the memory limit from memory.limit_in_bytes. This function
769 // assumes the given hierarchy and cgroup are valid.
771  const std::string& hierarchy,
772  const std::string& cgroup);
773 
774 
775 // Sets the memory limit using memory.limit_in_bytes. This function
776 // assumes the given hierarchy and cgroup are valid.
778  const std::string& hierarchy,
779  const std::string& cgroup,
780  const Bytes& limit);
781 
782 
783 // Returns the memory limit from memory.memsw.limit_in_bytes. Returns
784 // none if memory.memsw.limit_in_bytes is not supported (e.g., when
785 // swap is turned off). This function assumes the given hierarchy and
786 // cgroup are valid.
788  const std::string& hierarchy,
789  const std::string& cgroup);
790 
791 
792 // Sets the memory limit using memory.memsw.limit_in_bytes. Returns
793 // false if memory.memsw.limit_in_bytes is not supported (e.g., when
794 // swap is turned off). This function assumes the given hierarchy and
795 // cgroup are valid.
797  const std::string& hierarchy,
798  const std::string& cgroup,
799  const Bytes& limit);
800 
801 
802 // Returns the soft memory limit from memory.soft_limit_in_bytes. This
803 // function assumes the given hierarchy and cgroup are valid.
805  const std::string& hierarchy,
806  const std::string& cgroup);
807 
808 
809 // Sets the soft memory limit using memory.soft_limit_in_bytes. This
810 // function assumes the given hierarchy and cgroup are valid.
812  const std::string& hierarchy,
813  const std::string& cgroup,
814  const Bytes& limit);
815 
816 
817 // Returns the memory usage from memory.usage_in_bytes. This function
818 // assumes the given hierarchy and cgroup are valid.
820  const std::string& hierarchy,
821  const std::string& cgroup);
822 
823 
824 // Returns the memory + swap usage from memory.memsw.usage_in_bytes.
825 // This function assumes the given hierarchy and cgroup are valid.
827  const std::string& hierarchy,
828  const std::string& cgroup);
829 
830 
831 // Returns the max memory usage from memory.max_usage_in_bytes. This
832 // function assumes the given hierarchy and cgroup are valid.
834  const std::string& hierarchy,
835  const std::string& cgroup);
836 
837 
838 // Out-of-memory (OOM) controls.
839 namespace oom {
840 
841 // Listen for an OOM event for the cgroup. This function assumes the
842 // given hierarchy and cgroup are valid.
844  const std::string& hierarchy,
845  const std::string& cgroup);
846 
847 // OOM killer controls.
848 namespace killer {
849 
850 // Return whether the kernel OOM killer is enabled for the cgroup.
851 // This function assumes the given hierarchy and cgroup are valid.
853  const std::string& hierarchy,
854  const std::string& cgroup);
855 
856 // Enable the kernel OOM killer for the cgroup. The control file will
857 // only be written to if necessary. This function assumes the given
858 // hierarchy and cgroup are valid.
860  const std::string& hierarchy,
861  const std::string& cgroup);
862 
863 // Disable the kernel OOM killer. The control file will only be
864 // written to if necessary. This function assumes the given hierarchy
865 // and cgroup are valid.
867  const std::string& hierarchy,
868  const std::string& cgroup);
869 
870 } // namespace killer {
871 
872 } // namespace oom {
873 
874 
875 // Memory pressure counters.
876 namespace pressure {
877 
878 enum Level
879 {
883 };
884 
885 
886 std::ostream& operator<<(std::ostream& stream, Level level);
887 
888 
889 // Forward declaration.
890 class CounterProcess;
891 
892 
893 // Counter is a primitive to listen on events of a given memory
894 // pressure level for a cgroup and keep track of the number of
895 // occurrence of that event. Use the public 'create' function to
896 // create a new counter; see 'value' for how to use.
897 class Counter
898 {
899 public:
900  // Create a memory pressure counter for the given cgroup on the
901  // specified level. This function assumes the given hierarchy and
902  // cgroup are valid.
904  const std::string& hierarchy,
905  const std::string& cgroup,
906  Level level);
907 
908  virtual ~Counter();
909 
910  // Returns the current accumulated number of occurrences of the
911  // pressure event. Returns a failure if any error occurs while
912  // monitoring the pressure events, and any subsequent calls to
913  // 'value' will return the same failure. In such case, the user
914  // should consider creating a new Counter.
915  process::Future<uint64_t> value() const;
916 
917 private:
918  Counter(const std::string& hierarchy,
919  const std::string& cgroup,
920  Level level);
921 
923 };
924 
925 } // namespace pressure {
926 
927 } // namespace memory {
928 
929 
930 // Device controls.
931 namespace devices {
932 
933 struct Entry
934 {
935  static Try<Entry> parse(const std::string& s);
936 
937  struct Selector
938  {
939  enum class Type
940  {
941  ALL,
942  BLOCK,
943  CHARACTER,
944  };
945 
947  Option<unsigned int> major; // Matches all `major` numbers if None.
948  Option<unsigned int> minor; // Matches all `minor` numbers if None.
949  };
950 
951  struct Access
952  {
953  bool read;
954  bool write;
955  bool mknod;
956  };
957 
960 };
961 
962 std::ostream& operator<<(
963  std::ostream& stream,
964  const Entry::Selector::Type& type);
965 
966 std::ostream& operator<<(
967  std::ostream& stream,
968  const Entry::Selector& selector);
969 
970 std::ostream& operator<<(
971  std::ostream& stream,
972  const Entry::Access& access);
973 
974 std::ostream& operator<<(
975  std::ostream& stream,
976  const Entry& entry);
977 
978 
979 bool operator==(
980  const Entry::Selector& left,
981  const Entry::Selector& right);
982 
983 bool operator==(
984  const Entry::Access& left,
985  const Entry::Access& right);
986 
987 bool operator==(
988  const Entry& left,
989  const Entry& right);
990 
991 
992 // Returns the entries within devices.list. This function assumes the
993 // given hierarchy and cgroup are valid.
995  const std::string& hierarchy,
996  const std::string& cgroup);
997 
998 // Writes the provided `entry` into devices.allow. This function
999 // assumes the given hierarchy and cgroup are valid.
1001  const std::string& hierarchy,
1002  const std::string& cgroup,
1003  const Entry& entry);
1004 
1005 // Writes the provided `entry` into devices.deny. This function
1006 // assumes the given hierarchy and cgroup are valid.
1008  const std::string& hierarchy,
1009  const std::string& cgroup,
1010  const Entry& entry);
1011 
1012 } // namespace devices {
1013 
1014 
1015 // Freezer controls.
1016 // The freezer can be in one of three states:
1017 // 1. THAWED : No process in the cgroup is frozen.
1018 // 2. FREEZING : Freezing is in progress but not all processes are frozen.
1019 // 3. FROZEN : All processes are frozen.
1020 namespace freezer {
1021 
1022 // Freeze all processes in the given cgroup. This function will return
1023 // a future which will become ready when all processes have been
1024 // frozen (cgroup is in the FROZEN state). This function assumes the
1025 // given hierarchy and cgroup are valid.
1027  const std::string& hierarchy,
1028  const std::string& cgroup);
1029 
1030 
1031 // Thaw all processes in the given cgroup. This is a revert operation
1032 // of freezer::freeze. This function will return a future which will
1033 // become ready when all processes have been thawed (cgroup is in the
1034 // THAWED state). This function assumes the given hierarchy and cgroup
1035 // are valid.
1037  const std::string& hierarchy,
1038  const std::string& cgroup);
1039 
1040 } // namespace freezer {
1041 
1042 
1043 // Net_cls subsystem.
1044 namespace net_cls {
1045 
1046 // Read the uint32_t handle set in `net_cls.classid`. This function
1047 // assumes the given hierarchy and cgroup are valid.
1049  const std::string& hierarchy,
1050  const std::string& cgroup);
1051 
1052 
1053 // Write the uint32_t handle to the `net_cls.classid`. This function
1054 // assumes the given hierarchy and cgroup are valid.
1056  const std::string& hierarchy,
1057  const std::string& cgroup,
1058  const uint32_t handle);
1059 
1060 } // namespace net_cls {
1061 
1062 
1063 // Named hierarchy.
1064 namespace named {
1065 
1066 // Returns the cgroup that the specified pid is a member of within the
1067 // given named hierarchy is mounted or None if the named hierarchy is
1068 // not mounted or the pid is not a member of a cgroup.
1069 Result<std::string> cgroup(const std::string& hierarchyName, pid_t pid);
1070 
1071 } // namespace named {
1072 
1073 
1074 } // namespace cgroups {
1075 
1076 namespace std {
1077 
1078 template <>
1080 {
1081  typedef size_t result_type;
1082 
1084 
1085  result_type operator()(const argument_type& level) const
1086  {
1087  // Use the underlying type of the enum as hash value.
1088  return static_cast<size_t>(level);
1089  }
1090 };
1091 
1092 } // namespace std {
1093 
1094 #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:955
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:933
Option< unsigned int > minor
Definition: cgroups.hpp:948
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:937
const int ALL
Definition: diagnosis.hpp:52
Option< Operation > op
Definition: cgroups.hpp:479
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:550
bool write
Definition: cgroups.hpp:954
result_type operator()(const argument_type &level) const
Definition: cgroups.hpp:1085
Operation
Definition: cgroups.hpp:458
uint64_t value
Definition: cgroups.hpp:480
cgroups::memory::pressure::Level argument_type
Definition: cgroups.hpp:1083
const Duration system
Definition: cgroups.hpp:741
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:882
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:951
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:880
Definition: cgroups.hpp:881
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:939
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:958
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:476
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:947
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:388
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:953
bool operator!=(const Device &that) const
Definition: cgroups.hpp:443
Access access
Definition: cgroups.hpp:959
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:897
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:878
Try< std::vector< Value > > io_merged_recursive(const std::string &hierarchy, const std::string &cgroup)
Option< Device > device
Definition: cgroups.hpp:478
Try< std::set< std::string > > hierarchies()
Definition: cgroups.hpp:738
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:1081
Result< std::string > hierarchy(const std::string &subsystems)
Try< Memory > memory()
Definition: freebsd.hpp:78
const Duration user
Definition: cgroups.hpp:740
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:946
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)