Ressourcen-Verwaltung mit Control Groups (cgroups)
Virtual File System: cgroup
Bei der Implementierung der cgroups wurde neben Änderungen an Syscalls wie exit()
und [fork]fork() ein Virtuelles Dateisystem namens »cgroup« eingeführt. Dieses erlaubt Userspace-Zugriff, um Gruppen zu erzeugen und diese und deren Subsysteme zu konfigurieren. Ein Ordner in diesem Pseudo-Dateisystem stellt eine cgroup dar. Dateien in diesem Ordner erlauben es, die Gruppe zu konfigurieren.
Das cgroup-Dateisystem wird wie andere Pseudo-Dateisysteme ohne Geräte an einem beliebigen Punkt in der vorhandenen Dateisystem-Hierarchie eingehängt. Ohne weitere Mount-Optionen werden alle verfügbaren Subsysteme in dieser Control Group Hierarchie genutzt. Es wird jedoch empfohlen, nur die benötigten Subsysteme zu nutzen, da dies die notwenidige Konfiguration nur auf diese Subsysteme beschränkt. Um nur eine Auswahl an Subsystemen zu nutzen, werden diese mit Komma getrennt als Mount-Option übergeben:
# mkdir /cgroup # mount -t cgroup -ocpu,cpuset,memory nodev /cgroup
Eine cgroups-Gruppe wird durch den einfachen Aufruf von mkdir
im eingehängten cgroup-Dateisystem erzeugt:
# cd /cgroup # ls cgroup.event_control cpu.rt_period_us cpu.shares release_agent cgroup.procs cpu.rt_runtime_us notify_on_release tasks # mkdir students # ls students cgroup.event_control cpu.rt_period_us cpu.shares tasks cgroup.procs cpu.rt_runtime_us notify_on_release
Subsystem-Schnittstellen beginnen immer mit dem Namen des Subsystems. Beispiel: Bei cpuset.cpu_exclusive
handelt es sich um die Schnittstelle des cpuset-Subsystems.
CGroups-eigene Einträge, unabhängig von Subsystemen, beginnen mit dem Präfix
cgroup.
oder besitzen kein Präfix (aus historischen Gründen). Beispiele für letzteres sind tasks
, release_agent
und notify_on_release
.
tasks
enthält eine Liste aller PIDs, die dieser cgroup zugewiesen sind. Um Prozesse einer Gruppe hinzuzufügen, müssen die jeweiligen PIDs einzeln in die tasks
-Datei geschrieben werden:
# cd /cgroup/students # wc -l tasks 0 tasks # echo 24650 > tasks # echo 24568 > tasks # cat tasks 24650 24568
Diese Prozesse werden automatisch aus ihrer ursprünglichen Gruppe entfernt und in die Gruppe students
verschoben. Je nach geladenen Subsystemen oder Prozess-Eigenschaften kann das Zuweisen eines Prozesses fehlschlagen. Subsysteme überprüfen bei der Zuweisung, ob bestimmte Voraussetzungen erfüllt sind. Zu diesen Voraussetzungen gehören bestimmte Prozess-Eigenschaften, beispielsweise auch, ob ein Subsystem einer initialen Konfiguration unterzogen werden muss. Je nach Fehlermeldung des Schreibvorgangs lässt sich dies unterscheiden. ENOSPC
bedeutet in den meisten Fällen, dass ein Subsystem noch konfiguriert werden muss. EINVAL
bedeutet, dass ein Prozess von einem der Subsysteme nicht in diese Gruppe aufgenommen werden kann.
# echo 24650 > tasks -bash: echo: write error: No space left on device
Bei Nutzung des cpuset
-Subsystems müssen beispielsweise der Gruppe erst CPU- und Speicher-Ressourcen zugewiesen werden, bevor die Gruppe Prozesse aufnehmen kann. Andernfalls würde das Schreiben der PID in die tasks-Datei mit der Fehlermeldung ENOSPC
fehlschlagen.
Sollten Prozesse mit Eigenschaften wie zum Beispiel dem Scheduler-Attribut SCHED_FIFO
oder anderen Echtzeit Scheduler-Policies laufen, werden diese vom Group CPU Scheduler-Subsystem (cpu
) abgelehnt, da der Group CPU Scheduler, je nach Kernel, keine Echtzeit-Prozesse unterstützt. Solche Informationen sind der jeweiligen Subsystem-Dokumentation zu entnehmen.
# ls cgroup.event_control cpu.rt_period_us cpu.shares tasks cgroup.procs cpu.rt_runtime_us notify_on_release # chrt -f 99 yes &> /dev/null & [1] 24940 # echo $! > tasks -bash: echo: write error: Invalid argument # echo $?
Gelöscht werden Control Groups mit dem Befehl oder Syscall rmdir
. Dabei sind folgende Besonderheiten zu beachten: Vor dem Löschen einer Gruppe müssen alle Prozesse in andere Gruppen verschoben werden. Es dürfen auch keine Untergruppen existieren. Aufrufe wie rm -rf
führen hier nicht zum gewünschten Ziel, da das virtuelle Dateisystem der Einfachheit halber nur den Syscall rmdir()
erwartet und rm -rf
viele andere Syscalls nutzt, welche im cgroup-Dateisystem nicht implementiert sind.