Co dokładnie robi init?


43

Tworzę dystrybucję Linuksa i teraz potrzebuję programu init. Potrafię dobrze napisać c-c i wiem trochę o Linuksie (niewiele, ale używam arch-linuxa do programowania od 4 lat), więc pomyślałem, że powinienem spróbować napisać własny skrypt skryptowy w C. tylko zastanawiam się, jakie zadania wykonuje init, aby skonfigurować system dla prostej powłoki? (Kiedy pytam „co robi init?”, Wiem, czym jest init i do czego służy. Po prostu nie wiem, jakie zadania wykonuje.)

Nie potrzebuję kodu i prawdopodobnie nie trzeba nawet podstawowych komend, ale ja nie potrzebuję kolejność, w jakiej są one uruchamiane w.


1
Możesz używać dowolnego interpretera dla skryptów inicjujących w stylu SysV, w tym Perla, awk, bash, (t) csh, natywnych plików binarnych, ... Bash jest zwykle używany, ponieważ jest praktycznie gwarantowany, że jest dostępny w systemie, w którym takie skrypty są wdrażane w odpowiednim punkcie procesu rozruchu, nie dlatego, że istnieje pewne sprzężenie między SysVinit i bash. SysVinit definiuje umowę, a każdy skrypt może dowolnie realizować tę umowę w dowolny sposób, który uzna za odpowiedni.
CVn

Odpowiedzi:


53

System 5 initopowie ci tylko niewielką część historii.

Istnieje rodzaj krótkowzroczności, która wpływa na świat Linuksa. Ludzie myślą, że używają czegoś o nazwie „System 5 init”, i to jest zarówno tradycyjne, jak i najlepsze miejsce na start. W rzeczywistości tak nie jest.

Na początek tradycja nie jest tym, co mówią tacy ludzie. System 5 initi System 5 rcdatują się na AT&T UNIX System 5, który był prawie tak daleko od pierwszego UNIX-a, jak obecnie (powiedzmy) po pierwszej wersji Linux-Mandrake.

1st Edition UNIX miał tylko init. Nie miał rc. Język asemblerowy 1. edycji init( którego kod został przywrócony i udostępniony przez Warren Toomey i in. ) Bezpośrednio spawnował i odradzał 12 gettyprocesów, montował 3 wbudowane systemy plików z wbudowanej tabeli i bezpośrednio uruchamiał program z katalogu domowego użytkownik o nazwie mel. gettyStół był również bezpośrednio na obrazie programu.

Minęła kolejna dekada po UNIX System 5, kiedy pojawił się tak zwany „tradycyjny” system inicjujący Linuksa. W 1992 r. Miquel van Smoorenburg (ponownie) napisał Linux init+ rci powiązane z nim narzędzia, które ludzie nazywają teraz „Systemem 5 init”, mimo że tak naprawdę nie jest to oprogramowanie z systemu UNIX System 5 (i to nie tylko init).

System 5 init/ rcnie jest najlepszym miejscem do rozpoczęcia, a nawet jeśli dodaje się wiedzę o systemd, która nie obejmuje połowy tego, co trzeba wiedzieć. Wiele pracy poświęcono projektowaniu systemu init (dla Linuksa i BSD), co miało miejsce w ciągu ostatnich dwóch dekad. Omawiano, podejmowano, projektowano, wdrażano i praktykowano wszelkiego rodzaju decyzje inżynierskie. Komercyjne Unices też wiele zrobiły.

Istniejące systemy do nauki i uczenia się od

Oto niepełna lista niektórych głównych systemów inicjujących innych niż te dwa oraz jeden lub dwa z ich (kilku) istotnych punktów:

  • Finał Joachima Nilssona podążył drogą użycia pliku konfiguracyjnego bardziej czytelnego dla człowieka.
  • Minit Felixa von Leitnera wybrał między innymi system konfiguracji systemu plików - system baz danych, małe ślady pamięci oraz zależności start / stop init.
  • Runit Gerrita Pape'a był zgodny z tym, co wcześniej opisałem jako po prostu spawnowanie czterech skryptów powłoki .
  • Celem InitNG było posiadanie zależności, nazwanych celów, wielu plików konfiguracyjnych i bardziej elastycznej składni konfiguracji z całym ładowaniem więcej ustawień dla procesów potomnych.
  • upstart zdecydował się na całkowitą przeprojektowanie, modelując system nie jako usługi i współzależności, ale jako wywołane przez nie zdarzenia i zadania.
  • Projekt nosh obejmuje wypchnięcie całego zarządzania usługami (w tym nawet gettyspawnowanie i zbieranie zombie) do osobnego menedżera usług oraz po prostu obsługę specyficznych dla systemu operacyjnego urządzeń „API” / dowiązań symbolicznych / katalogów i zdarzeń systemowych.
  • sinit jest bardzo prostym inicjatorem . Wykonuje /bin/rc.initzadanie, którego zadaniem jest uruchamianie programów, montowanie systemu plików itp. W tym celu można użyć czegoś takiego jak minirc .

Co więcej, około 10 lat temu, nie było dyskusji wśród daemontools użytkowników i innych z użyciem svscanjako procesu nr 1, która doprowadziła do projektów takich jak Paul Jarc na svscan jako proces 1 badaniu , pomysłów Gerrit Pape jest i Laurent Bercot na svscan jako proces 1 .

Co prowadzi nas do tego, co robią programy nr 1.

Co robią programy nr 1

Pojęcia tego, co proces „1” ma wykonać, są z natury subiektywne. Znaczącym obiektywnym kryterium projektowym jest to, co musi wykonać proces nr 1 . Jądro nakłada na niego kilka wymagań. I zawsze ma do czynienia z różnymi rzeczami specyficznymi dla systemu operacyjnego. Jeśli chodzi o to, co tradycyjnie zrobił proces nr 1 , to nie jesteśmy na tym minimum i nigdy tak naprawdę nie byliśmy.

Jest kilka rzeczy, których różne jądra systemu operacyjnego i inne programy wymagają od procesu nr 1, z których po prostu nie można uciec.

Ludzie powiedzą ci, że fork()tworzenie rzeczy i działanie jako rodzic osieroconych procesów jest podstawową funkcją procesu nr 1. Jak na ironię, to nieprawda. Radzenie sobie z osieroconymi procesami jest (z najnowszymi jądrami Linuksa, jak wyjaśniono na https://unix.stackexchange.com/a/177361/5132 ) częścią systemu, który można w dużej mierze uwzględnić poza procesem nr 1 w innych procesach, takich jak dedykowany kierownik serwisu . Wszystkie są menedżerami usług, które działają poza procesem nr 1:

Podobnie, jak wyjaśniono na https://superuser.com/a/888936/38062 , cały /dev/initctlpomysł nie musi znajdować się w pobliżu procesu nr 1. Jak na ironię, jest to wysoce scentralizowany system, który pokazuje, że można go usunąć z procesu nr 1.

Odwrotnie, obowiązkowe rzeczy dla init, że ludzie zwykle zapomnieć w ich off-the-top-of-the-head wzorów, są rzeczy, takich jak obsługa SIGINT, SIGPWR, SIGWINCH, i tak dalej wysyłane z jądra i przyjmując różne żądania zmiany stanu systemu wysłane z programów, które „wiedzą”, że pewne sygnały do ​​przetworzenia nr 1 oznaczają pewne rzeczy. (Na przykład: Jak wyjaśniono na https://unix.stackexchange.com/a/196471/5132 , zestawy narzędzi BSD „wiedzą”, że SIGUSR1mają określone znaczenie.)

Istnieją również jednorazowe zadania inicjalizacji i finalizacji, których nie można uciec lub które będą bardzo cierpieć z powodu niewykonania, takie jak montowanie systemów plików „API” lub opróżnianie pamięci podręcznej systemu plików.

Podstawy radzenia sobie z systemami plików „API” niewiele różnią się od działania initROM 1. edycja UNIX: Jeden zawiera listę informacji zapisanych w programie i po prostu mount()wszystkie wpisy na liście. Znajdziesz ten mechanizm w systemach tak różnorodnych jak BSD (sic!) init, Od nosh system-manager, do systemd.

„skonfiguruj system dla prostej powłoki”

Jak zauważyłeś, init=/bin/shnie można zamontować systemów plików „API”, ulega awarii w nieładny sposób bez opróżniania pamięci podręcznej, gdy jeden typ exit( https://unix.stackexchange.com/a/195978/5132 ) i ogólnie pozostawia to (super) użytkownikowi, aby ręcznie wykonał czynności, które sprawiają, że system jest minimalnie użyteczny.

Aby zobaczyć, co tak naprawdę nie ma innego wyjścia, jak zrobić w programach procesu nr 1, a tym samym ustawić dobry kurs dla podanego celu projektowego, najlepszym rozwiązaniem jest przyjrzenie się nakładaniu się działania Runit Gerrita Pape'a, Felixa von Minit Leitnera i system-managerprogram z pakietu nosh. Dwie poprzednie pokazują dwie próby bycia minimalistą, ale wciąż radzą sobie z rzeczami, których nie można uniknąć.

Ta ostatnia jest użyteczna, sugeruję, ze względu na obszerne ręczne wprowadzanie do system-managerprogramu, który szczegółowo opisuje, jakie systemy plików „API” są zamontowane, jakie zadania inicjujące są uruchamiane i jakie sygnały są obsługiwane; w systemie, który z założenia ma menedżera systemu, po prostu spawnują trzy inne rzeczy (menedżer usług, towarzyszący rejestrator i program do uruchamiania zmian stanu) i robią tylko nieuniknione w procesie nr 1.


3
Świetna odpowiedź i bardzo pouczająca. Ale zastanawiam się, gdzie na tym dużym obrazie jest OSX launchd. Czasami ludzie całkowicie zapominają, że OSX jest (świetnym) członkiem dużej rodziny * nix.
DavAlPi

4

System V init na Debianie (istnieją inne warianty i odmiany) wykonuje następujące czynności:

  • Wchodząc na poziom działania, wywołuje skrypty w /etc/rcX.d/S*kolejności alfanumerycznej, gdzie Xjest poziom działania. Te skrypty powinny skonfigurować poziom działania. Typowa instalacja to uruchamianie demonów i wykonywanie zadań konfiguracji dla tego poziomu uruchamiania. Jest to jednorazowa czynność wykonywana podczas wchodzenia na poziom uruchamiania.
  • Na poziomie uruchomienia uruchamia demony wymienione w liście /etc/inittabjako wymagające działania podczas tego poziomu uruchamiania. Jeśli te demony przestaną działać, uruchomi je ponownie. Chociaż możesz mieć dowolnego demona, którym chcesz zarządzać, potrzebujesz initco najmniej kilku getty, abyś mógł się zalogować. gettyKończy się po zakończeniu logowania, a następnie inituruchamia go ponownie, zapewniając ponowne logowanie.
    • Jeśli demon uruchamia się zbyt wiele razy w zbyt krótkim czasie, przestaje próbować go ponownie uruchomić na chwilę.
    • Tylko dlatego, że coś zostało uruchomione przez skrypty startowe podczas wchodzenia na poziom uruchamiania, nie powoduje initautomatycznie próby utrzymania go w działaniu. Musisz to określić osobno w /etc/inittab.
  • Podczas wychodzenia z poziomu uruchamiania wywołuje skrypty w /etc/rcX.d/K*kolejności alfanumerycznej, gdzie Xjest poziom działania. Sposobem na wdrożenie zamknięcia lub ponownego uruchomienia jest zdefiniowanie poziomu uruchamiania dla tych zdarzeń i wykonanie ostatniego zadania polecenia haltlub reboot.
  • Wywoła pliki wykonywalne w odpowiedzi na pewne zdarzenia, takie jak zdarzenia mocy lub Ctrl-Alt-Del.
  • Nasłuchuje na gnieździe, jeśli otrzyma pewne wiadomości, zmieni poziom działania.

Jeśli chcesz, możesz więc użyć go initjako podstawowego menedżera usług, ale obecnie jego głównym zadaniem jest utrzymanie gettydostępności, aby użytkownik mógł się zalogować i rozpocząć przejścia na poziomie uruchamiania.

Zastanawiałem się tylko, jakie zadania wykonuje init, aby skonfigurować system dla prostej powłoki?

Cokolwiek chcesz. Na Debianie w każdym /etc/rcX.dkatalogu znajduje się dowiązanie symboliczne do skryptu, w /etc/init.dktórym można w pełni dostosować lub usunąć te skrypty. Kolejność ustala poprzedzając każdy skrypt z 00, 01itp

Możesz także określić -bopcję init(np. Poprzez linię poleceń jądra), jeśli chcesz po prostu initodrodzić powłokę. Kiedy wyjdziesz z powłoki, initumiera, a kiedy initumiera, jądro wpadnie w panikę.


2

Absolutne minimum, które musi wykonać init, to uruchomić przynajmniej jeden inny program i nigdy nie wychodzić. Jeśli init kończy działanie, system ulega awarii. Podejrzewam, że nawet uruchomienie jednego innego programu nie jest absolutnie konieczne, ale jeśli tego nie zrobisz, init musiałby być odpowiedzialny za zrobienie wszystkiego, co powinien zrobić system, albo nie byłoby to bardzo przydatne.


1
Miałem wadliwe systemy Linux, w których PID 1 ulegał awarii, ale system zasadniczo działał. To, jak źle ulega awarii PID 1, może zależeć od wersji jądra.
Gilles 'SO - przestań być zły'

1

init możesz robić co chcesz

init jest dowolnym plikiem wykonywalnym wywoływanym przez jądro Linuksa na końcu procesu rozruchu (i jedynym takim plikiem wykonywalnym).

Zwykle jest implementowany jako plik wykonywalny ELF, ale może nawet być skryptem powłoki z chmod +x: Init jako skryptem powłoki

Typowe implementacje, takie jak sysemd, odczytują pliki konfiguracyjne, ofen /etc/initrc, a następnie rozwidlają kilka procesów użytkownika w oparciu o te konfiguracje, aby zaimplementować różne aspekty systemu.

Jest to jednak całkowicie specyficzne dla implementacji, dlatego na pytanie nie można odpowiedzieć bez podania konkretnej implementacji. Na przykład bawiłem się initprocesem, który po prostu wykonuje rebootsyscall w celach edukacyjnych.

Jądro systemu Linux /initdomyślnie po prostu szuka pliku wykonywalnego w ścieżce , ale można to zastąpić init=parametrem wiersza polecenia jądra systemu Linux.

Jednym świetnym sposobem na zabawę initjest użycie QEMU, ponieważ można przekazać parametry wiersza polecenia jądra do QEMU z wiersza polecenia QEMU z -appendopcją i bez obawy o uszkodzenie pulpitu.

Oto moja minimalna, w pełni zautomatyzowana konfiguracja Buildroot + QEMU, która sprawia, że ​​bardzo łatwo jest bawić się własnymi initami w celu wyjaśnienia sprawy.


0

Jeśli jesteś zaangażowany w modułową zasadę „zrób jedną rzecz i zrób to dobrze”, initprogram powinien rozpocząć procesy.

Rozpocznij procesy

Powinien zostać wykonany po pomyślnym zdekompresowaniu jądra, dbając o wszystkie podstawowe zadania związane z inicjowaniem wszystkich początkowych procesów wymaganych przez system (takich jak montowanie napędów znalezionych w / etc / fstab, uruchamianie interfejsów sieciowych i wkrótce).

Ponieważ proces uruchamiania i zamykania jest zasadniczo odwrotny względem siebie, program inicjujący często zapewnia również zatrzymanie procesów po wydaniu polecenia zamknięcia.

Zatrzymaj procesy

Oznacza to, że musi zatrzymać procesy zgodnie ze stroną kill -9podręcznika tego procesu (innymi słowy, nie tylko rażąco , powinien sprowadzić proces w sposób, w jaki chce się zakończyć), odmontować dyski i ostatecznie wydać polecenie końcowego wyłączenia zasilania .

Bibliografia

Dobrym odniesieniem do tego, jak robią to inni, jest przyjrzenie się skryptom /etc/rc.d Slackware , a także prostemu systemowi inicjalizacji, który już istnieje, takim jak ninit (następca minit). Ma nadzór nad procesem (co oznacza, że ​​jeśli proces umrze, zostanie ponownie uruchomiony), co prawdopodobnie nie jest zadaniem init, ale nadal jest dość prosty i łatwy do zrozumienia, szczególnie za pomocą przykładowych skryptów autora.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.