.\" -*- coding: UTF-8 -*- '\" t .\" Copyright (c) 1992 Drew Eckhardt , March 28, 1992 .\" and Copyright (c) Michael Kerrisk, 2001, 2002, 2005, 2013, 2019 .\" .\" SPDX-License-Identifier: GPL-1.0-or-later .\" .\" Modified by Michael Haardt .\" Modified 24 Jul 1993 by Rik Faith .\" Modified 21 Aug 1994 by Michael Chastain : .\" New man page (copied from 'fork.2'). .\" Modified 10 June 1995 by Andries Brouwer .\" Modified 25 April 1998 by Xavier Leroy .\" Modified 26 Jun 2001 by Michael Kerrisk .\" Mostly upgraded to Linux 2.4.x .\" Added prototype for sys_clone() plus description .\" Added CLONE_THREAD with a brief description of thread groups .\" Added CLONE_PARENT and revised entire page remove ambiguity .\" between "calling process" and "parent process" .\" Added CLONE_PTRACE and CLONE_VFORK .\" Added EPERM and EINVAL error codes .\" Renamed "__clone" to "clone" (which is the prototype in ) .\" various other minor tidy ups and clarifications. .\" Modified 26 Jun 2001 by Michael Kerrisk .\" Updated notes for 2.4.7+ behavior of CLONE_THREAD .\" Modified 15 Oct 2002 by Michael Kerrisk .\" Added description for CLONE_NEWNS, which was added in Linux 2.4.19 .\" Slightly rephrased, aeb. .\" Modified 1 Feb 2003 - added CLONE_SIGHAND restriction, aeb. .\" Modified 1 Jan 2004 - various updates, aeb .\" Modified 2004-09-10 - added CLONE_PARENT_SETTID etc. - aeb. .\" 2005-04-12, mtk, noted the PID caching behavior of NPTL's getpid() .\" wrapper under BUGS. .\" 2005-05-10, mtk, added CLONE_SYSVSEM, CLONE_UNTRACED, CLONE_STOPPED. .\" 2005-05-17, mtk, Substantially enhanced discussion of CLONE_THREAD. .\" 2008-11-18, mtk, order CLONE_* flags alphabetically .\" 2008-11-18, mtk, document CLONE_NEWPID .\" 2008-11-19, mtk, document CLONE_NEWUTS .\" 2008-11-19, mtk, document CLONE_NEWIPC .\" 2008-11-19, Jens Axboe, mtk, document CLONE_IO .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH clone 2 "15 czerwca 2024 r." "Linux man\-pages 6.9.1" .SH NAZWA clone, __clone2, clone3 \- tworzy proces potomny .SH BIBLIOTEKA Standardowa biblioteka C (\fIlibc\fP, \fI\-lc\fP) .SH SKŁADNIA .nf /* Prototyp funkcji opakowującej z glibc */ .P \fB#define _GNU_SOURCE\fP \fB#include \fP .P \fBint clone(int (*\fP\fIfn\fP\fB)(void *_Nullable), void *\fP\fIstack\fP\fB, int \fP\fIflags\fP\fB,\fP \fB void *_Nullable \fP\fIarg\fP\fB, ...\fP\fI \fP/*\fB pid_t *_Nullable \fP\fIparent_tid\fP\fB,\fP \fB void *_Nullable \fP\fItls\fP\fB,\fP \fB pid_t *_Nullable \fP\fIchild_tid\fP\fB \fP*/\fB );\fP .P /* Zob. UWAGI dot. prototypu surowego wywołania syst. clone() */ .P \fB#include \fP /* Definicja \fBstruct clone_args\fP */ \fB#include \fP /* Definicja stałych \fBCLONE_*\fP */ \fB#include \fP /* Definicja stałych \fBSYS_*\fP */ \fB#include \fP .P \fBlong syscall(SYS_clone3, struct clone_args *\fP\fIcl_args\fP\fB, size_t \fP\fIsize\fP\fB);\fP .fi .P \fIUwaga\fP: glibc nie udostępnia opakowania do \fBclone3\fP(), zatem wymagane jest użycie \fBsyscall\fP(2). .SH OPIS Niniejsze wywołania systemowe tworzą nowy proces (\[Bq]potomny\[rq]), w sposób podobny do \fBfork\fP(2). .P W przeciwieństwie do \fBfork\fP(2), te wywołania systemowe udostępniają precyzyjniejszą kontrolę wobec kontekstu wykonania, który jest dzielony między procesem wywołującym a procesem potomnym. Przykładowo, za pomocą niniejszych wywołań systemowych, wywołujący może kontrolować czy oba procesy dzielą wirtualną przestrzeń adresową, tablicę deskryptorów pliku i tablicę procedur obsługi sygnałów. Te wywołania systemowego umożliwiają również umieszczenie procesu potomnego w oddzielnych przestrzeniach nazw (zob. \fBnamespaces\fP(7)). .P Proszę zauważyć, że w niniejszym podręczniku systemowym \[Bq]proces wywołujący\[rq] odpowiada zwykle \[Bq]procesowy macierzystemu\[rq]. Proszę jednak sprawdzić opisy \fBCLONE_PARENT\fP i \fBCLONE_THREAD\fP niżej. .P Niniejsza strona podręcznika opisuje następujące interfejsy: .IP \[bu] 3 Funkcję opakowującą \fBclone\fP() z glibc i podległe wywołanie systemowe, w oparciu o które działa. Główna część podręcznika opisuje funkcję opakowującą; różnice w stosunku do surowego wywołania systemowego opisano bliżej końca. .IP \[bu] Nowsze wywołanie systemowe \fBclone3\fP(). .P .\" W pozostałej treści niniejszego podręcznika, pojęcie \[Bq]wywołanie clone\[rq] lub \[Bq]wywołanie klonowania\[rq] używane jest przy opisywaniu szczegółów odnoszących się do wszystkich tych interfejsów. .SS "Funkcja opakowująca clone()" Gdy proces potomny tworzony jest za pomocą funkcji opakowującej \fBclone\fP(), rozpoczyna on wykonanie od wywołania funkcji, na którą wskazuje argument \fIfn\fP (różni się to od \fBfork\fP(2), gdzie proces potomny kontynuuje wykonanie od miejsca wywołania \fBfork\fP(2)). Argument \fIarg\fP jest przekazywany jako argument do funkcji \fIfn\fP. .P Gdy funkcja \fIfn\fP(\fIarg\fP) powróci, proces potomny kończy działanie. Liczba całkowita zwrócona przez \fIfn\fP jest statusem zakończenia procesu potomnego. Proces potomny może również zakończyć się jawnie wołając \fBexit\fP(2) lub po otrzymaniu krytycznego sygnału. .P Argument \fIstack\fP określa położenie stosu używanego przez proces potomny. Ponieważ potomek i proces wywołujący mogą współdzielić pamięć, nie jest możliwe, aby proces potomny korzystał z tego samego stosu, co proces wywołujący. Proces wywołujący musi więc przydzielić obszar pamięci przeznaczony na stos potomka i przekazać wskaźnik do tego obszaru w \fBclone\fP. Stosy rosną w dół na wszystkich procesorach, na których działa Linux (z wyjątkiem procesorów HP PA), więc \fIstack\fP zazwyczaj wskazuje na najwyższy adres obszaru pamięci zarezerwowanego na stos potomka. Proszę zauważyć, że \fBclone\fP() nie zapewnia mechanizmu, w którym wywołujący mógłby poinformować jądro o wielkości obszaru stosu. .P .\" Pozostałe argumenty \fBclone\fP() opisano poniżej. .SS clone3() Wywołanie systemowe \fBclone3\fP() udostępnia nadzbiór funkcjonalności wobec starszego interfejsu \fBclone\fP(). Zawiera również wiele usprawnień API m.in: przestrzeń na dodatkowe bity znaczników, przejrzystszy podział stosowania różnych argumentów oraz możliwość określenia rozmiaru przestrzeni stosu procesu potomnego. .P Podobnie jak \fBfork\fP(2), \fBclone3\fP() powraca zarówno w procesie macierzystym, jak i potomnym. Zwraca 0 do procesu potomnego, natomiast procesowi macierzystemu zwraca PID procesu potomnego. .P Argumentem \fIcl_args\fP \fBclone3\fP() jest struktura w następującej postaci: .P .in +4n .EX struct clone_args { u64 flags; /* Maska bitowa znaczników */ u64 pidfd; /* Gdzie przechowywać deskryptor pliku PID (\fIint *\fP) */ u64 child_tid; /* Gdzie przechowywać TID p. potomnego, w pamięci p. potomnego (\fIpid_t *\fP) */ u64 parent_tid; /* Gdzie przechowywać TID, w pamięci procesu macierzystego (\fIpid_t *\fP) */ u64 exit_signal; /* Sygnał do dostarcz. przy zakończeniu procesu potomnego */ u64 stack; /* Wskaźnik do najniższych bajtów stosu */ u64 stack_size; /* Rozmiar stosu */ u64 tls; /* Położenie nowego TLS */ u64 set_tid; /* Wskaźnik do tablicy \fIpid_t\fP (od Linuksa 5.5) */ u64 set_tid_size; /* Liczba elementów w \fIset_tid\fP (od Linuksa 5.5) */ u64 cgroup; /* Deskryptor pliku docelowej gr. kontr. procesu potomnego (od Linuksa 5.7) */ }; .EE .in .P Argument \fIsize\fP dostarczany do \fBclone3\fP() powinien być zainicjowany z rozmiarem tej struktury (obecność argumentu \fIsize\fP pozwala na przyszłe poszerzanie struktury \fIclone_args\fP). .P Stos procesu potomnego podaje się za pomocą \fIcl_args.stack\fP, które wskazuje na najniższe bajty w przestrzeni stosu oraz za pomocą \fIcl_args.stack_size\fP, które określa rozmiar stosu w bajtach. W przypadku gdy poda się znacznik \fBCLONE_VM\fP (zob. niżej), stos musi być jawnie zaalokowany i określony. W przeciwnym przypadku, te dwa pola można podać jako NULL i 0, co powoduje używanie przez proces potomny tej samej przestrzeni stosu, z jakiej korzysta proces macierzysty (we własnej wirtualnej przestrzeni adresowej procesu potomnego). .P .\" Pozostałe pola argumentu \fIcl_args\fP opisano niżej. .SS "Równoważność pomiędzy argumentami clone() i clone3()" W odróżnieniu do starszego interfejsu \fBclone\fP(), którego argumenty są przekazywane pojedynczo, w nowszym interfejsie \fBclone3\fP() argumenty są łączone w strukturze \fIclone_args\fP pokazanej wyżej. Struktura pozwala na przekazanie nadzbioru informacji, przekazywanych za pomocą argumentów \fBclone\fP(). .P Poniższa tabela ukazuje równoważność pomiędzy argumentami \fBclone\fP() i polami w argumencie \fIclone_args\fP przekazywanym \fBclone3\fP(): .RS 4 .TS lb lb lb l l l li li l. clone() clone3() Uwagi pole \fIcl_args\fP flags & \[ti]0xff flags T{ Do większości znaczników; szczegóły niżej T} parent_tid pidfd Zob. CLONE_PIDFD child_tid child_tid Zob. CLONE_CHILD_SETTID parent_tid parent_tid Zob. CLONE_PARENT_SETTID flags & 0xff exit_signal stack stack \fI\-\-\-\fP stack_size tls tls Zob. CLONE_SETTLS \fI\-\-\-\fP set_tid Zob. niżej aby poznać szczegóły \fI\-\-\-\fP set_tid_size \fI\-\-\-\fP cgroup Zob. CLONE_INTO_CGROUP .TE .RE .\" .SS "Sygnał zakończenia potomka" .\" Gdy proces potomny zostanie zakończony, do rodzica może być wysłany sygnał. Sygnał zakończenia jest określany niższym bajtem \fIflags\fP (\fBclone\fP()) lub \fIcl_args.exit_signal\fP (\fBclone3\fP()). Jeśli określono inny sygnał niż \fBSIGCHLD\fP, to proces macierzysty musi podać opcję \fB__WALL\fP lub \fB__WCLONE\fP czekając na potomka w \fBwait\fP(2). Gdy sygnał nie zostanie określony (tj. podano zero), to proces macierzysty nie zostanie zawiadomiony o zakończeniu pracy potomka. .SS "Tablica set_tid" Domyślnie, jądro wybiera następny numer PID dla nowego procesu, w każdej przestrzeni nazw PID, w której jest on obecny. Przy tworzeniu procesu za pomocą \fBclone3\fP(), tablicę \fIset_tid\fP (dostępną od Linuksa 5.5) można użyć do wybrania konkretnych PID\-ów w niektórych lub we wszystkich przestrzeniach nazw PID, w których jest on obecny. Jeśli PID nowo tworzonego procesu ma być ustawiony tylko w bieżącej przestrzeni nazw PID lub w nowo tworzonej przestrzeni nazw PID (jeśli \fIflags\fP zawiera \fBCLONE_NEWPID\fP), to pierwszym elementem w tablicy \fIset_tid\fP musi być żądany PID, a \fIset_tid_size\fP musi wynosić 1. .P Jeśli PID nowo tworzonego procesu ma mieć określoną wartość w wielu przestrzeniach nazw PID, to tablica \fIset_tid\fP może zawierać wiele wpisów. Pierwszy wpis definiuje PID najbardziej zagnieżdżonej przestrzeni nazw PID, a każdy kolejny zawiera PID w odpowiadającej przestrzeni nazw PID przodka. Liczba przestrzeni nazw PID, w której PID ma być ustawiony, jest definiowana przez \fIset_tid_size\fP, które nie może być większe od liczby aktualnie zagnieżdżonych przestrzeni nazw. .P Aby utworzyć proces z następującymi PID\-ami w hierarchii przestrzeni nazw PID: .RS 4 .TS lb lb lb l l l. Poziom zagn. PID Żądany PID Uwagi 0 31496 Najbardziej zewnętrzna p. n. PID 1 42 2 7 Najbardziej wewnętrzna p. n. PID .TE .RE .P Należy ustawić tablicę na .P .in +4n .EX set_tid[0] = 7; set_tid[1] = 42; set_tid[2] = 31496; set_tid_size = 3; .EE .in .P Jeśli mają być określone jedynie PID\-y w dwóch najbardziej wewnętrznych przestrzeniach nazw PID, należy ustawić tablicę na: .P .in +4n .EX set_tid[0] = 7; set_tid[1] = 42; set_tid_size = 2; .EE .in .P PID w przestrzeni nazw PID poza dwoma najbardziej wewnętrznymi przestrzeniami nazw PID jest wybierany w ten sam sposób, jak inne PID\-y. .P .\" commit 124ea650d3072b005457faed69909221c2905a1f .\" commit 1caef81da05a84a40dbf02110e967ce6d1135ff6 Funkcja \fIset_tid\fP wymaga przywileju (ang. capability) \fBCAP_SYS_ADMIN\fP lub (od Linuksa 5.9) \fBCAP_CHECKPOINT_RESTORE\fP we wszystkich posiadanych przestrzeniach nazw użytkownika, w których PID ma być zmieniany. .P .\" Wywołujący mogą wybrać PID większy od 1 jedynie, gdy w danej przestrzeni nazw PID istnieje już proces \fBinit\fP (tj. proces z PID 1). W przeciwnym przypadku, wpis PID dla tej przestrzeni nazw musi wynosić 1. .SS "Maska znaczników" \fBclone\fP() i \fBclone3\fP() umożliwiają użycie maski bitowej znaczników, które modyfikują ich zachowanie i pozwalają wywołującemu na określenie tego, co ma być dzielone między procesem wywołującym a potomnym. Maska bitowa \[em] argument \fIflags\fP \fBclone\fP() lub pole \fIcl_args.flags\fP przekazywane do \fBclone3\fP() \[em] jest nazywana w pozostałem części niniejszego podręcznika maską \fIflags\fP. .P Maskę \fIflags\fP można podać jako sumę bitową (OR) zera lub więcej z poniższych zmiennych. Poza wskazanymi wyjątkami, znaczniki te są dostępne (i mają takie samo zastosowanie) w \fBclone\fP() i \fBclone3\fP(). .TP \fBCLONE_CHILD_CLEARTID\fP (od Linuksa 2.5.49) Czyści (zeruje) identyfikator wątku potomnego w położeniu, na które wskazuje \fIchild_tid\fP (\fBclone\fP()) lub \fIcl_args.child_tid\fP (\fBclone3\fP()) w pamięci potomka, gdy potomek istnieje i wybudza zatrzask (mutex) pod tym adresem. Adres można zmienić wywołaniem systemowym \fBset_tid_address\fP(2). Używane przez biblioteki związane z wątkami. .TP \fBCLONE_CHILD_SETTID\fP (od Linuksa 2.5.49) Przechowuje identyfikator wątku potomnego w położeniu, na które wskazuje \fIchild_tid\fP (\fBclone\fP()) lub \fIcl_args.child_tid\fP (\fBclone3\fP()) w pamięci potomka. Operacja przechowania kończy się przed zwróceniem kontroli przez wywołanie clone do przestrzeni użytkownika w procesie potomnym (proszę zauważyć, że operacja przechowania może nie zakończyć się przed powrotem przez wywołanie clone do procesu macierzystego, co ma znaczenie, jeśli używa się również znacznika \fBCLONE_VM\fP). .TP \fBCLONE_CLEAR_SIGHAND\fP (od Linuksa 5.5) .\" commit b612e5df4587c934bd056bf05f4a1deca4de4f75 Domyślnie, dyspozycje sygnału w wątku potomnym są takie same jak w wątku macierzystym. Przy podaniu tego znacznika, wszystkie sygnały, które są obsługiwane przez wątek macierzysty (i nie ustawione na \fBSIG_IGN\fP) są resetowane do swych domyślnych dyspozycji (\fBSIG_DFL\fP) w potomku. .IP Podanie tego znacznika razem z \fBCLONE_SIGHAND\fP jest bezsensowne i niedozwolone. .TP \fBCLONE_DETACHED\fP (historyczny) .\" added in Linux 2.5.32; removed in Linux 2.6.0-test4 Przez pewien czas (w trakcie serii rozwojowej Linuksa 2.5) istniał znacznik \fBCLONE_DETACHED\fP, który powodował nieotrzymywanie przez rodzica sygnału przy przerwaniu potomka. Ostatecznie, efekt tego znacznika został włączony do znacznika \fBCLONE_THREAD\fP i w momencie wydania Linuksa 2.6.0, znacznik już nie działał. Począwszy od Linuksa 2.6.2, potrzeba podawania tego znacznika razem z \fBCLONE_THREAD\fP zanikła. .IP Znacznik jest wciąż zdefiniowany, lecz z reguły jest ignorowany przy wywoływaniu \fBclone\fP(). Pewne wyjątki opisano przy znaczniku \fBCLONE_PIDFD\fP. .TP \fBCLONE_FILES\fP (od Linuksa 2.0) Jeśli \fBCLONE_FILES\fP będzie ustawione, to proces wywołujący i proces potomny będą współdzielić tablicę deskryptorów plików. Dowolny deskryptor pliku utworzony przez proces wywołujący, jak też przez proces potomny będzie obowiązywać również w drugim procesie. Podobnie, jeśli jeden z procesów zamknie deskryptor pliku lub zmieni stowarzyszone z nim znaczniki (za pomocą operacji \fBF_SETFD\fP \fBfcntl\fP(2)), będzie to obowiązywać również w drugim procesie. Jeśli proces dzielący tablicę deskryptorów pliku wywoła \fBexecve\fP(2), to jego tablica deskryptorów pliku zostanie zduplikowana (przestanie być współdzielona). .IP Jeśli \fBCLONE_FILES\fP nie zostanie ustawione, to proces potomny odziedziczy kopię wszystkich deskryptorów plików otwartych w procesie macierzystym w chwili wywołania klonowania. Kolejne operacja otwierające lub zamykające deskryptory pliku przeprowadzone później przez proces wywołujący lub przez proces potomny nie będą miały wpływu na drugi proces. Proszę jednak zauważyć, że zduplikowane deskryptory pliku w potomku odnoszą się tych samym opisów otwartego pliku (ODF) jak odpowiadające im deskryptory pliku w procesie wywołującym; będą zatem dzielić przesunięcie pliku i znaczniki statusu pliku (zob. \fBopen\fP(2)). .TP \fBCLONE_FS\fP (od Linuksa 2.0) Jeśli ustawione będzie \fBCLONE_FS\fP, to wywołujący i proces potomny będą współdzielić informacje o systemie plików. Informacje te obejmują katalog główny systemu plików, bieżący katalog roboczy i umaskę. Dowolne z wywołań \fBchroot\fP(2), \fBchdir\fP(2) lub \fBumask\fP(2) wykonane przez proces wywołujący lub proces potomny będzie wpływać również na drugi proces. .IP Jeśli \fBCLONE_FS\fP nie zostanie ustawione, to proces potomny będzie pracować na kopii informacji o systemie plików procesu wywołującego z chwili wywołania klonowania. Wywołania \fBchroot\fP(2), \fBchdir\fP(2) lub \fBumask\fP(2) wykonane później przez jeden z procesów nie będą mieć wpływu na drugi proces. .TP \fBCLONE_INTO_CGROUP\fP (od Linuksa 5.7) .\" commit ef2c41cf38a7559bbf91af42d5b6a4429db8fc68 Domyślnie, proces potomny jest umieszczany w tej samej grupie kontrolnej (cgroup) w wersji 2, jak rodzic. Znacznik \fBCLONE_INTO_CGROUP\fP pozwala na utworzenie procesu potomnego w innej grupie kontrolnej w wersji 2 (proszę zauważyć, że \fBCLONE_INTO_CGROUP\fP dotyczy tylko grup kontrolnych w wersji 2). .IP Aby umieścić proces potomny w innej grupie kontrolnej, wywołujący określa \fBCLONE_INTO_CGROUP\fP w \fIcl_args.flags\fP i przekazuje deskryptor pliku, który odnosi się do grupy kontrolnej w wersji 2 w polu \fIcl_args.cgroup\fP (ten deskryptor pliku można uzyskać otwierając katalog grupy kontrolnej v2, za pomocą znacznika \fBO_RDONLY\fP lub \fBO_PATH\fP). Proszę zauważyć, że obowiązują wszystkie zwykłe ograniczenia na umieszczanie procesu w grupie kontrolnej w wersji 2 (opisane w \fBcgroups\fP(7)). .IP Pośród możliwych zastosowań \fBCLONE_INTO_CGROUP\fP są następujące: .RS .IP \[bu] 3 Utworzenie procesu w grupie kontrolnej innej niż grupa kontrolna rodzica, umożliwia menedżerowi usług bezpośrednie tworzenie nowych usług w oddzielnych grupach kontrolnych. Eliminuje się w ten sposób narzut księgowania, który spowodowany byłby tworzeniem procesu potomnego pierwotnie w tej samej grupie kontrolnej co rodzic, a dopiero później przenoszenie go do docelowej grupy kontrolnej. Co więcej, tworzenie procesu potomnego od razu w docelowej grupie kontrolnej jest zdecydowanie tańsze, niż przenoszenie procesu potomnego do docelowej grupy kontrolnej dopiero po utworzeniu. .IP \[bu] Znacznik \fBCLONE_INTO_CGROUP\fP pozwala również na utworzenie zamrożonego procesu potomnego, przez utworzenie go w zamrożonej grupie kontrolnej (zob. \fBcgroups\fP(7) aby dowiedzieć się więcej o kontrolerze freezer). .IP \[bu] W przypadku aplikacji korzystających z wątków (lub choćby implementacji wątków korzystających z grup kontrolnych do limitowania poszczególnych wątków), da się ustanowić ustalony schemat grupy kontrolnej, przed utworzeniem każdego wątku bezpośrednio w jego docelowej grupie kontrolnej. .RE .TP \fBCLONE_IO\fP (od Linuksa 2.6.25) Jeśli \fBCLONE_IO\fP jest ustawiony, to nowy proces dzieli kontekst wejścia/wyjścia z procesem wywołującym. Jeśli znacznik nie jest ustawiony, to (jak przy \fBfork\fP(2)) nowy proces posiada swój kontekst wejścia/wyjścia. .IP .\" The following based on text from Jens Axboe .\" the anticipatory and CFQ scheduler .\" with CFQ and AS. Kontekst wejścia/wyjścia (we/wy) jest zakresem we/wy planisty dysku (tj. tym, co planista we/wy używa do planowania we/wy procesu). Jeśli procesy dzielą ten sam kontekst we/wy, to są traktowane jako jedność przez planistę we/wy. Muszą zatem dzielić czas dysku. W przypadku pewnych planistów we/wy, jeśli dwa procesy dzielą kontekst we/wy, to pozwala się im na przeplatanie dostępu do dysku. Jeśli wiele wątków korzysta z we/wy w imieniu jakiegoś procesu (np. \fBaio_read\fP(3)), to aby uzyskać lepszą wydajność wejścia/wyjścia, powinny korzystać z \fBCLONE_IO\fP. .IP Jeśli jądra nie skonfigurowano z opcją \fBCONFIG_BLOCK\fP, to ten znacznik nie daje żadnego efektu. .TP \fBCLONE_NEWCGROUP\fP (od Linuksa 4.6) Tworzy proces w nowej przestrzeni nazw cgroup. Jeśli znacznik nie jest ustawiony (jak w przypadku \fBfork\fP(2)), to proces jest tworzony w tej samej przestrzeni nazw cgroup, co proces wywołujący. .IP Więcej informacji o przestrzeniach nazw cgroup znajduje się w podręczniku \fBcgroup_namespaces\fP(7). .IP .\" Jedynie proces uprzywilejowany (\fBCAP_SYS_ADMIN\fP) może użyć \fBCLONE_NEWCGROUP\fP. .TP \fBCLONE_NEWIPC\fP (od Linuksa 2.6.19) Jeśli \fBCLONE_NEWIPC\fP jest ustawiony, to proces jest tworzony w nowej przestrzeni nazw IPC. Jeśli znacznik nie jest ustawiony (jak w przypadku \fBfork\fP(2)), to proces jest tworzony w tej samej przestrzeni nazw IPC, co proces wywołujący. .IP Więcej informacji o przestrzeniach nazw IPC znajduje się w podręczniku \fBipc_namespaces\fP(7). .IP Jedynie proces uprzywilejowany (\fBCAP_SYS_ADMIN\fP) może użyć \fBCLONE_NEWIPC\fP. Niniejszy znacznik nie może być podany razem z \fBCLONE_SYSVSEM\fP. .TP \fBCLONE_NEWNET\fP (od Linuksa 2.6.24) (Implementacja tej flagi została ukończona dopiero w okolicy Linuksa 2.6.29). .IP Jest \fBCLONE_NEWNET\fP jest ustawiony, to proces jest tworzony w nowej przestrzeni nazw sieci. Jeśli znacznik nie jest ustawiony (jak w przypadku \fBfork\fP(2)), to proces jest tworzony w tej samej przestrzeni nazw sieci, co proces wywołujący. .IP Więcej informacji o przestrzeniach nazw sieci znajduje się w podręczniku \fBnetwork_namespaces\fP(7). .IP Jedynie proces uprzywilejowany (\fBCAP_SYS_ADMIN\fP) może użyć \fBCLONE_NEWNET\fP. .TP \fBCLONE_NEWNS\fP (od Linuksa 2.4.19) Jeśli ustawiono \fBCLONE_NEWNS\fP, sklonowany potomek jest uruchamiany w nowej przestrzeni nazw montowań, inicjowanej jako kopia przestrzeni nazw rodzica. Jeśli nie ustawiono \fBCLONE_NEWNS\fP, to potomek istnieje w tej samej przestrzeni nazw montowań, co rodzic. .IP Więcej informacji o przestrzeniach nazw montowań znajduje się w podręcznikach \fBnamespaces\fP(7) i \fBmount_namespaces\fP(7). .IP .\" See https://lwn.net/Articles/543273/ Znacznik \fBCLONE_NEWNS\fP może zostać użyty jedynie przez proces uprzywilejowany (\fBCAP_SYS_ADMIN\fP). Zabronione jest podanie w tym samym wywołaniu klonowania zarówno \fBCLONE_NEWNS\fP, jak i \fBCLONE_FS\fP. .TP \fBCLONE_NEWPID\fP (od Linuksa 2.6.24) .\" This explanation draws a lot of details from .\" http://lwn.net/Articles/259217/ .\" Authors: Pavel Emelyanov .\" and Kir Kolyshkin .\" .\" The primary kernel commit is 30e49c263e36341b60b735cbef5ca37912549264 .\" Author: Pavel Emelyanov Jest \fBCLONE_NEWPID\fP jest ustawiony, to proces jest tworzony w nowej przestrzeni nazw PID. Jeśli znacznik nie jest ustawiony (jak w przypadku \fBfork\fP(2)), to proces jest tworzony w tej samej przestrzeni nazw PID, co proces wywołujący. .IP Więcej informacji o przestrzeniach nazw PID znajduje się w podręcznikach \fBnamespaces\fP(7) i \fBpid_namespaces\fP(7). .IP \fBCLONE_NEWPID\fP może zostać użyty jedynie przez proces uprzywilejowany (\fBCAP_SYS_ADMIN\fP). Nie można podać tego znacznika razem z \fBCLONE_THREAD\fP. .TP \fBCLONE_NEWUSER\fP (Flaga ta nabrała znaczenia dla \fBclone\fP() w Linuksie 2.6.23, bieżąca semantyka \fBclone\fP() pojawiła się w Linuksie 3.5, a ostatnie elementy dające pełną funkcjonalność przestrzeni nazw użytkownika ukończono w Linuksie 3.8). .IP Jest \fBCLONE_NEWUSER\fP jest ustawiony, to proces jest tworzony w nowej przestrzeni nazw użytkownika. Jeśli znacznik nie jest ustawiony (jak w przypadku \fBfork\fP(2)), to proces jest tworzony w tej samej przestrzeni nazw użytkownika, co proces wywołujący. .IP Więcej informacji o przestrzeniach nazw użytkownika znajduje się w podręcznikach \fBnamespaces\fP(7) i \fBuser_namespaces\fP(7). .IP .\" Before Linux 2.6.29, it appears that only CAP_SYS_ADMIN was needed Przed Linuksem 3.8, użycie \fBCLONE_NEWUSER\fP wymagało posiadania trzech przywilejów (ang. capabilities) przez wywołującego: \fBCAP_SYS_ADMIN\fP, \fBCAP_SETUID\fP i \fBCAP_SETGID\fP. Od Linuksa 3.8, do utworzenia przestrzeni nazw użytkownika nie są wymagane przywileje. .IP .\" commit e66eded8309ebf679d3d3c1f5820d1f2ca332c71 .\" https://lwn.net/Articles/543273/ .\" The fix actually went into Linux 3.9 and into Linux 3.8.3. However, user namespaces .\" were, for practical purposes, unusable in earlier Linux 3.8.x because of the .\" various filesystems that didn't support userns. Znacznika tego nie można podać razem z \fBCLONE_THREAD\fP lub \fBCLONE_PARENT\fP. Ze względów bezpieczeństwa, \fBCLONE_NEWUSER\fP nie można podać razem z \fBCLONE_FS\fP. .TP \fBCLONE_NEWUTS\fP (od Linuksa 2.6.19) Jest \fBCLONE_NEWUTS\fP jest ustawiony, to proces jest tworzony w nowej przestrzeni nazw UTS, której identyfikatory są inicjowane przez zduplikowanie identyfikatorów z przestrzeni nazw UTS procesu wywołującego. Jeśli znacznik nie jest ustawiony (jak w przypadku \fBfork\fP(2)), to proces jest tworzony w tej samej przestrzeni nazw UTS, co proces wywołujący. .IP Więcej informacji o przestrzeniach nazw UTS znajduje się w podręczniku \fButs_namespaces\fP(7). .IP Jedynie proces uprzywilejowany (\fBCAP_SYS_ADMIN\fP) może użyć \fBCLONE_NEWUTS\fP. .TP \fBCLONE_PARENT\fP (od Linuksa 2.3.12) Jeśli \fBCLONE_PARENT\fP będzie ustawione, to rodzic nowego procesu potomnego (zwrócony przez \fBgetppid\fP(2)) będzie ten sam, co dla procesu wywołującego. .IP Jeśli \fBCLONE_PARENT\fP nie zostanie ustawione, to (jak dla \fBfork\fP(2)) rodzicem potomka będzie proces wywołujący. .IP Należy zauważyć, że to proces macierzysty, zwracany przez \fBgetppid\fP(2), zostanie powiadomiony o zakończeniu pracy przez potomka, więc jeśli \fBCLONE_PARENT\fP będzie ustawione, to zawiadomiony zostanie rodzic procesu wywołującego, a nie sam proces wywołujący. .IP Znacznika \fBCLONE_PARENT\fP nie można użyć w wywołaniach klonowania przez globalny proces init (o PID 1 w pierwotnej przestrzeni nazw PID) oraz procesy init w innych przestrzeniach nazw PID. To ograniczenie zapobiega tworzeniu zakorzenionych w wielu miejscach drzew procesów oraz tworzeniu zombie w pierwotnej przestrzeni nazw, których nie da się dorżnąć (unreapable). .TP \fBCLONE_PARENT_SETTID\fP (od Linuksa 2.5.49) Przechowuje identyfikator wątku potomka w położeniu, na które wskazuje \fIparent_tid\fP (\fBclone\fP()) lub \fIcl_args.parent_tid\fP (\fBclone3\fP()) w pamięci rodzica (w Linuksie 2.5.32\-2.5.48 istniał znacznik \fBCLONE_SETTID\fP, który działał w ten sam sposób). Operacja przechowania kończy się, przed zwróceniem kontroli do przestrzeni użytkownika przez wywołanie klonowania. .TP \fBCLONE_PID\fP (od Linuksa 2.0 do Linuksa 2.5.15) Jeśli \fBCLONE_PID\fP jest ustawiony, to proces potomny jest tworzony z tym samym identyfikatorem jak proces wywołujący. Trudno wymyślić jego przydatne zastosowanie, poza hakowaniem systemu. Od Linuksa 2.3.21, ten znacznik mógł być podany tylko przez systemowy proces rozruchu (PID 0). Znacznik zupełnie zniknął ze źródeł jądra w Linuksie 2.5.16. Następnie jądro po cichu ignorowało ten bit, gdy był podany w masce \fIflags\fP. Znacznie później, ten sam bit użyto do znacznika \fBCLONE_PIDFD\fP. .TP \fBCLONE_PIDFD\fP (od Linuksa 5.2) .\" commit b3e5838252665ee4cfa76b82bdf1198dca81e5be Jeśli znacznik jest podany, to deskryptor pliku PID odnoszącego się do procesu potomnego jest alokowany i umieszczany w określonym położeniu pamięci rodzica. Na tym nowym deskryptorze pliku ustawiany jest znacznik zamknij\-przy\-wykonaniu. Deskryptory pliku PID można wykorzystać w celach opisanych w podręczniku \fBpidfd_open\fP(2). .RS .IP \[bu] 3 Jeśli korzysta się z \fBclone3\fP(), to deskryptor pliku PID jest umieszczany w położeniu, na które wskazuje \fIcl_args.pidfd\fP. .IP \[bu] Jeśli korzysta się z \fBclone\fP(), to deskryptor pliku PID jest umieszczany w położeniu, na które wskazuje \fIparent_tid\fP. Ponieważ argument \fIparent_tid\fP jest używany do zwrócenia deskryptora pliku PID, nie można użyć \fBCLONE_PIDFD\fP razem z \fBCLONE_PARENT_SETTID\fP przy wywoływaniu \fBclone\fP(). .RE .IP Nie da się obecnie korzystać z tego znacznika razem z \fBCLONE_THREAD\fP. Oznacza to, że proces identyfikowany przez deskryptor pliku PID będzie zawsze liderem grupy wątków. .IP Jeśli przestarzały znacznik \fBCLONE_DETACHED\fP poda się razem z \fBCLONE_PIDFD\fP przy wywoływaniu \fBclone\fP(), to zwracany jest błąd. Błąd występuje również jeśli poda się \fBCLONE_DETACHED\fP przy wywoływaniu \fBclone3\fP(). Zwracanie błędu zapewnia, że bit odnoszący się do \fBCLONE_DETACHED\fP może być w przyszłości użyty ponownie do następnych funkcji deskryptora pliku PID. .TP \fBCLONE_PTRACE\fP (od Linuksa 2.2) Jeśli zostanie podane \fBCLONE_PTRACE\fP, a proces wywołujący będzie śledzony, to śledzenie obejmie również potomka (zobacz \fBptrace\fP(2)). .TP \fBCLONE_SETTLS\fP (od Linuksa 2.5.32) Deskryptor TLS (Thread Local Storage \[em] pamięć lokalna wątku) jest ustawiony na \fItls\fP. .IP Interpretacja \fItls\fP i jego skutek zależy od architektury. Na x86, \fItls\fP jest interpretowane jako \fIstruct user_desc\ *\fP (zob. \fBset_thread_area\fP(2)). Na x86\-64 jest to nowa wartość, jaka ma być ustawiona w bazowym rejestrze %fs (zob. argument \fBARCH_SET_FS\fP do \fBarch_prctl\fP(2)). Na architekturach ze specjalnym rejestrem TLS, jest to nowa wartość tego rejestru. .IP Znacznik ten wymaga szczegółowej wiedzy i zwykle nie powinno się go używać poza bibliotekami implementującymi wątkowanie. .TP \fBCLONE_SIGHAND\fP (od Linuksa 2.0) Jeśli \fBCLONE_SIGHAND\fP będzie ustawione, to proces wywołujący i procesy potomne będą współdzielić tablicę programów obsługi sygnałów. Jeśli proces wywołujący lub proces potomny wywoła \fBsigaction\fP(2), aby zmienić zachowanie towarzyszące sygnałowi, zachowanie to zostanie zmienione również w drugim procesie. Jednakże, proces wywołujący i proces potomny wciąż będą posiadać osobne maski sygnałów i zestawy sygnałów oczekujących. Zatem jeden z nich może zablokować lub odblokować niektóre sygnały za pomocą \fBsigprocmask\fP(2) nie wpływając na drugi proces. .IP Jeśli \fBCLONE_SIGHAND\fP nie zostanie ustawione, to proces potomny odziedziczy kopię programów obsługi sygnałów od procesu wywołującego z chwili wywołania klonowania. Wywołania \fBsigaction\fP(2) przeprowadzone później przez jeden z procesów nie będą mieć wpływu na drugi proces. .IP .\" Precisely: Linux 2.6.0-test6 Od Linuksa 2.6.0, maska \fIflags\fP musi również zawierać \fBCLONE_VM\fP, jeśli podano \fBCLONE_SIGHAND\fP. .TP \fBCLONE_STOPPED\fP (od Linuksa 2.6.0) .\" Precisely: Linux 2.6.0-test2 Jeśli \fBCLONE_STOPPED\fP jest ustawione, to potomek jest początkowo zatrzymany (jakby otrzymał sygnał \fBSIGSTOP\fP) i musi być wznowiony sygnałem \fBSIGCONT\fP. .IP .\" glibc 2.8 removed this defn from bits/sched.h Znacznik był oznaczony jako \fIprzestarzały\fP od Linuksa 2.6.25 i został zupełnie \fIusunięty\fP w Linuksie 2.6.38. Od tego czasu jądro po cichu ignoruje go, nie wypisując błędu. Od Linuksa 4.6, ten sam bit służy znacznikowi \fBCLONE_NEWCGROUP\fP. .TP \fBCLONE_SYSVSEM\fP (od Linuksa 2.5.10) Jeśli ustawiony jest \fBCLONE_SYSVSEM\fP to potomek i proces wywołujący dzielą jedną listę wartości dostosowań semaforów Systemu V (\fIsemadj\fP; zob. \fBsemop\fP(2)). W tym przypadku wspólna lista zbiera wartości \fIsemadj\fP ze wszystkich procesów dzielących listę, a dostosowania semaforów są wykonywane tylko gdy ostatni proces dzielący listę zostanie zakończony (lub przestanie dzielić listę, za pomocą \fBunshare\fP(2)). Jeśli znacznik ten nie jest ustawiony, to potomek posiada oddzielną listę \fIsemadj\fP, która początkowo jest pusta. .TP \fBCLONE_THREAD\fP (od Linuksa 2.4.0) .\" Precisely: Linux 2.6.0-test8 Jeśli ustawiony jest \fBCLONE_THREAD\fP to potomek jest umieszczany w tej samej grupie wątków, co proces wywołujący. Aby dalsza część opisu \fBCLONE_THREAD\fP była bardziej przejrzysta, termin \[Bq]wątek\[rq] oznaczać będzie tu procesy w grupie wątków. .IP Grupy wątków zostały dodane w Linuksie 2.4 do obsługi wątków POSIX dla zbioru procesów współdzielących ten sam PID. Wewnętrznie, ten wspólny PID jest tzw. identyfikatorem grupy wątków (ang. thread group ID \[em] TGID) dla grupy wątków. Od Linuksa 2.4 wywołania \fBgetpid\fP(2) zwracają TGID wywołującego. .IP Wątki wewnątrz grupy można rozróżnić za pomocą ich unikatowego (w systemie) identyfikatora wątku (ang. thread ID \[em] TID). TID nowego wątku jest dostępny jako wynik funkcji zwracany do wywołującego, a sam wątek może uzyskać swój TID za pomocą \fBgettid\fP(2). .IP Gdy wywołanie clone ma miejsce bez podania \fBCLONE_THREAD\fP, to wynikowy wątek jest umieszczany w nowej grupie wątków, której TGID jest taki sam jak TID wątku. Wątek ten staje się \fIliderem\fP nowej grupy wątków. .IP Nowy wątek utworzony przy podaniu \fBCLONE_THREAD\fP ma ten sam proces macierzysty jak proces, który wykonał wywołanie klonowania (tj. jak \fBCLONE_PARENT\fP), tak więc wywołanie \fBgetppid\fP(2) zwróci tę samą wartość dla wszystkich wątków w grupie wątków. Gdy wątek z \fBCLONE_THREAD\fP zostanie zakończony, wątek który go utworzył nie otrzymuje sygnału \fBSIGCHLD\fP (ani innego sygnału przerwania); statusu takiego wątku nie da się również pozyskać za pomocą \fBwait\fP(2) (taki wątek jest nazywany \fIoddzielonym\fP \[em] ang. detached). .IP Po tym, jak wszystkie wątki w grupie wątków zakończą się, proces macierzysty grupy wątków otrzymuje sygnał \fBSIGCHLD\fP (lub inny sygnał przerwania). .IP Jeśli któryś z wątków w grupie wątków wykona \fBexecve\fP(2), to wszystkie wątki poza liderem grupy wątków są zakańczane i nowy program wykonywany jest przez lidera grupy wątków. .IP Jeśli jeden z wątków w grupie wątków tworzy potomka za pomocą \fBfork\fP(2), to każdy wątek w grupie może czekać (\fBwait\fP(2)) na tego potomka. .IP .\" Precisely: Linux 2.6.0-test6 Od Linuksa 2.5.35, maska \fIflags\fP musi zawierać również \fBCLONE_SIGHAND\fP jeśli podano \fBCLONE_THREAD\fP (i proszę zauważyć, że od Linuksa 2.6.0, \fBCLONE_SIGHAND\fP wymaga również zamieszczenia \fBCLONE_VM\fP). .IP Akcje i dyspozycje sygnałów mają znaczenie dla całego procesu: jeśli do wątku dostarczony zostanie nieobsłużony sygnał, to dotknie on (przerwie, zatrzyma, wznowi, ustawi ignorowanie) wszystkich członków grupy wątków. .IP Każdy wątek ma swoją maskę sygnałów, jak ustawianą przez \fBsigprocmask\fP(2). .IP Sygnał może być kierowany do procesu lub kierowany do wątku. Sygnał kierowany do procesu jest przeznaczony do grupy wątku (tj. TGID) i jest dostarczany do dowolnie wybranego wątku spośród tych, które nie blokują sygnału. Sygnał może być kierowany do procesu, ponieważ został wygenerowany przez jądro z powodów innych niż wyjątek sprzętowy, albo ponieważ został wysłany za pomocą \fBkill\fP(2) lub \fBsigqueue\fP(3). Sygnał kierowany do wątku jest przeznaczony (tj. dostarczany) do określonego wątku. Sygnał może być kierowany do wątku, ponieważ został wysłany za pomocą \fBtgkill\fP(2) lub \fBpthread_sigqueue\fP(3), albo ponieważ wątek wykonał instrukcję języka maszynowego, która wyzwoliła wyjątek sprzętowy (np. nieprawidłowy dostęp do pamięci wyzwalający \fBSIGSEGV\fP lub wyjątek zmiennoprzecinkowy wyzwalający \fBSIGFPE\fP). .IP Wywołanie do \fBsigpending\fP(2) zwraca sygnał, który jest ustawiany na sumę oczekującego sygnału skierowanego do procesu oraz sygnałów które są oczekujące dla wątku wywołującego. .IP Jeśli sygnał kierowany do procesu zostanie dostarczony do grupy wątków, a grupa ta ma zainstalowaną procedurę obsługi sygnału, to jest ona wywoływana w dokładnie jednym, dowolnie wybranym członku grupy wątków, który nie zablokował sygnału. Jeśli na zaakceptowanie tego samego sygnału za pomocą \fBsigwaitinfo\fP(2) czeka wiele wątków w grupie, to jądro wybierze w sposób dowolny jeden z wątków, który otrzyma sygnał. .TP \fBCLONE_UNTRACED\fP (od Linuksa 2.5.46) Jeśli podano \fBCLONE_UNTRACED\fP, to proces śledzący nie może wymusić \fBCLONE_PTRACE\fP na tym procesie potomnym. .TP \fBCLONE_VFORK\fP (od Linuksa 2.2) Jeśli \fBCLONE_VFORK\fP będzie ustawione, wykonywanie procesu wywołującego zostanie wstrzymane do chwili, gdy potomek zwolni swoją pamięć wirtualną za pomocą \fBexecve\fP(2) lub \fB_exit\fP(2) (jak w przypadku \fBvfork\fP(2)). .IP Jeśli \fBCLONE_VFORK\fP nie zostanie ustawione, wtedy zarówno proces wywołujący, jak i potomny podlegają po wywołaniu \fBclone\fP szeregowaniu zadań i aplikacja nie może zakładać, że ich wykonywanie będzie się odbywać w określonej kolejności. .TP \fBCLONE_VM\fP (od Linuksa 2.0) Jeśli \fBCLONE_VM\fP będzie ustawione, to proces wywołujący i potomny będą działać w tym samym obszarze pamięci. W szczególności, zapisy do pamięci wykonywane przez proces wywołujący lub przez proces potomny będą widoczne dla drugiego z procesów. Ponadto, dowolne mapowania pamięci i usunięcia mapowań wykonane przez jeden z tych procesów za pomocą \fBmmap\fP(2) lub \fBmunmap\fP(2) będą dotyczyć również drugiego procesu. .IP Jeśli \fBCLONE_VM\fP nie zostanie ustawione, to proces potomny będzie działać w kopii obszaru pamięci procesu wywołującego, wykonanej w chwili wywołania klonowania. Zapisy do pamięci oraz mapowania i usunięcia mapowań wykonane przez jeden z tych procesów nie będą dotyczyć drugiego z nich, tak jak w przypadku \fBfork\fP(2). .IP Jeśli podano znacznik \fBCLONE_VM\fP, a nie podano znacznika \fBCLONE_VFORK\fP to wszystkie alternatywne stosy sygnałów ustanowione przez \fBsigaltstack\fP(2) są czyszczone w procesie potomnym. .SH "WARTOŚĆ ZWRACANA" .\" gettid(2) returns current->pid; .\" getpid(2) returns current->tgid; Po pomyślnym zakończeniu, w wątku rodzica zwracany jest identyfikator wątku potomka. W wypadku błędu, w kontekście procesu wywołującego zwracane jest \-1, a proces potomny nie jest tworzony i ustawiane jest \fIerrno\fP wskazując błąd. .SH BŁĘDY .TP \fBEACCES\fP (tylko \fBclone3\fP()) W \fIcl_args.flags\fP podano \fBCLONE_INTO_CGROUP\fP, nie spełniono ograniczeń (opisanych w \fBcgroups\fP(7)), w odniesieniu do \fIcl_args.cgroup\fP, dotyczących umieszczania procesu potomnego w grupie kontrolnej w wersji 2. .TP \fBEAGAIN\fP Działa już zbyt wiele procesów; zob. \fBfork\fP(2). .TP \fBEBUSY\fP (tylko \fBclone3\fP()) W \fIcl_args.flags\fP podano \fBCLONE_INTO_CGROUP\fP, lecz deskryptor pliku podany w \fIcl_args.cgroup\fP odnosi się do grupy kontrolnej w wersji 2, w której włączony jest kontroler domeny. .TP \fBEEXIST\fP (tylko \fBclone3\fP()) Jeden (lub więcej) PID podany w \fIset_tid\fP już istnieje w odpowiedniej przestrzeni nazw PID. .TP \fBEINVAL\fP W masce \fIflags\fP podano jednocześnie \fBCLONE_SIGHAND\fP i \fBCLONE_CLEAR_SIGHAND\fP. .TP \fBEINVAL\fP .\" Precisely: Linux 2.6.0-test6 W masce \fIflags\fP podano \fBCLONE_SIGHAND\fP, lecz nie podano \fBCLONE_VM\fP (od Linuksa 2.6.0). .TP \fBEINVAL\fP .\" .TP .\" .B EINVAL .\" Precisely one of .\" .B CLONE_DETACHED .\" and .\" .B CLONE_THREAD .\" was specified. .\" (Since Linux 2.6.0-test6.) W masce \fIflags\fP podano \fBCLONE_THREAD\fP, lecz nie podano \fBCLONE_SIGHAND\fP (od Linuksa 2.5.35). .TP \fBEINVAL\fP W masce \fIflags\fP podano \fBCLONE_THREAD\fP, lecz bieżący proces użył uprzednio \fBunshare\fP(2) ze znacznikiem \fBCLONE_NEWPID\fP lub użył \fBsetns\fP(2) do ponownego związania się z przestrzenią nazw PID. .TP \fBEINVAL\fP .\" commit e66eded8309ebf679d3d3c1f5820d1f2ca332c71 W masce \fIflags\fP podano jednocześnie \fBCLONE_FS\fP i \fBCLONE_NEWNS\fP. .TP \fBEINVAL\fP (od Linuksa 3.9) W masce \fIflags\fP podano jednocześnie \fBCLONE_NEWUSER\fP i \fBCLONE_FS\fP. .TP \fBEINVAL\fP W masce \fIflags\fP podano jednocześnie \fBCLONE_NEWIPC\fP i \fBCLONE_SYSVSEM\fP. .TP \fBEINVAL\fP W masce \fIflags\fP podano jednocześnie \fBCLONE_FS\fP i \fBCLONE_NEWNS\fP. .TP \fBEINVAL\fP W masce \fIflags\fP podano jednocześnie \fBCLONE_FS\fP i \fBCLONE_NEWNS\fP. .TP \fBEINVAL\fP (od Linuksa 2.6.32) .\" commit 123be07b0b399670a7cc3d82fef0cb4f93ef885c Podano \fBCLONE_PARENT\fP, a wywołujący jest procesem init. .TP \fBEINVAL\fP Zwracane przez funkcję opakowującą \fBclone\fP() z glibc, gdy \fIfn\fP lub \fIstack\fP określono jako NULL. .TP \fBEINVAL\fP W masce \fIflags\fP podano \fBCLONE_NEWIPC\fP, lecz jądro nie zostało skonfigurowane z opcjami \fBCONFIG_SYSVIPC\fP i \fBCONFIG_IPC_NS\fP. .TP \fBEINVAL\fP W masce \fIflags\fP podano \fBCLONE_NEWNET\fP, lecz jądro nie zostało skonfigurowane z opcją \fBCONFIG_NET_NS\fP. .TP \fBEINVAL\fP W masce \fIflags\fP podano \fBCLONE_NEWPID\fP, lecz jądro nie zostało skonfigurowane z opcją \fBCONFIG_PID_NS\fP. .TP \fBEINVAL\fP W masce \fIflags\fP podano \fBCLONE_NEWUSER\fP, lecz jądro nie zostało skonfigurowane z opcją \fBCONFIG_USER_NS\fP. .TP \fBEINVAL\fP W masce \fIflags\fP podano \fBCLONE_NEWUTS\fP, lecz jądro nie zostało skonfigurowane z opcją \fBCONFIG_UTS_NS\fP. .TP \fBEINVAL\fP Stos \fIstack\fP nie jest wyrównany do odpowiedniej granicy na tej architekturze. Przykładowo na aarch64, \fIstack\fP musi być wielokrotnością 16. .TP \fBEINVAL\fP (tylko \fBclone3\fP()) W masce \fIflags\fP podano \fBCLONE_DETACHED\fP. .TP \fBEINVAL\fP (tylko \fBclone\fP()) W masce \fIflags\fP podano \fBCLONE_PIDFD\fP jednocześnie z \fBCLONE_DETACHED\fP. .TP \fBEINVAL\fP W masce \fIflags\fP podano \fBCLONE_PIDFD\fP jednocześnie z \fBCLONE_THREAD\fP. .TP \fBEINVAL\fP (tylko \fBclone\fP()) W masce \fIflags\fP podano \fBCLONE_PIDFD\fP jednocześnie z \fBCLONE_PARENT_SETTID\fP. .TP \fBEINVAL\fP (tylko \fBclone3\fP()) \fIset_tid_size\fP jest większy od liczby zagnieżdżonych przestrzeni nazw PID. .TP \fBEINVAL\fP (tylko \fBclone3\fP()) Jeden z PID\-ów podanych w \fIset_tid\fP był nieprawidłowy. .TP \fBEINVAL\fP (tylko \fBclone3\fP()) .\" commit 7f192e3cd316ba58c88dfa26796cf77789dd9872 W masce \fIflags\fP podano \fBCLONE_THREAD\fP lub \fBCLONE_PARENT\fP, lecz w \fIexit_signal\fP określono sygnał. .TP \fBEINVAL\fP (tylko AArch64, Linux 4.6 i wcześniejsze) \fIstack\fP nie był wyrównany do granicy 128\-bitów. .TP \fBENOMEM\fP Za mało pamięci aby przydzielić strukturę zadania dla procesu potomnego, lub aby skopiować niezbędne fragmenty kontekstu procesu wywołującego. .TP \fBENOSPC\fP (od Linuksa 3.7) .\" commit f2302505775fd13ba93f034206f1e2a587017929 W masce \fIflags\fP podano \fBCLONE_NEWPID\fP, lecz zostałby przekroczony limit zagnieżdżenia przestrzeni nazw PID; zob. \fBpid_namespaces\fP(7). .TP \fBENOSPC\fP (od Linuksa 4.9; wcześniej \fBEUSERS\fP) W masce \fIflags\fP podano \fBCLONE_NEWUSER\fP, a wywołanie przekroczyłoby limit liczby zagnieżdżonych przestrzeni nazw użytkownika. Zob. \fBuser_namespaces\fP(7). .IP Od Linuksa 3.11 do Linuksa 4.8, diagnozowanym w tym przypadku błędem był \fBEUSERS\fP. .TP \fBENOSPC\fP (od Linuksa 4.9) Jedna z wartości w masce \fIflags\fP określiła utworzenie nowej przestrzeni nazw użytkownika, lecz uczynienie tego, spowodowałoby przekroczenie limitu zdefiniowanego przez odpowiedni plik w \fI/proc/sys/user\fP. Więcej informacji znajduje się w podręczniku \fBnamespaces\fP(7). .TP \fBEOPNOTSUPP\fP (tylko \fBclone3\fP()) W \fIcl_args.flags\fP podano \fBCLONE_INTO_CGROUP\fP, lecz deskryptor pliku podany w \fIcl_args.cgroup\fP odnosi się do grupy kontrolnej w wersji 2, która jest w stanie \fIdomain invalid\fP. .TP \fBEPERM\fP \fBCLONE_NEWCGROUP\fP, \fBCLONE_NEWIPC\fP, \fBCLONE_NEWNET\fP, \fBCLONE_NEWNS\fP, \fBCLONE_NEWPID\fP lub \fBCLONE_NEWUTS\fP były określone przez proces nieuprzywilejowany (proces bez przywileju \fBCAP_SYS_ADMIN\fP). .TP \fBEPERM\fP \fBCLONE_PID\fP został podany przez proces inny niż proces 0 (błąd ten występował jedynie do Linuksa 2.5.15). .TP \fBEPERM\fP W masce \fIflags\fP podano \fBCLONE_NEWUSER\fP, lecz ani efektywny identyfikator użytkownika, ani efektywny identyfikator grupy wywołującego nie jest przypisany do przestrzeni nazw rodzica (zob. \fBuser_namespaces\fP(7)). .TP \fBEPERM\fP (od Linuksa 3.9) .\" commit 3151527ee007b73a0ebd296010f1c0454a919c7d .\" FIXME What is the rationale for this restriction? W masce \fIflags\fP podano \fBCLONE_NEWUSER\fP, a wywołujący znajduje się w środowisku chroot (tj. główny katalog wywołującego nie jest głównym katalogiem przestrzeni nazw montowań, w której rezyduje). .TP \fBEPERM\fP (tylko \fBclone3\fP()) \fIset_tid_size\fP był większy niż zero, a wywołujący nie ma przywileju \fBCAP_SYS_ADMIN\fP w jednej lub większej liczbie przestrzeni nazw użytkownika, które posiadają odpowiednie przestrzenie nazw PID. .TP \fBERESTARTNOINTR\fP (od Linuksa 2.6.17) .\" commit 4a2c7a7837da1b91468e50426066d988050e4d56 Wywołanie systemowe przerwano sygnałem i zostanie ono przeładowane (widać to tylko przy śledzeniu). .TP \fBEUSERS\fP (od Linuksa 3.11 do Linuksa 4.8) W masce \fIflags\fP podano \fBCLONE_NEWUSER\fP, a przekroczono by limit liczby zagnieżdżonych przestrzeni nazw użytkownika. Zob. opis błędu \fBENOSPC\fP powyżej. .SH WERSJE Funkcja opakowująca \fBclone\fP() z biblioteki glibc czyni pewne zmiany w pamięci, na którą wskazuje \fIstack\fP (zmiany wymagane do prawidłowego ustawienia stosu w stosunku do potomka) \fIprzed\fP przywołaniem wywołania systemowego \fBclone\fP(). Dlatego, w przypadkach gdy \fBclone\fP() służy do rekurencyjnego tworzenia potomków, nie należy używać bufora w stosie rodzica, jako stosu potomka. .P Na i386, nie należy wywoływać \fBclone\fP() za pomocą vsyscall; powinno się to robić bezpośrednio, poprzez \fIint $0x80\fP. .SS "Różnice biblioteki C/jądra" Surowe wywołanie systemowe \fBclone\fP() jest bliższe \fBfork\fP(2) w tym zakresie, że wykonanie procesu potomnego jest kontynuowane od miejsca wywołania. Dlatego argumenty \fIfn\fP i \fIarg\fP funkcji opakowującej \fBclone\fP() są pominięte. .P W odróżnienie od opakowania z glibc, surowe wywołanie systemowe \fBclone\fP() jako argument \fIstack\fP akceptuje NULL (a \fBclone3\fP() podobnie pozwala, aby \fIcl_args.stack\fP wynosiło NULL). W takim przypadku, potomek używa duplikatu stosu rodzica (jest to dokonywane za pomocą kopiowania\-przy\-zapisie, co zapewnia, że potomek otrzyma odrębne kopie stron stosu, gdy jeden z procesów zmodyfikuje stos). W tym przypadku, aby zapewnić poprawne działanie, nie powinno się podawać opcji \fBCLONE_VM\fP (jeśli potomek \fIwspółdzieli\fP pamięć z rodzicem ze względu na znacznik \fBCLONE_VM\fP, to nie zachodzi duplikacja z kopiowaniem\-przy\-zapisie, co prawdopodobnie doprowadzi do chaotycznych rezultatów). .P Kolejność argumentów również różni się w surowym wywołaniu systemowym, występuje także zmienność argumentów w zależności od architektury, zgodnie z poniższym opisem. .P Interfejsem surowego wywołania systemowego na x86\-64 i niektórych innych architekturach (w tym sh, tile i alpha) jest: .P .in +4n .EX \fBlong clone(unsigned long \fP\fIflags\fP\fB, void *\fP\fIstack\fP\fB,\fP \fB int *\fP\fIparent_tid\fP\fB, int *\fP\fIchild_tid\fP\fB,\fP \fB unsigned long \fP\fItls\fP\fB);\fP .EE .in .P .\" CONFIG_CLONE_BACKWARDS Na x86\-32 i wielu innych popularnych architekturach (w tym score, ARM, ARM 64, PA\-RISC, arc, Power PC, xtensa i MIPS), kolejność dwóch ostatnich argumentów jest zamieniona: .P .in +4n .EX \fBlong clone(unsigned long \fP\fIflags\fP\fB, void *\fP\fIstack\fP\fB,\fP \fB int *\fP\fIparent_tid\fP\fB, unsigned long \fP\fItls\fP\fB,\fP \fB int *\fP\fIchild_tid\fP\fB);\fP .EE .in .P .\" CONFIG_CLONE_BACKWARDS2 Na architekturach cris i s390, kolejność pierwszych dwóch argumentów jest zamieniona: .P .in +4n .EX \fBlong clone(void *\fP\fIstack\fP\fB, unsigned long \fP\fIflags\fP\fB,\fP \fB int *\fP\fIparent_tid\fP\fB, int *\fP\fIchild_tid\fP\fB,\fP \fB unsigned long \fP\fItls\fP\fB);\fP .EE .in .P .\" CONFIG_CLONE_BACKWARDS3 Na architekturze microblaze występuje dodatkowy argument: .P .in +4n .EX \fBlong clone(unsigned long \fP\fIflags\fP\fB, void *\fP\fIstack\fP\fB,\fP \fB int \fP\fIstack_size\fP\fB,\fP /* Rozmiar stosu */ \fB int *\fP\fIparent_tid\fP\fB, int *\fP\fIchild_tid\fP\fB,\fP \fB unsigned long \fP\fItls\fP\fB);\fP .EE .in .\" .SS "blackfin, m68k i sparc" .\" Mike Frysinger noted in a 2013 mail: .\" these arches don't define __ARCH_WANT_SYS_CLONE: .\" blackfin ia64 m68k sparc Konwencje przekazywania argumentów na blackfin, m68k i sparc są odmienne od powyższych opisów. Więcej szczegółów w źródle jądra (i glibc). .SS ia64 Na ia64 używany jest inny interfejs: .P .in +4n .EX \fBint __clone2(int (*\fP\fIfn\fP\fB)(void *),\fP \fB void *\fP\fIstack_base\fP\fB, size_t \fP\fIstack_size\fP\fB,\fP \fB int \fP\fIflags\fP\fB, void *\fP\fIarg\fP\fB, ...\fP \fB /* pid_t *\fP\fIparent_tid\fP\fB, struct user_desc *\fP\fItls\fP\fB,\fP \fB pid_t *\fP\fIchild_tid\fP\fB */ );\fP .EE .in .P Powyższy prototyp jest do funkcji opakowującej z glibc; jeśli chodzi o samo wywołanie systemowe, jego prototyp może być opisany w sposób następujący (jest identyczny do prototypu \fBclone\fP() na microblaze): .P .in +4n .EX \fBlong clone2(unsigned long \fP\fIflags\fP\fB, void *\fP\fIstack_base\fP\fB,\fP \fB int \fP\fIstack_size\fP\fB,\fP /* Rozmiar stosu */ \fB int *\fP\fIparent_tid\fP\fB, int *\fP\fIchild_tid\fP\fB,\fP \fB unsigned long \fP\fItls\fP\fB);\fP .EE .in .P \fB__clone2\fP() działa w ten sam sposób co \fBclone\fP() z tym wyjątkiem, że \fIstack_base\fP wskazuje na najniższy adres przestrzeni stosu potomka, a \fIstack_size\fP określa rozmiar stosu, na który wskazuje \fIstack_base\fP. .SH STANDARDY Linux. .SH HISTORIA .TP \fBclone3\fP() .\" There is no entry for .\" .BR clone () .\" in libc5. .\" glibc2 provides .\" .BR clone () .\" as described in this manual page. Linux 5.3. .SS "Linux 2.4 i wcześniejsze" W serii Linuksa 2.4.x, \fBCLONE_THREAD\fP zwykle nie czyniło rodzicem nowego wątku rodzica procesu wywołującego. Jednak od Linuksa 2.4.7 do Linuksa 2.4.18 znacznik \fBCLONE_THREAD\fP implikował znacznik \fBCLONE_PARENT\fP (jak ma to miejsce od Linuksa 2.6.0). .P W Linuksie 2.4 i wcześniejszych \fBclone\fP() nie przyjmowało argumentów \fIparent_tid\fP, \fItls\fP ani \fIchild_tid\fP. .SH UWAGI Jednym z zastosowań tych wywołań systemowych jest implementacja wątków: zarządzanie wieloma przepływami kontroli w programie, które działają równolegle we współdzielonej przestrzeni adresowej. .P Wywołanie systemowe \fBkcmp\fP(2) może posłużyć do sprawdzenia, czy dwa procesy współdzielą różne zasoby, takie jak tablica deskryptorów pliku, operacje cofnięć semaforów Systemu V lub wirtualną przestrzeń adresową. .P Uchwyty zarejestrowane przy pomocy \fBpthread_atfork\fP(3) nie są wykonywane przy wywołaniu klonowania. .SH USTERKI Biblioteka GNU C w wersjach od 2.3.4 do 2.24 włącznie, zawierała funkcję opakowującą \fBgetpid\fP(2), która przeprowadzała buforowanie PID\-ów. To buforowanie zależało od obsługi opakowania \fBclone\fP() z glibc, jednak ograniczenia w implementacji powodowały, że w niektórych przypadkach bufor ten nie był aktualny. W szczególności, jeśli do potomka dostarczano sygnał od razu po wywołaniu \fBclone\fP(), to wywołanie \fBgetpid\fP(2) w procedurze obsługi sygnału mogło zwrócić PID procesu wywołującego (\[Bq]rodzica\[rq]), jeśli opakowanie clone nie miało jeszcze szansy zaktualizowania bufora PID w potomku (ten opis ignoruje sytuację, gdy potomka utworzono za pomocą \fBCLONE_THREAD\fP; wówczas \fBgetpid\fP(2) \fIpowinno\fP zwracać tę samą wartość w potomku jak w procesie wywołującym \fBclone\fP(), ponieważ wywołujący i potomek znajdują się w tej samej grupie wątków. Problem nieaktualnego bufora nie występuje również, gdy argument \fIflags\fP zawiera \fBCLONE_VM\fP). Do dotarcia do prawdziwego PID, trzeba było czasem użyć kodu takiego jak poniższy: .P .in +4n .EX #include \& pid_t mypid; \& mypid = syscall(SYS_getpid); .EE .in .\" See also the following bug reports .\" https://bugzilla.redhat.com/show_bug.cgi?id=417521 .\" http://sourceware.org/bugzilla/show_bug.cgi?id=6910 .P Ze względu na kłopot z nieaktualnym buforem i inne problemy opisane w \fBgetpid\fP(2), funkcjonalność buforowania PID\-ów usunięto w glibc 2.25. .SH PRZYKŁADY Poniższy program demonstruje użycie \fBclone\fP() do utworzenia procesu potomnego, który wykonuje się w oddzielnej przestrzeni nazw UTS. Potomek zmienia nazwę stacji w swojej przestrzeni nazw UTS. Rodzic i potomek wyświetlają następnie systemową nazwę stacji, przez co widać, że różni się ona w przestrzeniach nazw UTS rodzica i potomka. Przykład użycia tego programu znajduje się w podręczniku \fBsetns\fP(2). .P W programie przykładowym pamięć, która ma być użyta do stosu potomka, przydzielamy za pomocą \fBmmap\fP(2), zamiast \fBmalloc\fP(3), z następujących powodów: .IP \[bu] 3 \fBmmap\fP(2) przydziela blok pamięci zaczynający się na granicy strony i będący wielokrotnością rozmiaru strony. Przydaje się to, gdy chcemy ustawić ochronę strony (stronę z ochroną \fBPROT_NONE\fP) na końcu stosu, za pomocą \fBmprotect\fP(2). .IP \[bu] Możemy podać znacznik \fBMAP_STACK\fP, aby zażądać mapowania, które jest odpowiednie do stosu. W tej chwili znacznik ten nie daje efektu na Linuksie, ale istnieje i działa na niektórych innych systemach, dlatego należy go podać ze względu na przenośność. .SS "Kod źródłowy programu" .\" SRC BEGIN (clone.c) .EX #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include \& static int /* Start function for cloned child */ childFunc(void *arg) { struct utsname uts; \& /* Change hostname in UTS namespace of child. */ \& if (sethostname(arg, strlen(arg)) == \-1) err(EXIT_FAILURE, "sethostname"); \& /* Retrieve and display hostname. */ \& if (uname(&uts) == \-1) err(EXIT_FAILURE, "uname"); printf("uts.nodename in child: %s\[rs]n", uts.nodename); \& /* Keep the namespace open for a while, by sleeping. This allows some experimentation\-\-for example, another process might join the namespace. */ \& sleep(200); \& return 0; /* Child terminates now */ } \& #define STACK_SIZE (1024 * 1024) /* Stack size for cloned child */ \& int main(int argc, char *argv[]) { char *stack; /* Start of stack buffer */ char *stackTop; /* End of stack buffer */ pid_t pid; struct utsname uts; \& if (argc < 2) { fprintf(stderr, "Usage: %s \[rs]n", argv[0]); exit(EXIT_SUCCESS); } \& /* Allocate memory to be used for the stack of the child. */ \& stack = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, \-1, 0); if (stack == MAP_FAILED) err(EXIT_FAILURE, "mmap"); \& stackTop = stack + STACK_SIZE; /* Assume stack grows downward */ \& /* Create child that has its own UTS namespace; child commences execution in childFunc(). */ \& pid = clone(childFunc, stackTop, CLONE_NEWUTS | SIGCHLD, argv[1]); if (pid == \-1) err(EXIT_FAILURE, "clone"); printf("clone() returned %jd\[rs]n", (intmax_t) pid); \& /* Parent falls through to here */ \& sleep(1); /* Give child time to change its hostname */ \& /* Display hostname in parent\[aq]s UTS namespace. This will be different from hostname in child\[aq]s UTS namespace. */ \& if (uname(&uts) == \-1) err(EXIT_FAILURE, "uname"); printf("uts.nodename in parent: %s\[rs]n", uts.nodename); \& if (waitpid(pid, NULL, 0) == \-1) /* Wait for child */ err(EXIT_FAILURE, "waitpid"); printf("child has terminated\[rs]n"); \& exit(EXIT_SUCCESS); } .EE .\" SRC END .SH "ZOBACZ TAKŻE" \fBfork\fP(2), \fBfutex\fP(2), \fBgetpid\fP(2), \fBgettid\fP(2), \fBkcmp\fP(2), \fBmmap\fP(2), \fBpidfd_open\fP(2), \fBset_thread_area\fP(2), \fBset_tid_address\fP(2), \fBsetns\fP(2), \fBtkill\fP(2), \fBunshare\fP(2), \fBwait\fP(2), \fBcapabilities\fP(7), \fBnamespaces\fP(7), \fBpthreads\fP(7) .PP .SH TŁUMACZENIE Autorami polskiego tłumaczenia niniejszej strony podręcznika są: Przemek Borys , Andrzej Krzysztofowicz i Michał Kułach . .PP Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z .UR https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License w wersji 3 .UE lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI. .PP Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej .MT manpages-pl-list@lists.sourceforge.net .ME .