pid_namespaces(7) Miscellaneous Information Manual pid_namespaces(7) NUME pid_namespaces - vedere de ansamblu a spaiilor de nume PID Linux DESCRIERE Pentru o descriere generala a spaiilor de nume, consultai namespaces(7). Spaiile de nume PID izoleaza spaiul numerelor ID ale proceselor, ceea ce inseamna ca procesele din diferite spaii de nume PID pot avea acelai PID. Spaiile de nume PID permit containerelor sa ofere funcionalitai precum suspendarea/reluarea setului de procese din container i migrarea containerului catre o noua gazda, in timp ce procesele din container pastreaza aceleai PID-uri. PID-urile dintr-un nou spaiu de nume PID incep de la 1, oarecum ca intr-un sistem autonom, iar apelurile la fork(2), vfork(2) sau clone(2) vor produce procese cu PID-uri unice in spaiul de nume. Utilizarea spaiilor de nume PID necesita un nucleu care este configurat cu opiunea CONFIG_PID_NS. Procesul de iniiere (init) a spaiului de nume Primul proces creat intr-un spaiu de nume nou (de exemplu, procesul creat folosind clone(2) cu fanionul CLONE_NEWPID sau primul copil creat de un proces dupa un apel la unshare(2) folosind fanionul CLONE_NEWPID) are PID-ul 1 i este procesul ,,init" pentru spaiul de nume (a se vedea init(1)). Acest proces devine parintele oricarui proces copil ramas orfan din cauza incetarii unui proces care se afla in acest spaiu de nume PID (a se vedea mai jos pentru detalii suplimentare). Daca procesul ,,init" al unui spaiu de nume PID se incheie, nucleul incheie toate procesele din spaiul de nume prin intermediul unui semnal SIGKILL. Acest comportament reflecta faptul ca procesul ,,init" este esenial pentru funcionarea corecta a unui spaiu de nume PID. In acest caz, un fork(2) ulterior in acest spaiu de nume PID eueaza cu eroarea ENOMEM; nu este posibila crearea unui proces nou intr-un spaiu de nume PID al carui proces ,,init" s-a incheiat. Astfel de scenarii pot aparea atunci cand, de exemplu, un proces utilizeaza un descriptor de fiier deschis pentru un fiier /proc/pid/ns/pid corespunzator unui proces care se afla intr-un spaiu de nume pentru a setns(2) in acel spaiu de nume dupa ce procesul ,,init" s-a incheiat. Un alt scenariu posibil poate aparea dupa un apel la unshare(2): daca primul copil creat ulterior de un fork(2) se termina, atunci apelurile ulterioare la fork(2) eueaza cu ENOMEM. Doar semnalele pentru care procesul ,,init" a stabilit un gestionar de semnale pot fi trimise procesului ,,init" de catre ali membri ai spaiului de nume PID. Aceasta restricie se aplica chiar i proceselor privilegiate i previne omorarea accidentala a procesului ,,init" de catre ali membri ai spaiului de nume PID. De asemenea, un proces dintr-un spaiu de nume antecesor poate trimite semnale catre procesul ,,init" al unui spaiu de nume PID copil numai daca procesul ,,init" a stabilit un gestionar pentru semnalul respectiv -- sub rezerva verificarilor obinuite ale permisiunilor descrise in kill(2) --; (in cadrul gestionarului, campul siginfo_t si_pid descris in sigaction(2) va fi zero). SIGKILL sau SIGSTOP sunt tratate in mod excepional: aceste semnale sunt livrate forat atunci cand sunt trimise dintr-un spaiu de nume PID antecesor. Niciunul dintre aceste semnale nu poate fi capturat de procesul ,,init" i, prin urmare, va duce la aciunile obinuite asociate acestor semnale (respectiv, terminarea i oprirea procesului). Incepand cu Linux 3.4, apelul de sistem reboot(2) face ca un semnal sa fie trimis catre procesul ,,init" din spaiul de nume. Consultai reboot(2) pentru mai multe detalii. Imbricarea spaiilor de nume PID Spaiile de nume PID pot fi imbricate: fiecare spaiu de nume PID are un parinte, cu excepia spaiului de nume PID iniial (,,radacina"). Parintele unui spaiu de nume PID este spaiul de nume PID al procesului care a creat spaiul de nume utilizand clone(2) sau unshare(2). Spaiile de nume PID formeaza astfel un arbore, toate spaiile de nume urmandu-i stramoii pana la spaiul de nume radacina. Incepand cu Linux 3.7, nucleul limiteaza la 32 adancimea maxima de imbricare pentru spaiile de nume PID. Un proces este vizibil pentru alte procese din spaiul sau de nume PID i pentru procesele din fiecare spaiu de nume PID ancestru direct pana la spaiul de nume PID radacina. In acest context, ,,vizibil" inseamna ca un proces poate fi inta operaiilor unui alt proces care utilizeaza apeluri sistem care specifica un ID de proces. Invers, procesele dintr-un spaiu de nume PID copil nu pot vedea procesele din spaiul de nume parinte i din spaiile de nume ancestru mai indepartate. Mai succint: un proces poate vedea (de exemplu, poate trimite semnale cu kill(2), poate stabili valori de curtoazie (nice) cu setpriority(2) etc.) numai proceselor coninute in propriul sau spaiu de nume PID i in descendenii acestui spaiu de nume. Un proces are un ID de proces in fiecare dintre straturile ierarhiei spaiului de nume PID in care este vizibil i se deplaseaza inapoi prin fiecare spaiu de nume ancestru direct pana la spaiul de nume PID radacina. Apelurile sistemului care opereaza asupra ID-urilor de proces opereaza intotdeauna folosind ID-ul de proces care este vizibil in spaiul de nume PID al apelantului. Un apel la getpid(2) returneaza intotdeauna PID-ul asociat cu spaiul de nume in care a fost creat procesul. Unele procese dintr-un spaiu de nume PID pot avea parini care sunt in afara spaiului de nume. De exemplu, parintele procesului iniial din spaiul de nume (i anume, procesul init(1) cu PID 1) se afla in mod necesar intr-un alt spaiu de nume. De asemenea, copiii direci ai unui proces care utilizeaza setns(2) pentru a determina copiii sai sa se alature unui spaiu de nume PID se afla intr-un spaiu de nume PID diferit de cel care apeleaza setns(2). Apelurile la getppid(2) pentru astfel de procese returneaza 0. In timp ce procesele pot cobori liber in spaiile de nume PID copil (de exemplu, utilizand setns(2) cu un descriptor de fiier de spaiu de nume PID), acestea nu se pot deplasa in direcia opusa. Cu alte cuvinte, procesele nu pot intra in niciun spaiu de nume ancestru (parinte, bunic etc.). Schimbarea spaiilor de nume PID este o operaie unidirecionala. Operaia NS_GET_PARENT ioctl(2) poate fi utilizata pentru a descoperi relaia parentala dintre spaiile de nume PID; a se vedea ioctl_nsfs(2). Semanticele setns(2) i unshare(2) Apelurile la setns(2) care specifica un descriptor de fiier al spaiului de nume PID i apelurile la unshare(2) cu fanionul CLONE_NEWPID determina ca procesele-copil create ulterior de apelant sa fie plasate intr-un spaiu de nume PID diferit de cel al apelantului; (incepand cu Linux 4.12, acel spaiu de nume PID este indicat prin intermediul fiierului /proc/pid/ns/pid_for_children, aa cum este descris in namespaces(7)). Cu toate acestea, aceste apeluri nu modifica spaiul de nume PID al procesului apelant, deoarece acest lucru ar schimba ideea apelantului despre propriul sau PID (aa cum este raportat de getpid()), ceea ce ar rupe multe aplicaii i biblioteci. Altfel spus: apartenena unui proces la spaiul de nume PID este determinata la crearea procesului i nu poate fi modificata ulterior. Printre altele, aceasta inseamna ca relaia parentala dintre procese reflecta relaia parentala dintre spaiile de nume PID: parintele unui proces fie se afla in acelai spaiu de nume, fie se afla in spaiul de nume PID al parintelui imediat. Un proces poate apela unshare(2) cu fanionul CLONE_NEWPID o singura data. Dupa ce a efectuat aceasta operaie, legatura sa simbolica /proc/pid/ns/pid_for_children va fi goala pana cand primul proces-copil este creat in spaiul de nume. Adoptarea proceselor-copil orfane Cand un proces-copil devine orfan, acesta este transferat catre procesul ,,init" din spaiul de nume PID al parintelui sau (cu excepia cazului in care unul dintre stramoii mai apropiai ai parintelui a utilizat comanda prctl(2) PR_SET_CHILD_SUBREAPER pentru a se marca drept colector al proceselor descendente orfane). Reinei ca, din cauza semanticii setns(2) i unshare(2) descrise mai sus, acesta poate fi procesul ,,init" din spaiul de nume PID care este parintele spaiului de nume PID al copilului, mai degraba decat procesul ,,init" din propriul spaiu de nume PID al procesului-copil. Compatibilitatea CLONE_NEWPID cu alte fanioane CLONE_* In versiunile curente de Linux, CLONE_NEWPID nu poate fi combinat cu CLONE_THREAD. Firele trebuie sa se afle in acelai spaiu de nume PID, astfel incat firele dintr-un proces sa ii poata trimite semnale intre ele. In mod similar, trebuie sa fie posibil sa se vada toate firele unui proces in sistemul de fiiere proc(5). In plus, daca doua fire de execuie se afla in spaii de nume PID diferite, ID-ul procesului care trimite un semnal nu poate fi codificat in mod semnificativ atunci cand se trimite un semnal (a se vedea descrierea tipului siginfo_t in sigaction(2)). Deoarece acesta este calculat atunci cand un semnal este pus la coada, o coada de semnale partajata de procese in mai multe spaii de nume PID ar impiedica acest lucru. In versiunile anterioare de Linux, CLONE_NEWPID era in plus interzis (euand cu eroarea EINVAL) in combinaie cu CLONE_SIGHAND (inainte de Linux 4.3), precum i cu CLONE_VM (inainte de Linux 3.12). Modificarile care au eliminat aceste restricii au fost, de asemenea, adaptate la nucleele stabile anterioare. /proc i spaiile de nume PID Un sistem de fiiere /proc afieaza (in directoarele /proc/pid) numai procesele vizibile in spaiul de nume PID al procesului care a efectuat montarea, chiar daca sistemul de fiiere /proc este vizualizat de procese din alte spaii de nume. Dupa crearea unui nou spaiu de nume PID, este util pentru procesul-copil sa ii schimbe directorul radacina i sa monteze o noua instana <> la /proc, astfel incat instrumente precum ps(1) sa funcioneze corect. Daca un nou spaiu de nume de montare este creat simultan prin includerea CLONE_NEWNS in argumentul fanioane al clone(2) sau unshare(2), atunci nu este necesar sa se schimbe directorul radacina: o noua instana <> poate fi montata direct pe /proc. Dintr-un shell, comanda pentru a monta /proc este: $ mount -t proc proc /proc Apelarea readlink(2) pe ruta /proc/self produce ID-ul procesului apelantului in spaiul de nume PID al montarii <> (adica spaiul de nume PID al procesului care a montat ,,procfs"). Acest lucru poate fi util in scopuri de introspecie, atunci cand un proces dorete sa ii descopere PID-ul in alte spaii de nume. Fiiere /proc /proc/sys/kernel/ns_last_pid (incepand cu Linux 3.3) Acest fiier (care este virtualizat pentru fiecare spaiu de nume PID) afieaza ultimul PID care a fost alocat in acest spaiu de nume PID. Atunci cand urmatorul PID este alocat, nucleul va cauta cel mai mic PID nealocat care este mai mare decat aceasta valoare, iar atunci cand acest fiier este citit ulterior, va afia acel PID. Acest fiier poate fi scris de catre un proces care are capacitatea CAP_SYS_ADMIN sau (incepand cu Linux 5.9) CAP_CHECKPOINT_RESTORE in spaiul de nume al utilizatorului care deine spaiul de nume PID. Acest lucru face posibila determinarea PID-ului care este alocat urmatorului proces care este creat in acest spaiu de nume PID. Diverse Atunci cand un ID de proces este transmis printr-un soclu de domeniu UNIX unui proces dintr-un spaiu de nume PID diferit (a se vedea descrierea SCM_CREDENTIALS in unix(7)), acesta este tradus in valoarea PID corespunzatoare in spaiul de nume PID al procesului receptor. STANDARDE Linux. EXEMPLE A se vedea user_namespaces(7). CONSULTAI I clone(2), reboot(2), setns(2), unshare(2), proc(5), capabilities(7), credentials(7), mount_namespaces(7), namespaces(7), user_namespaces(7), switch_root(8) TRADUCERE Traducerea in limba romana a acestui manual a fost facuta de Remus- Gabriel Chelu Aceasta traducere este documentaie gratuita; citii Licena publica generala GNU Versiunea 3 sau o versiune ulterioara cu privire la condiii privind drepturile de autor. NU se asuma NICIO RESPONSABILITATE. Daca gasii erori in traducerea acestui manual, va rugam sa trimitei un e-mail la . Pagini de manual de Linux 6.9.1 13 iunie 2024 pid_namespaces(7)