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