Proces Numer 1 14


Jedną z pierwszych czynności, która ma miejsce podczas startu systemu Linux, jest przekazanie odpowiedzialności za uruchomienie wszelkich jego elementów przez jądro (kernel) do programu będącego implementacją init. Proces ten zostaje oznaczony numerem identyfikacyjnym (PID) 1. Odpowiada on za uruchamianie pozostałych procesów stając się ich rodzicem. W konsekwencji staje się przodkiem wszystkich procesów w czasie działania systemu. Bez tego programu nie można więc nawet zalogować się do konsoli. Jednak na samym uruchamianiu procesów nie kończy się rola implementacji init. Zarządza ona także wyłączaniem usług, przejmuje kontrolę nad osieroconymi procesami oraz zajmuje się zależnością jednej usługi od drugiej. Ostatnio w świecie Linuksa następują spore zmiany w sposobie implementacji init, a poniższy artykuł ma za zadanie przybliżyć czytelnikowi to zagadnienie.

1. sysvinit

Tradycyjnie w Linuksie zadania init są realizowane przez implementację zwaną sysvinit, która bierze swe początki od Uniksów System V jeszcze z lat 80-tych. sysvinit reprezentuje bardzo klasyczne podejście do procesu uruchamiania systemu. Gdy program rozruchowy przekazuje proces inicjalizacji systemu do jądra, to wtedy kernel rozpoczyna montowanie systemu plików root, którego lokalizacja została podana w parametrze przekazanym przez program rozruchowy (np. root=/dev/sda1). System plików root to taki, w którym można znaleźć katalog „root”, czyli po prostu „/”. Jądro uruchomia system plików root tylko do odczytu, a następnie poszukuje na nim programu init (w miejscach takich jak „/sbin”, „/etc”, „/bin”). Gdy go znajdzie, przekazuje mu odpowiedzialność za uruchomienie reszty systemu. sysvinit po swoim uruchomieniu stawia resztę systemu na podstawie skryptów znalezionych w „/etc/init.d” (ta lokalizacja może się różnić w zależności od dystrybucji). Skrypty wykonywane są tak jak skrypty – od początku do końca, po kolei. Chociaż nowsze wersje sysvinit pozwalają na jednoczesne uruchamianie wielu procesów, to praktyka wskazuje, że te możliwości są bardzo ograniczone. Posługując się uproszczonym przykładem: żeby uruchomić menedżer sieci, najpierw musi zostać uruchomiony D-Bus. Natomiast, żeby D-Bus wystartował, to musi mieć gdzie logować, czyli usługa Syslog musi być uruchamiana. Tak więc sysvinit uruchomi po kolei Syslog->D-Bus->Network Manager. Jest to podejście w miarę proste w implementacji i zrozumieniu, a także łatwe w administracji. Jednak główną jego wadą jest powolność. Wszystkie procesy uruchamiają się jeden po drugim i to na podstawie skryptów powłoki (język wysokiego poziomu), czego owocem jest tak długi czas oczekiwania na gotowość systemu do pracy.

2. Upstart

Powolność uruchomienia systemu przy pomocy sysvinit w niczym nie przeszkadza na serwerach. Jednak Ubuntu to dystrybucja skierowana na biurka, a użytkownik domowy najchętniej chciałby mieć system gotowy do pracy w kilka sekund po wciśnięciu przycisku zasilania. Ten problem dostrzegał Canonical i 2006 roku zaczął pracować nad własną implementacją progamu init zwaną Upstart. W Ubuntu 9.10 system ten całkowicie przeszedł na natywną obsługę Upstartu. Z implementacji tej zaczęła też korzystać Fedora (od wersji 9) i wyglądało na to, że definitywnie zastąpi ona już leciwy sysvinit. Upstart reprezentuje sobą zupełną zmianę podejścia do zagadnienia uruchamiania systemu. Działa asynchronicznie oraz w oparciu o wydarzenia (events). Tak więc, kiedy np. D-Bus zostanie uruchomiony, to Upstart wyśle sygnał o tym wydarzeniu. W tym momencie wszystkie procesy, które wymagają D-Bus do uruchomienia (np. Network Manager i Bluez) mogą zacząć startować i to jednocześnie! Upstart wykorzystuje więc znakomicie wielowątkowość współczesnych procesorów, co w widoczny sposób przekłada się na wydajność uruchamiania systemu. Projekt ten we wdzięczny sposób obsługuje także dynamiczną wymianę sprzętu w czasie działania systemu (np. podłączenie pamięci USB). Po prostu taka wymiana generuje wydarzenie, a odpowiednie powiadomione o tym usługi rozpoczynają pracę. Na sysvinit zagadnienie to jest problematyczne w implementacji i wymaga nieeleganckich rozwiązań. Ponadto Upstart może w ramach wstecznej kompatybilności obsługiwać też skrypty przeznaczone dla sysvinit, co przynajmniej w pierwszym etapie migracji miało ułatwić developerom pracę. Jednak pełna migracja wymaga olbrzymiego nakładu pracy. Dość powiedzieć, że samemu Ubuntu zabrało to prawie 3 lata. Zupełnie inna filozofia działania powodowała, że skryptów sysvinit nie da się bezpośrednio przepisać na potrzeby Upstartu. Zamiast tradycyjnego podejścia, ta implementacja init korzysta z tzw. prac (jobs) opisanych w tekstowych plikach „*.conf” w katalogu „/etc/init/”. Trzeba więc przeprojektować cały mechanizm inicjalizacji systemu i obsługi sygnałów niemalże od początku. Z tego powodu Upstart nigdy nie zastąpił sysvanit nawet w Debianie, a proces migracji dystrybucji na to rozwiązanie został wstrzymany przez pojawienie się trzeciego gracza.

3. systemd

systemd to implementacja init, której rozwój w 2010 roku rozpoczął Lennart Poettering – twórca PulseAudio. I na początku właśnie przez ten pryzmat była postrzegana. PulseAudio (przynajmniej w początkowej fazie rozwoju) spędzało sen z powiek niejednemu użytkownikowi Linuksa. Wadliwa wsteczna kompatybilność interfejsu do ALSA (skrzeczący dźwięk), wysoka latencja oraz dźwięk niedziałający w ogóle to były tematy powszechne na forach linuksowych. Nic więc dziwnego, że z początku wszyscy chcieli, żeby Lennart trzymał się z daleka od tak ważnego elementu systemu jak init. Jednak systemd dzięki swoim zaletom pokonał te uprzedzenia i jest na najlepszej drodze, żeby stać się nowym powszechnie stosowanym następcą sysvinit. systemd jest programem inspirowanym launchd, który Apple wykorzystuje w Mac OS X oraz iOS. Literka „d” na końcu obu nazw wpisuje się w Uniksowy styl oznaczania programów-demonów (takich, które działają w tle bez interakcji z użytkownikiem). systemd uruchamia system w bardzo ciekawy sposób, a mianowicie startuje wszystkie procesy jednocześnie i buforuje komunikację między nimi. Tak więc nawiązując do przykładu Network Managera i D-Busa. Oba te procesy uruchamiane są jednocześnie. Gdy Network Manager chce wysłać sygnał do D-Bus, to systemd przejmuje ten sygnał, buforuje go i przekazuje D-Busowi, dopiero gdy ten będzie już gotowy do jego odebrania. W międzyczasie Network Manager może kontynuować swoje uruchamianie. Jeżeli Network Manager w pewnym etapie uruchamianie będzie oczekiwał na odpowiedź od D-Bus, to systemd go zamrozi. Gdy D-Bus dojdzie do stanu, żeby udzielić odpowiedzi, to systemd przekaże ją Network Managerowi i odmrozi proces. Dodatkowe zalety takiego rozwiązania są też wykorzystywane na w pełni włączonym już komputerze. Gdy jakaś usługa ulegnie awarii, to systemd może w podobny sposób buforować komunikację z nią do momentu jej restartu, a dzięki temu praca systemu pozostanie niezachwiana. Administratorzy docenią na pewno jeszcze inną zaletę tego rozwiązania. A mianowicie zdolności buforowania systemd pozwalają na zapisywanie logów nie tylko jeszcze sprzed uruchomienia Syslog, ale nawet sprzed oznaczenia systemu plików root jako zdolnego do zapisu. Nie gubią się więc żadne powiadomienia nawet z bardzo wczesnych etapów startu systemu. Podobnie jak Upstart systemd jest wstecznie kompatybilny do skryptów sysvinit, jednak w swojej natywnej implementacji korzysta z jednostek (units), które opisują uruchamianą usługę. Sam proces uruchamiania usługi nie jest natomiast zawarty w skryptach powłoki, a w programikach napisanych w języku niskiego poziomu – C, co dodatkowo skraca czas startu. Ogólnie uważa się, że migracja na systemd jest wyraźnie łatwiejsza niż na Upstart.

4. A więc znowu wojna?

Ze względu na różnice w metodyce działania nie jest do końca jasne co jest lepsze Upstart, czy systemd. Jednak niektóre porównania obu technologii nie pozostawiają na Upstarcie suchej nitki. Szalę przeważyło przejście Fedory 15 w 2011 roku właśnie z Upstartu na systemd. Tym ruchem ta dystrybucja osiągnęła niesamowite rezultaty takie jak podkręcanie systemu do startu w krócej niż 3 sekundy. Za przykładem Fedory wkrótce poszli developerzy OpenSUSE oraz Mandriva/Mageia, a Debian, Gentoo i Arch zastanawiają się nad migracją na systemd. Kolejny cios przyszedł w kwietniu 2012. Menadżer urządzeń udev zarządzający katalogiem „/dev” został wchłonięty przez systemd, stając się tym samym jego elementem. Upstart potrzebuje udev do zarządzania plikami urządzeń, tak więc chcąc, czy nie chcąc Canonical musi go dostarczać, de facto implementując już element systemd. Developerzy systemd zapewniają, że udev będzie mógł być dalej wykorzystywany przez inne implementacje init, ale chyba nikt nie ma złudzeń,  pod kątem której będzie dalej rozwijany. Canonical nie ma jednak w zwyczaju łatwo rezygnować z technologii, które samemu stworzył. Ubuntu pozostaje oddane Upstartowi i kontynuuje jego rozwój. Znajdujemy się więc w momencie przesilenia. Ubuntu jako najpopularniejsza dystrybucja korzysta z Upstara, część innych dystrybucji zmigrowała już do systemd, a reszta ciągle pozostała na sysvinit. W ciągu najbliższych lat dowiemy się, czy kolejny rozłam w świecie oprogramowania open source się utrwali, czy jednak któraś z implementacji przejmie dominację na Linuksie.


Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

14 komentarzy do “Proces Numer 1