Ein mislukka oppstart av OpenVPN kjem ofte som ei klage på ressursar pluss eit velmeint framlegg om å heve ei grense, og framlegget verkar berre om lag halvparten av gongene. Bak desse feila står to uavhengige teljarar. Den eine er ei kjernegrense for talet på oppgåver som ein ekte brukar-ID eig, og ho vert arva når prosessen vert køyrd. Den andre er eit cgroup-budsjett som tenestestyringa brukar på ei eining og alt ho forgreinar. Å lese den effektive verdien av kvar av dei, for eininga som faktisk køyrer, kostar mindre enn ei gjetting.

To teljarar, to spørsmål

LimitNPROC er RLIMIT_NPROC under eit systemd-namn, og rekneskapseininga er den ekte brukar-ID-en. Kvar prosess som brukaren eig, vert talt mot den same summen, inkludert arbeid som andre einingar, ei innloggingsøkt eller ein planleggjarjobb har starta. Grensa er derfor ikkje eit tak per teneste sjølv når ho er sett inne i ei tenesteeining, og ei teneste som forgreinar ein hjelpar for kvar klient, konkurrerer med alt anna som køyrer under den kontoen. Ein travel cron-jobb under same brukaren kan skyve ei VPN-eining over ei linje ho aldri sjølv kryssa.

TasksMax har ein annan eigar: pids-kontrolløren på cgroupen til eininga, som tel oppgåver i staden for prosessar. Trådar er oppgåver, så ein daemon som ser eintråda ut, men har ein arbeidarpool, kan bruke eit budsjett som ved første augekast ser langt større ut enn prosessane hans. EffectiveTasksMax rapporterer kva cgroup-hierarkiet faktisk tillèt når dei overordna slicane har sagt sitt.

Kvifor root-unntaket endrar svaret

Kjernen brukar ikkje RLIMIT_NPROC på ein prosess som ber CAP_SYS_RESOURCE eller CAP_SYS_ADMIN, og difor er ei eining som køyrer som root utan å sleppe privilegium, reelt ubegrensa av den innstillinga. Dette eine unntaket forklarer dei motstridande råda folk byter: å heve LimitNPROC reparerer ein utrulling som sleppte privilegium og gjer absolutt ingenting for ein som vart verande privilegert. Sjekk User= og om daemonen byter identitet etter oppstart før du gjev den innstillinga æra eller skulda. Ei privilegert eining som seinare byter til ein uprivilegert konto, fell tilbake under grensa i bytteaugneblinken, noko som gjer tidslinja til feilen verd å lese også.

Feilfasen snevrar det ytterlegare inn. Ei avvising under klargjering av køyringa, ein forgreiningsfeil rapportert av daemonen sjølv og ei avvist oppgåveoppretting inne i ein cgroup gjev ulike journal-linjer, og berre éi av dei vert svara på av eit større budsjett.

Les dei effektive verdiane, ikkje dei frå skalet

ulimit -u i eit interaktivt skal skildrar det skalet. Det skildrar ikkje kva tenestestyringa sende til daemonen, og seier ingenting om cgroup-rekneskap. Spør eininga i staden, med instansnamnet som finst på verten og ikkje eit døme frå ei rettleing.

systemctl show [email protected] -p User -p LimitNPROC -p TasksCurrent -p TasksMax -p EffectiveTasksMax
cat /proc/$(systemctl show -p MainPID --value [email protected])/limits | grep -i processes

Inne i ein container treng svaret to avlesingar til, fordi ein indre verdi av infinity berre skildrar synet til gjesten. Spør eigaren av verten om containeren sitt eige pids-tak, og stadfest om den indre tenestestyringa i det heile kan delegera den kontrolløren. Ei nøsta eining kan ikkje halde eit budsjett som cgroupen over henne aldri gav.

Dimensjoner rettinga og prov ho under last

Vel eit tal frå arbeidslasta i staden for frå feilteksten. Tel prosessane daemonen startar per tilkopla klient eller per hjelparoppkall, multipliser med samtidigheita utrullinga er venta å bera, legg til ein margin for administrative økter, og samanlikn deretter talet med dei to effektive verdiane. Ei lokal drop-in-overstyring held endringa gjennomgåeleg og overlever pakkeoppdateringar, medan redigering av ei levert einingfil løyner endringa til neste oppdatering byter ho ut. Skriv reknestykket ved sida av overstyringa, fordi neste person som hevar eller senkar ho treng føresetnadene, ikkje det endelege talet.

Budsjettendringar vert brukte ved køyring, så ei ny innlasting åleine endrar ikkje storleiken på prosessar som alt køyrer. Start eininga på nytt gjennom den normale livssyklusen, godta øktavbrotet, og les teljarane igjen på den nye instansen.

sudo systemctl daemon-reload
sudo systemctl restart [email protected]
systemctl show [email protected] -p TasksCurrent -p EffectiveTasksMax
sudo journalctl -u [email protected] -b --no-pager | tail -n 20

Det som provar rettinga, er ei omstarta eining der oppgåvetalet ligg under begge taka medan ho ber den tiltenkte lasta, pluss ein journal som ikkje lenger rapporterer oppgåve- eller forgreiningstømming på same stadiet. Ta vare på tala før og etter saman med endringa, slik at neste gransking startar frå ei måling og ikkje frå det same rådet. Viss talet framleis når taket, var reknestykket feil og ikkje grensa tilfeldigvis for lita, og den skilnaden er verd å kjenne før neste omstart.

Relaterte artiklar