cgroups(7) | Miscellaneous Information Manual | cgroups(7) |
cgroups — Linux styrgrupper
Styrgrupper, vanligen refererade till som cgroups, är en funktion i Linuxkärnan som gör att processer kan organiseras i hierarkiska grupper vars användning av olika typer av resurser sedan kan begränsas och övervakas. Kärnans cgroup-gränssnitt tillhandahålls via ett pseudofilsystem som kallas cgroupfs. Gruppering implementeras i kärnans centrala cgroup-kod, medan resursspårning och -begränsning implementeras i ett antal undersystem per resurstyp (minne, CPU, och så vidare).
En cgroup är en samling av processer som är bundna av en uppsättning gränser eller parametrar som definieras via cgroup-filsystemet.
Ett undersystem är en kärnkomponent som modifierar beteendet hos processerna i en cgroup. Olika undersystem har implementerats, vilket gör det möjligt att göra saker som att begränsa mängden CPU-tid och minne som är tillgängligt i en cgroup, bokföring av CPU-tiden som används av en cgroup och frysning och återupptagande av körningen av processerna i en cgroup. Undersystem är också ibland kända som resurshanterare (resource controllers) (eller helt enkelt, hanterare (controllers)).
En hanterares cgroups är arrangerade i en hierarki. Denna hierarki defineras genom att skapa, ta bort och byta namn på underkataloger i cgroup-filsystemet. På varje nivå av hierarkin kan attribut (t.ex., gränser) definieras. Gränserna, styrningen och bokföringen som erbjuds av cgroups har allmänt sett påverkan genom underhierarkin under den cgroup där attributen definieras. Alltså kan till exempel inte gränserna som placeras på en cgroup på en högre nivå i hierarkin överskridas av avkomme-cgroups.
Den ursprungliga utgåvan av cgroups-implementationen var i Linux 2.6.24. Med tiden har olika cgroup-hanterare lagts till för att möjliggöra hanteringen av olika typer av resurser. Dock var utvecklingen av dessa hanterare i stort sett okoordinerad, med resultatet att många inkonsistenser uppstod mellan hanterare och användandet av cgroup-hierarkier blev ganska komplext. En längre beskrivning av dessa problem finns i kärnans källfil Documentation/admin-guide/cgroup-v2.rst (eller Documentation/cgroup-v2.txt i Linux 4.17 och tidigare).
På grund av problemen med den ursprungliga cgroups-implementationen (cgroups version 1) inleddes, med början i Linux 3.10, arbete på en ny, ortogonal implementation för att åtgärda dessa problem. Från början markerad experimentell, och dold bakom monteringsflaggan -o __DEVEL__sane_behavior gjordes den nya versionen (cgroups version 2) slutligen officiell i och med utgåvan av Linux 4.5. Skillnader mellan de två versionerna beskrivs i texten nedan. Filen cgroup.sane_behavior, som finns i cgroups v1, är en relik från denna monteringsflagga. Filen rapporterar alltid ”0” och finns bara kvar för bakåtkompatibilitet.
Även om cgroups v2 är avsett att vara en ersättning för cgroups v1 finns det äldre systemet kvar (och av kompatibilitetsskäl är det osannolikt att det kommer tas bort). För närvarande implementerar cgroups v2 endast en delmängd av hanterarna som är tillgängliga i cgroups v1. De två systemen är implementerade så att både v1-hanterare och v2-hanterare kan monteras på samma system. Alltså är det till exempel möjligt att använda de hanterare som stödjs under version 2, men också använda version 1-hanterare där version 2 ännu inte stödjer dessa hanterare. Den enda begränsningen är att en hanterare inte samtidigt kan användas i både en cgroups v1-hierarki och i cgroups v2-hierarkin.
Under cgroups v1 kan varje hanterare monteras mot ett separat cgroup-filsystem som ger sin egen hierarkiska organisation av processerna på systemet. Det är också möjligt att sammontera flera (eller alla) cgroups v1-hanterare mot samma cgroup-filsystem, vilket betyder att de sammonterade hanterarna använder samma hierarkiska organisation av processer.
För varje monterad hierarki avspeglar katalogträdet styrgruppshierarkin. Varje styrgrupp representeras av en katalog, där var och en av dess barnstyr-cgroup representeras av en barnkatalog. Till exempel representerar /user/johan/1.session styrgruppen 1.session, vilken är ett barn till johan, vilken är ett barn till /user. Under varje cgroup-katalog finns en uppsättning filer vilka kan läsas eller skrivas till, vilket avspeglar resursbegränsningar och några allmänna cgroup-egenskaper.
I cgroups v1 dras en distinktion mellan processer och uppgifter. I denna vy kan en process bestå av flera uppgifter (oftare kallade trådar, från ett användarperspektiv, och kallas så i resten av denna manualsida). I cgroups v1 är det möjligt att hantera cgroup-medlemskapet hos trådarna i en process oberoende av varandra.
Cgroups v1 möjlighet att dela trådar över olika cgroups orsakade problem i en del fall. Till exempel var det inte meningsfullt för minneshanteraren eftersom alla trådarna i en process delar en enda adressrymd. På grund av dessa problem togs möjlighetn att oberoende hantera cgroup-medlemskapet hos trådar i en process bort i den ursprungliga cgroups v2-implementationen, och återställdes senare i en mer begränsad form (se diskussionen om ”trådläge” nedan).
Användningen av cgroups förutsätter en kärna byggd med alternativet CONFIG_CGROUP. Dessutom har var och en av v1-hanterarna ett associerat konfigurationsalternativ som måste vara satt för att använda den hanteraren.
För att använda en v1-hanterare måste den monteras mot ett cgroup-filsystem. Den vanliga platsen för sådana monteringar är under ett tmpfs(5)-filsystem monterat på /sys/fs/cgroup. Man kan alltså montera cpu-hanteraren enligt följande:
mount -t cgroup -o cpu none /sys/fs/cgroup/cpu
Det är möjligt att sammontera flera hanterare mot samma hierarki. Till exempel sammonteras här hanterarna cpu och cpuacct mot en enda hierarki:
mount -t cgroup -o cpu,cpuacct none /sys/fs/cgroup/cpu,cpuacct
Sammontering av hanterare har effekten att en process är i samma cgroup för alla sammonterade hanterare. Separat monterade hanterare gör det möjligt för en process att finnas i en cgroup /apa1 för en hanterare medan den finns i /apa2/apa3 för en annan.
Det är möjligt att sammontera alla v1-hanterare mot samma hierarki:
mount -t cgroup -o all cgroup /sys/fs/cgroup
(Man kan åstadkomma samma resultat genom att utelämna -o all eftersom det är standardbeteendet om inga hanterare uttryckligen anges.)
Det är inte möjligt att montera samma hanterare mot flera cgroup-hierarkier. Till exempel är det inte möjligt att montera både hanteraren cpu och cpuacct mot en hierarki, och att montera hanteraren cpu ensam mot en annan hierarki. Det är möjligt att skapa flera monteringar med exakt samma uppsättning av sammonterade hanterare. I det fallet är dock det enda som händer att flera monteringspunkter ger en vy av samma hierarki.
Observera att på många system är v1-hanterarna automatiskt monterade under /sys/fs/cgroup; speciellt skapar systemd(1) automatiskt sådana monteringar.
Ett monterat cgroup-filsystem kan avmonteras med kommandot umount(8), som i följande exempel:
umount /sys/fs/cgroup/pids
Men observera även: ett cgroup-filsystem avmonteras bara om det inte är upptaget, det vill säga att det inte har någon barn-cgroup. Om det inte är fallet är enda effekten av umount(8) att göra monteringen osynlig. Alltså måste man för att säkerställa att en montering verkligen tas bort först ta bort alla barn-cgroup:er, vilket i sin tur endast kan göras efter att alla medlemsprocesser har flyttats ifrån dessa cgroup:er till root-cgroup:en.
Varje hanterare i cgroup version 1 styrs av ett kärnkonfigurationsalternativ (uppräknat nedan). Dessutom styrs tillgängligheten av funktionen cgroup av kärnkonfigurationsalternativet CONFIG_CGROUPS.
Ett styrgruppfilsystem innehåller initialt en ensam rotstyrgrupp, ”/”, vilken alla processer hör till. En ny styrgrupp skapas genom att skapa en katalog i styrgruppfilsystemet:
mkdir /sys/fs/cgroup/cpu/sg1
Detta skapar en ny tom styrgrupp.
En process kan flyttas till denna styrgrup genom att skriva dess PID in i styrgruppens fil cgroup.procs:
echo $$ > /sys/fs/cgroup/cpu/sg1/cgroup.procs
Endast en PID åt gången får skrivas till denna fil.
Om man skriver värdet 0 till en fil cgroup.procs flyttas den skrivande processen till motsvarande styrgrupp.
När man skriver ett PID in i cgroup.procs flyttas alla trådar i processen in i den nya styrgruppen på en gång.
Inom en hierarki kan en process vara medlem av precis en styrgrupp. När man skriver en process PID till en fil cgroup.procs tas den automatiskt bort från den styrgrupp den var medlem av tidigare.
Filen cgroup.procs kan läsas för att hämta en lista på processer som är medlemmar av en styrgrupp. Den returnerade listan av PID:er är inte garanterat i ordning. Inte heller är den garanterat fri från upprepningar. (Till exempel kan ett PID ha blivit återanvänt medan listan lästes.)
I cgroups v1 kan en enskild tråd flyttas till en annan styrgrupp genom att skriva dess tråd-ID (d.v.s., kärnans tråd-ID returnerat från clone(2) och gettid(2)) till filen tasks i en styrgruppskatalog. Denna fil kan läsas för att se uppsättningen av trådar som är medlemmar av styrgruppen.
För att ta bort en styrgrupp får den först inte ha några barnstyrgrupper och inte innehålla några processer (andra än zombier). Förutsatt att det är fallet kan man helt enkelt ta bort motsvarande katalogsökväg. Observera att filer i en styrgruppskatalog inte kan och inte behöver tas bort.
Två filer kan användas för att avgöra huruvida kärnan skall tillhandahålla notifieringar när en styrgrupp blir tom. En styrgrupp anses tom när den inte innehåller några barnstyrgrupper och inga medlemsprocesser.
En speciell fil i rotkatalogen av varje styrgruppshierarki, release_agent, kan användas för att registrera sökvägsnamnet till ett program som kan anropas när en styrgrupp i hierarkin blir tom. Sökvägen till den nyss tömda styrgruppen (relativt monteringspunkten för styrgrupper) ges som det enda kommandoradsargumentet när programmet release_agent anropas. Programmet release_agent kan ta bort styrgruppskatalogen, eller kanske återpopulera den med en process.
Standardvärdet i filen release_agent är tomt, vilket betyder att ingen släppagent anropas.
Innehållet i filen release_agent kan också anges via en monteringsflagga när styrgruppsfilsystemet monteras:
mount -o release_agent=sökväg …
Huruvida programmet release_agent anropas eller inte när en viss styrgrupp blir tom avgörs av värdet i filen notify_on_release i motsvarande styrgruppskatalog. Om denna fil innehåller värdet 0, då anropas inte programmet release_agent. Om den innehåller värdet 1 anropas programmet release_agent. Standardvärdet i denna fil i rotstyrgruppen är 0. När en ny styrgrupp skapas ärvs värdet i denna fil från motsvarande fil i föräldrastyrgruppen.
I cgroups v1 är det möjligt att montera en styrgruppshierarki som inte har några tillkopplade hanterare:
mount -t cgroup -o none,name=ngtnamn none /någon/monterings/punkt
Flera instanser av sådana hierarkier kan monteras; varje hierarki måste ha ett unikt namn. Det enda syftet med sådana hierarkier är att spåra processer. (Se diskussionen om släppnotifieringar nedan.) Ett exempel på detta är styrgruppshierarkin name=systemd som används av systemd(1) för att spåra tjänster och användarsessioner.
Sedan Linux 5.0 kan kärnans uppstartsflagga cgroup_no_v1 (beskriven nedan) användas till att avaktivera namngivna hierarkier inom cgroup v1, genom att ange cgroup_no_v1=namngiven.
I cgroups v2 bor alla monterade hanterare i en enda sammanslagen hierarki. Även om (olika) hanterare kan monteras samtidigt under v1- och v2-hierarkierna är det inte möjligt att montera samma hanterare samtidigt under både v1- och v2-hierarkierna.
De nya beteendena i cgroups v2 sammanfattas här, och utvecklas i några fall i de följande underavsnitten.
För fler ändringar, se filen Documentation/admin-guide/cgroup-v2.rst i kärnans källa (eller Documentation/cgroup-v2.txt i Linux 4.17 och tidigare).
Några av de nya beteendena ovan modifierades senare med tillägget i Linux 4.14 av ”trådläge” (beskrivet nedan).
I cgroups v1 var möjligheten att montera olika hanterare mot olika hierarkier avsedd att ge en stor flexibilitet i designen av program. I praktiken visade sig dock flexibiliteten vara mindre användbar än förväntat, och i många fall lade den till komplexitet. Därför monteras i cgroups v2 alla tillgängliga hanterare mot en enda hierarki. De tillgängliga hanterarna monteras automatiskt, vilket betyder att det inte är nödvändigt (eller möjligt) att ange hanterarna när man monterar filsystemet för cgroups v2 med ett kommando som det följande:
mount -t cgroup2 none /mnt/cgroup2
En hanterare i cgroup v2 är tillgänglig endast om den inte för närvarande används via en montering mot en cgroup v1-hierarki. Eller, för att uttrycka det på ett annat sätt, är det inte möjligt att använda samma hanterare mot både en v1-hierarki och den sammanslagna v2-hierarkin. Detta betyder att det kan vara nödvändigt att först avmontera en v1-hanterare (som beskrivet ovan) före den hanteraren är tillgänglig i v2. Eftersom systemd(1) normalt använder sig mycket av några v1-hanterare kan det i några fall vara enklare att starta med de valda v1-hanterarna avaktiverade. För att göra detta, ange flaggan cgroup_no_v1=lista på kärnans startkommandorad; lista är en kommaseparerad lista av namnen på hanterare att avaktivera, eller ordet all för att avaktivera alla v1-hanterare. (Denna situation hanteras korrekt av systemd(1) som faller tillbaka på att arbeta utan de angivna hanterarna.)
Observera att på många moderna system monterar systemd(1) automatiskt filsystemet cgroup2 på /sys/fs/cgroup/unified under uppstartsprocessen.
Följande flaggor (mount -o) kan anges vid montering av cgroup v2-filsystemet:
Följande hanterare, dokumenterade i kärnans källfil Documentation/admin-guide/cgroup-v2.rst (eller Documentation/cgroup-v2.txt i Linux 4.17 och tidigare), stödjs i styrgrupper version 2:
Det finns ingen direkt motsvarighet till hanterarna net_cls och net_prio från styrgrupper version 1. Istället har stöd lagts till i iptables(8) för att tillåta eBPF-filter att haka på sökvägar i cgroup v2 för att ta beslut om nätverkstrafik baserat på styrgrupp.
Hanteraren devices i v2 ger inget gränssnitt till filer; istället begränsas enhetsstyrningen genom att koppla ett eBPF-program (BPF_CGROUP_DEVICE) till en v2-styrgrupp.
Varje styrgrupp i v2-hierarkin innehåller följande två filer:
echo '+pids -memory' > x/y/cgroup.subtree_control
Eftersom listan av hanterare i cgroup.subtree_control är en delmängd av dem i cgroup.controllers kan en hanterare som har avaktiverats i en styrgrupp i hierarkin aldrig återaktiveras i underträdet nedanför den styrgruppen.
En styrgrupps fil cgroup.subree_control avgör uppsättningen hanterare som används i barnstyrgruppen. När en hanterare (t.ex., pids) finns i filen cgroup.subtree_control i en föräldrastyrgrupp, då skapas automatiskt motsvarande hanterargränssnittsfiler (t.ex., pids.max) i barnen till den styrgruppen och kan användas för att utöva resursstyrning i barnstyrgrupperna.
Cgroups v2 upprätthåller en så kallad ”inga interna processer”-regel. Grovt uttryckt betyder denna regel att, med undantag för rotstyrgruppen, processer endast får bo i lövnoder (styrgrupper som inte själva innehåller barnstyrgrupper). Detta undviker behovet av att avgöra hur resurser skall fördelas mellan processer som är medlemmar av en styrgrupp A och processer i barnstyrgrupper till A.
Till exempel, om styrgruppen /sg1/sg2 finns, då kan en process bo i /sg1/sg2, men inte i /sg1. Detta är så för att undvika en tvetydighet i cgroups v1 med avseende på delegationen av resurser mellan processer i /sg1 och dess barnstyrgrupper. Det rekommenderade sättet i cgroups v2 är att skapa en underkatalog som heter leaf för alla styrgrupper som inte är löv, vilken skall innehålla processer men inga barnstyrgrupper. Alltså, processer vilka tidigare skulle ha hamnat i /sg1 skulle nu hamna i /sg1/leaf. Detta har fördelen att göra relationen mellan processer i /sg1/leaf och /sg1s andra barn explicit.
Regeln om ”inga interna processer” är i verkligheten mer subtil än den uttrycks ovan. Mer exakt är regeln att en styrgrupp (annan än roten) inte både kan (1) ha medlemsprocesser, och (2) distribuera resurser till barnstyrgrupper — det vill säga, ha en fil cgroup.subtree_control som inte är tom. Alltså är det möjligt för en styrgrupp att både ha medlemsprocesser och barnstyrgrupper, men före några hanterare kan aktiveras för den styrgruppen måste medlemsprocesserna flyttas ut ur styrgruppen (t.ex., kanske in i barnstyrgrupperna).
Med tillägget i Linux 4.14 av ”trådat läge” (beskrivet nedan) har regeln om ”inga interna processer” blivit friare i några fall.
Varje styrgrupp annan än roten i v2-hierarkin innehåller en fil endast för läsning, cgroup.events, vars innehåll är nyckel-värde-par (begränsade med nyradstecken, med nyckeln och värdet separerade med blanktecken) som ger information om styrgruppen.
$ cat mingrp/cgroup.events populated 1 frozen 0
Följande nycklar kan förekomma i denna fil:
Filen cgroup.events kan övervakas för att ta emot notifieringar när värdet på en av dess nycklar ändras. Sådan övervakning kan göras med inotify(7), vilket notifierar om ändringar som IN_MODIFY-händelser, eller poll(2), vilket notifierar om ändringar genom att returnera bitarna POLLPRI och POLLERR i fältet revents.
Cgroups v2 tillhandahåller en ny mekanism för att få notifieringar när en styrgrupp blir tom. Filerna release_agent och notify_on_release är borttagna, och ersatta av nyckeln populated i filen cgroup.events. Denna nyckel har antingen värdet 0, vilket betyder att styrgruppen (och dess avkommor) inte innehåller några medlemsprocesser (andra än zombier), eller 1, vilket betyder att styrgruppen (eller en av dess avkommor) innehåller medlemsprocesser.
Mekanismen för släppnotifieringar i cgroups v2 ger följande fördelar framför mekanismen release_agent i cgroups v1:
Varje styrgrupp i v2-hierarkin innehåller en fil cgroup.stat endast för läsning (först introducerad i Linux 4.14) som består av rader som innehåller nyckel-värde-par. Följande nycklar finns för närvarande i denna fil:
Varje styrgrupp i v2-hierarkin innehåller följande filer, vilka kan användas för att visa och sätta begränsningar på antalet avkommestyrgrupper under den styrgruppen:
I styrgruppssammanhang betyder delegering att man överlåter hanteringen av något underträd av denna styrgruppshierarki till en oprivilegierad användare. Cgroups v1 ger stöd för delegering baserat på filrättigheter i styrgruppshierarkin men med mindre strikta begränsningsregler än v2 (som noteras nedan). Cgroups v2 stödjer delegering med begränsningar genom en explicit design. Fokuset för diskussionen i detta avsnitt är på delegering i cgroups v2, med några avvikelser för cgroups v1 nämnda längs vägen.
Lite terminologi krävs för att beskriva delegering. En delegerare är en privilegierad användare (d.v.s., root) som äger en föräldrastyrgrupp. En delegat är en oprivilegierad användare som kommer få rättigheterna som behövs för att hantera någon underhierarki under föräldrastyrgruppen, känt som det delegerade underträdet.
För att utföra en delegering gör delegeraren vissa kataloger och filer skrivbara för delegaten, typiskt genom att ändra ägarskap på objekten till att vara användar-ID:t för delegaten. Om vi antar att vi vill delegera hierarkin med rot vid (förslagsvis) /dlgt_grp och att det inte ännu finns några barnstyrgrupper under den styrgruppen, då ändras ägandet av följande till användar-ID:t för delegaten:
Delegeraren skall inte ändra ägaren av någon annan av hanterarens gränssnittsfiler (t.ex., pids.max, memory.high) i dlgt_grp. Dessa filer används från nästa nivå ovanför det delegerade underträdet för att fördela resurser in i underträdet, och delegaten skall inte ha rätt att ändra resurserna som fördelas in i det delegerade underträdet.
Se även diskussionen om filen /sys/kernel/cgroup/delegate i NOTERINGAR för information om ytterligare delegerbara filer i cgroups v2.
Efter att de tidigare nämnda stegen har utförts kan delegaten skapa barnstyrgrupper inom det delegerade underträdet (styrgruppens underkataloger och filerna de innehåller kommer att ägas av delegaten) och flytta processer mellan styrgrupper i underträdet. Om några hanterare finns i dlgt_grp/cgroup.subtree_control, eller om ägandet av den filen överläts på delegaten, kan delegaten även styra den vidare omfördelningen av motsvarande resurser in i det delegerade underträdet.
Med start i Linux 4.13 finns det även ett andra sätt att utföra styrgruppsdelegering i cgroups v2-hierarkin. Detta görs genom att montera eller montera om cgroups v2-filsystemet med monteringsflaggan nsdelegate. Till exempel, om cgroup v2-filsystemet redan har monterats kan vi montera om det med flaggan nsdelegate så här:
mount -t cgroup2 -o remount,nsdelegate \ none /sys/fs/cgroup/unified
Effekten av denna monteringsflagga är att den får styrgruppsnamnrymder att automatiskt bli delegeringsgränser. Mer specifikt gäller följande restriktioner för processer inuti styrgruppsnamnrymden:
Möjligheten att definiera styrgruppsnamnrymder som delegeringsgränser gör styrgruppsnamnrymder mer användbara. För att förstå varför, anta att vi redan har en styrgruppshierarki som har delegerats till en oprivilegierad användare, cecilia, med den äldre delegeringstekniken som beskrivs ovan. Anta vidare att cecilia vill delegera en underhierarki vidare under den befintliga delegerade hierarkin. (Till exempel kanske den delegerade hierarkin kan vara associerad med en oprivilegierad behållare som körs av cecilia.) Även om en styrgruppsnamnrymd användes skulle, eftersom båda hierarkierna ägs av den oprivilegierade användaren cecilia, följande illegitima åtgärder kunna utföras.
Genom att använda monteringsflaggan nsdelegate förhindras båda dessa möjligheter.
Monteringsflaggan nsdelegate har bara någon effekt när den används i den initiala monteringsnamnrymden; i andra monteringsnamnrymder ignoreras flaggan tyst.
Observera: på en del system monterar systemd(1) automatiskt filsystemet cgroup v2. För att experimentera med flaggan nsdelegate kan det vara användbart att starta kärnan med följande kommandoradsflaggor:
cgroup_no_v1=all systemd.legacy_systemd_cgroup_controller
Dessa flaggor får kärnan att starta med cgroups v1-hanterarna avaktiverade (vilket betyder att hanterarna finns tillgängliga i v2-hierarkin), och säger till systemd(1) att inte montera och använda cgroup v2-hierarkin, så att v2-hierarkin kan monteras manuellt med de önskade flaggorna efter uppstart.
Några inneslutningsregler för delegering säkerställer att delegaten kan flytta processer mellan styrgrupper inom det delegerade underträdet, men inte kan flytta processer utifrån det delegerade underträdet in i underträdet eller vice versa. En oprivilegierad process (d.v.s., delegaten) kan skriva PID:en för en ”mål”-process in i en fil cgroup.procs endast om alla följande är sanna:
Observera: en konsekvens av dessa inneslutningsreger för delegering är att den oprivilegierade delegaten inte kan placera in den första processen i det delegerade underträdet; istället måste delegeraren placera in den första processen (en process som ägs av delegaten) i det delegerade underträdet.
Bland restriktionerna som åläggs av cgroups v2 och som inte fanns med i cgroups v1 är följande:
Båda dessa restriktioner lades till för att avsaknaden av dessa restriktioner hade orsakat problem i cgroups v1. Speciellt var möjligheten i cgroups v1 att tillåta upplösning på trådnivå av styrgruppsmedlemskap inte meningsfull för några hanterare. (Ett noterbart exempel var hanteraren memory: eftersom trådar delar en adressrymd är det inte meningsfullt att dela trådar mellan olika memory-styrgrupper.)
Oaktat det ursprungliga designbeslutet i cgroups v2 fanns det användningsfall för vissa hanterare, särskilt hanteraren cpu, för vilka upplösning av styrningen på trådnivå var meningsfull och användbar. För att rymma sådana fall lade Linux 4.14 till trådläge till cgroups v2.
Trådläge tillåter följande:
Med tillägget av trådläge innehåller numera varje styrgrupp utom roten en ny fil, cgroup.type, som visar, och under vissa omständigheter kan användas för att ändra, en styrgrupps ”typ”. Denna fil innehåller ett av följande typvärden:
I och med tillägget av trådat läge särskiljer cgroups v2 nu två typer av resurshanterare:
Det finns två vägar som leder till att ett trådat underträd skapas. Den första vägen är som följer:
Den andra vägen att skapa ett trådat underträd är som följer:
En av konsekvenserna av de ovanstående sätten för att skapa ett trådat underträd är att den trådade rotstyrgruppen endast kan vara förälder till styrgrupper som är trådade (och domän felaktiga). Den trådade rotstyrgruppen kan inte vara förälder till domänstyrgrupper, och en trådad styrgrupp kan inte ha ett syskon som är en domänstyrgrupp.
Inom ett trådat underträd kan trådade hanterare aktiveras i varje undergrupp vars typ har ändrats till trådad; när man gör det dyker motsvarande gränssnittsfiler för hanteraren upp i barnen till den styrgruppen.
En process kan flyttas in i ett trådat underträd genom att skriva dess PID till filen cgroup.procs i en av styrgrupperna inuti trädet. Detta medför att alla trådarna i den processen görs till medlemmar av motsvarande styrgrupp och gör processen till en medlem av det trådade underträdet. Processens trådar kan sedan spridas över det trådade underträdet genom att skriva deras tråd-ID:n (se gettid(2)) till filerna cgroup.threads i olika styrgrupper inuti underträdet. En process alla trådar måste befinna sig i samma trådade underträd.
Liksom när man skriver till cgroup.procs gäller vissa inneslutningsregler när man skriver till filen cgroup.threads:
Filen cgroup.threads finns i alla styrgrupper (inklusive domänstyrgrupper) och kan läsas för att upptäcka uppsättningen trådar som finns i styrgruppen. Uppsättningen tråd-ID:n som fås när man läser denna fil är inte garanterat i ordning eller fri från dubbletter.
Filen cgroup.procs i den trådade roten visar PID:arna för alla processer som är medlemmar av det trådade underträdet. Filen cgroup.procs i de andra styrgrupperna i underträdet är inte läsbara.
Domänhanterare kan inte aktiveras i ett trådat underträd; inga gränssnittsfiler till hanteraren dyker upp i styrgrupperna under den trådade roten. Från domänhanterarens synvinkel är trådade underträd osynliga: en multitrådad process i ett trådat underträd ser för domänhanteraren ut som en process som bor i den trådade rotstyrgruppen.
Inom ett trådat underträd gäller inte regeln ”inga interna processer”: en styrgrupp kan både innehålla medlemsprocesser (eller -trådar) och utöva styrning över barnstyrgrupper.
Ett antal regler gäller vid skrivning till filen cgroup.type:
Det finns även några begränsningar som måste vara uppfyllda för att skapa ett trådat underträd rotat i styrgruppen x:
Vid brott mot någon av ovanstående begränsningar kommer försök att skriva ”threaded” till en fil cgroup.type att misslyckas med felet ENOTSUP.
Enligt metoderna som beskrivs ovan kan typen på en styrgrupp ändras till domän trådad i endera av följande fall:
En domän trådad styrgrupp, x, kan återgå till typen domän om ovanstående villkor inte längre är uppfyllda — det vill säga, om alla trådade barnstyrgrupper till x tas bort och antingen x inte längre har trådade hanterare aktiverade eller inte längre har medlemsprocesser.
När en styrgrupp x som är domän trådad återgår till typen domän:
Rotstyrgruppen i v2-hierarkin hanteras speciellt: den kan vara förälder till både domän och trådade styrgrupper. Om strängen ”threaded” skrivs till filen cgroup.type i en av barnen till rotstyrgruppen, då
Observera att i detta fall finns det ingen styrgrupp vars typ blir domän trådad. (Teoretiskt sett kan rotstyrgruppen betraktas som den trådade roten till styrgruppen vars typ ändrades till trådad.)
Syftet med denna speciella hantering av rotstyrgruppen är att låta en trådad styrgrupp som använder hanteraren cpu att placeras så högt som möjligt i hierarkin, för att minimera den (lilla) kostnaden i att traversera styrgruppshierarkin.
Per Linux 4.19 stödjer inte hanteraren cpu i cgroups v2 styrning av realtidstrådar (specifikt trådar schemalagda under någon av policyerna SCHED_FIFO, SCHED_RR och SCHED_DEADLINE; se sched(7)). Därför kan hanteraren cpu aktiveras i rotstyrgruppen endast om alla realtidstrådar finns i rotstyrgruppen. (Om det finns realtidstrådar i andra styrgrupper än roten, då misslyckas ett anrop av write(2) med strängen ”+cpu” till filen cgroup.subtree_control med felet EINVAL.)
På vissa system placerar systemd(1) vissa realtidstrådar i andra styrgrupper än roten i v2-hierarkin. På sådana system måste dessa trådar först flyttas till rotstyrgruppen innan cpu-hanteraren kan aktiveras.
Följande fel kan förekomma för mount(2):
En barnprocess som skapas via fork(2) ärver sin förälders styrgruppsmedlemskap. En process styrgruppsmedlemskap bevaras över execve(2).
Flaggan CLONE_INTO_CGROUP till clone3(2) kan användas för att skapa en barnprocess som inleder sitt liv i en annan version-2-styrgrupp än föräldraprocessen.
#subsys_name hierarchy num_cgroups enabled cpuset 4 1 1 cpu 8 1 1 cpuacct 8 1 1 blkio 6 1 1 memory 3 1 1 devices 10 84 1 freezer 7 1 1 net_cls 9 1 1 perf_event 5 1 1 net_prio 9 1 1 hugetlb 0 1 0 pids 2 1 1
hierarki-ID:hanterarlista:styrgruppssökväg
5:cpuacct,cpu,cpuset:/daemons
$ cat /sys/kernel/cgroup/delegate cgroup.procs cgroup.subtree_control cgroup.threads
$ cat /sys/kernel/cgroup/features nsdelegate memory_localevents
prlimit(1), systemd(1), systemd-cgls(1), systemd-cgtop(1), clone(2), ioprio_set(2), perf_event_open(2), setrlimit(2), cgroup_namespaces(7), cpuset(7), namespaces(7), sched(7), user_namespaces(7)
Kärnans källfil Documentation/admin-guide/cgroup-v2.rst.
Den svenska översättningen av denna manualsida skapades av Göran Uddeborg <goeran@uddeborg.se>
Denna översättning är fri dokumentation; läs GNU General Public License Version 3 eller senare för upphovsrättsvillkor. Vi tar INGET ANSVAR.
Om du hittar fel i översättningen av denna manualsida, skicka ett mail till Tp-sv@listor.tp-sv.se.
5 februari 2023 | Linux man-pages 6.03 |