Chapter 2. Using Control Groups
Chapter 2. Using Control Groups As explained in Chapter 3, Subsystems and Tunable Parameters , control groups and the subsystems to which they relate can be manipulated using shell commands and utilities. However, the easiest way to work with cgroups is to install the libcgroup package, which contains a number of cgroup-related command line utilities and their associated man pages. It is possible to mount hierarchies and set cgroup parameters (non-persistently) using shell commands and utilities available on any system. However, using the libcgroup -provided utilities simplifies the process and extends your capabilities. Therefore, this guide focuses on libcgroup commands throughout. In most cases, we have included the equivalent shell commands to help describe the underlying mechanism. However, we recommend that you use the libcgroup commands wherever practical. Note In order to use cgroups, first ensure the libcgroup package is installed on your system by running, as root: 2.1. The cgconfig Service The cgconfig service installed with the libcgroup package provides a convenient way to create hierarchies, attach subsystems to hierarchies, and manage cgroups within those hierarchies. It is recommended that you use cgconfig to manage hierarchies and cgroups on your system. The cgconfig service is not started by default on Red Hat Enterprise Linux 6. When you start the service with chkconfig , it reads the cgroup configuration file - /etc/cgconfig.conf . Cgroups are therefore recreated from session to session and remain persistent. Depending on the contents of the configuration file, cgconfig can create hierarchies, mount necessary file systems, create cgroups, and set subsystem parameters for each group. The default /etc/cgconfig.conf file installed with the libcgroup package creates and mounts an individual hierarchy for each subsystem, and attaches the subsystems to these hierarchies. The cgconfig service also allows to create configuration files in the /etc/cgconfig.d/ directory and to invoke them from /etc/cgconfig.conf . If you stop the cgconfig service (with the service cgconfig stop command), it unmounts all the hierarchies that it mounted. 2.1.1. The /etc/cgconfig.conf File The /etc/cgconfig.conf file contains two major types of entries - mount and group . Mount entries create and mount hierarchies as virtual file systems, and attach subsystems to those hierarchies. Mount entries are defined using the following syntax: The libcgroup package automatically creates a default /etc/cgconfig.conf file when it is installed. The default configuration file looks as follows: The subsystems listed in the above configuration are automatically mounted to their respective hierarchies under the /cgroup/ directory. It is recommended to use these default hierarchies for specifying control groups. However, in certain cases you may need to create hierarchies manually, for example when they were deleted before, or it is beneficial to have a single hierarchy for multiple subsystems (as in Section 4.3, "Per-group Division of CPU and Memory Resources" ). Note that multiple subsystems can be mounted to a single hierarchy, but each subsystem can be mounted only once. See Example 2.1, "Creating a mount entry" for an example of creating a hierarchy. Example 2.1. Creating a mount entry The following example creates a hierarchy for the cpuset subsystem: the equivalent of the shell commands: Since each subsystem can be mounted only once, the above commands would fail if cpuset is already mounted. Group entries create cgroups and set subsystem parameters. Group entries are defined using the following syntax: Note that the permissions section is optional. To define permissions for a group entry, use the following syntax: See Example 2.2, "Creating a group entry" for example usage: Example 2.2. Creating a group entry The following example creates a cgroup for SQL daemons, with permissions for users in the sqladmin group to add tasks to the cgroup and the root user to modify subsystem parameters: When combined with the example of the mount entry in Example 2.1, "Creating a mount entry" , the equivalent shell commands are: Note You must restart the cgconfig service for the changes in the /etc/cgconfig.conf file to take effect. However, note that restarting this service causes the entire cgroup hierarchy to be rebuilt, which removes any previously existing cgroups (for example, any existing cgroups used by libvirtd ). To restart the cgconfig service, use the following command: When you install the libcgroup package, a sample configuration file is written to /etc/cgconfig.conf . The hash symbols (' # ') at the start of each line comment that line out and make it invisible to the cgconfig service. 2.1.2. The /etc/cgconfig.d/ Directory The /etc/cgconfig.d/ directory is reserved for storing configuration files for specific applications and use cases. These files should be created with the .conf suffix and adhere to the same syntax rules as /etc/cgconfig.conf . The cgconfig service first parses the /etc/cgconfig.conf file and then continues with files in the /etc/cgconfig.d/ directory. Note that the order of file parsing is not defined, because it does not make a difference provided that each configuration file is unique. Therefore, do not define the same group or template in multiple configuration files, otherwise they would interfere with each other. Storing specific configuration files in a separate directory makes them easily reusable. If an application is shipped with a dedicated configuration file, you can easily set up cgroups for the application just by copying its configuration file to /etc/cgconfig.d/ .
~]# yum install libcgroup mount { subsystem = /cgroup/ hierarchy ; ... } mount { cpuset = /cgroup/cpuset; cpu = /cgroup/cpu; cpuacct = /cgroup/cpuacct; memory = /cgroup/memory; devices = /cgroup/devices; freezer = /cgroup/freezer; net_cls = /cgroup/net_cls; blkio = /cgroup/blkio; } mount { cpuset = /cgroup/red; } ~]# mkdir /cgroup/red ~]# mount -t cgroup -o cpuset red /cgroup/red group <name> { [ <permissions> ] <controller> { <param name> = <param value> ; ... } ... } perm { task { uid = <task user> ; gid = <task group> ; } admin { uid = <admin name> ; gid = <admin group> ; } } group daemons { cpuset { cpuset.mems = 0; cpuset.cpus = 0; } } group daemons/sql { perm { task { uid = root; gid = sqladmin; } admin { uid = root; gid = root; } } cpuset { cpuset.mems = 0; cpuset.cpus = 0; } } ~]# mkdir -p /cgroup/red/daemons/sql ~]# chown root:root /cgroup/red/daemons/sql/* ~]# chown root:sqladmin /cgroup/red/daemons/sql/tasks ~]# echo USD(cgget -n -v -r cpuset.mems /) > /cgroup/red/daemons/cpuset.mems ~]# echo USD(cgget -n -v -r cpuset.cpus /) > /cgroup/red/daemons/cpuset.cpus ~]# echo 0 > /cgroup/red/daemons/sql/cpuset.mems ~]# echo 0 > /cgroup/red/daemons/sql/cpuset.cpus ~]# service cgconfig restart