Dokumentacja
Transkrypt
Dokumentacja
Politechnika Gdańska WYDZIAŁ ELEKTRONIKI TELEKOMUNIKACJI I INFORMATYKI Katedra Inżynierii Oprogramowania Imię i nazwisko dyplomanta: Nr albumu: Rodzaj studiów: Kierunek studiów: Wojciech Basałaj 78421/ETI Dzienne Informatyka Praca magisterska Wykonanie dystrybucji systemu Linux dla klastrowych stacji bezdyskowych Kierujący pracą: Konsultant: dr hab. inż. Jerzy Kaczmarek mgr inż. Michał Wróbel Zakres pracy: W ramach niniejszej pracy skonstruowano dystrybucję systemu operacyjnego klastrowy cdlinux.pl opartego o jądro GNU/Linux oraz o oprogramowanie, które w większej części wchodzi w skład dystrybucji cdlinux.pl. System operacyjny klastrowy cdlinux.pl uruchamiany jest na komputerze PC całkowicie z jednej płyty CD-ROM i pozwala na automatyczne stworzenie klastra obliczeniowego złożonego z danego komputera PC oraz wszystkich komputerów obecnych w jego sieci lokalnej. W części pisemnej przedstawiono podłoże teoretyczne tematu klastrów oraz szczegółowy opis uruchamiania i budowy systemu klastrowy cdlinux.pl. Część praktyczną stanowi realizacja projektu w postaci płyty z działającym systemem operacyjnym oraz wykonanie testów wydajności ukazujących zalety i wady zaprezentowanego rozwiązania, jak również porównanie skalowalności klastra z klastrami profesjonalnymi. Gdańsk, 2005 Spis treści 1. Wstęp...................................................................................................................................... 5 1.1. Porównanie systemów Linux i Microsoft Windows....................................................... 5 1.2. Dystrybucje uruchamiane z wymiennych nośników....................................................... 6 1.3. Dystrybucja cdlinux.pl.....................................................................................................8 1.4. Dystrybucja klastrowy cdlinux.pl.................................................................................... 8 2. Środowisko klastrowe openMosix........................................................................................ 11 2.1. Klastry obliczeniowe..................................................................................................... 11 2.1.1. Podstawowe pojęcia...............................................................................................11 2.1.2. Klasyfikacja klastrów............................................................................................ 12 2.1.3. Typy budowy klastrów HPC..................................................................................13 2.1.3.1. NUMA........................................................................................................... 13 2.1.3.2. DSM...............................................................................................................14 2.1.3.3. MPI oraz PVM............................................................................................... 14 2.2. Środowisko openMosix jako klaster HPC.....................................................................15 2.2.1. Single System Image..............................................................................................15 2.2.1.1. Perspektywa procesu......................................................................................16 2.2.1.2. Perspektywa użytkownika..............................................................................16 2.2.1.3. Perspektywa systemu plików......................................................................... 17 2.2.2. openMosix File System......................................................................................... 19 2.3. Konfiguracja openMosixa............................................................................................. 21 2.3.1. Konfiguracja statyczna...........................................................................................21 2.3.2. Konfiguracja dynamiczna – automatyczne odkrywanie........................................ 23 2.4. Oprogramowanie monitorujące openMosixview.......................................................... 25 2.4.1. Zdalne zarządzanie węzłami..................................................................................25 2.4.2. Główne okno programu......................................................................................... 27 2.4.3. Zarządzanie procesami przez openMosixprocs..................................................... 29 2.4.4. Statystyki............................................................................................................... 31 2.4.5. Graficzny monitoring i zarządzanie - openMosixmigmon.................................... 33 2.5. Wykorzystanie środowiska openMosix w klastrowym cdlinux.pl................................ 35 3. Uruchamianie systemu operacyjnego....................................................................................37 3.1. Uruchamianie kontrolera klastra................................................................................... 37 2 3.1.1. Wczytanie programu ładującego Linuxa............................................................... 38 3.1.1.1. El Torito ........................................................................................................ 38 3.1.1.2. SYSLINUX.................................................................................................... 40 3.1.2. Uruchomienie jądra Linuxa................................................................................... 42 3.1.3. Przygotowanie systemów plików.......................................................................... 43 3.1.4. Konfigurator yahade.............................................................................................. 45 3.1.5. Uruchomienie rozszerzeń względem cdlinux.pl....................................................47 3.2. Uruchamianie węzła klastra.......................................................................................... 48 3.2.1. Środowisko PXE (Pre Execution Environment)....................................................48 3.2.2. Nawiązanie komunikacji węzła z kontrolerem klastra.......................................... 50 3.2.2.1. Opis usługi Dynamic Host Configuration Protocol (dhcp)............................51 3.2.2.2. Opis usługi Trivial File Transfer Protocol (tftp)............................................ 53 3.2.3. PXELINUX – druga odsłona SYSLINUXa...........................................................55 3.2.4. Uruchomienie jądra z nfsroot................................................................................ 58 3.2.4.1. Opis protokołu NFS ...................................................................................... 60 3.2.5. Zakończenie inicjacji węzła...................................................................................65 4. Budowa systemu operacyjnego............................................................................................. 67 4.1. Doinstalowane oprogramowanie................................................................................... 67 4.2. Przygotowanie jądra...................................................................................................... 68 4.2.1. Wsparcie dla NFS w cramfs.................................................................................. 69 4.2.2. Opcje kompilacji jądra Linuxa.............................................................................. 73 4.3. Przygotowanie programu ładującego ISOLINUX.........................................................76 4.4. Przygotowanie systemów plików.................................................................................. 80 4.5. Narzędzia openMosix....................................................................................................81 4.6. Zmiany dokonane przez yahade.................................................................................... 82 4.7. Usunięcie niepotrzebnego oprogramowania................................................................. 90 4.8. System plików eksportowany do węzła.........................................................................90 4.9. Stworzenie płyty z dystrybucją......................................................................................93 4.10. Przygotowanie węzła do uruchomienia przez sieć...................................................... 95 4.11 Gotowy produkt............................................................................................................98 5. Testy wykonanego systemu.................................................................................................100 5.1. Test przy pomocy POVRAY w oparciu o PVM......................................................... 100 5.1.1. Test na trzech węzłach o różnej wydajności............................................................ 101 3 5.1.2. Test na węzłach o takiej samej wydajności.............................................................. 105 5.1.2.1. Pomiar prędkości uruchamiania....................................................................... 105 5.1.2.2. Renderowanie mało skomplikowanej grafiki................................................... 107 5.1.2.3. Renderowanie bardziej skomplikowanej grafiki.............................................. 110 5.2. Testy w oparciu o MPI................................................................................................ 112 5.2.1. Test przy pomocy POVRAY w oparciu o MPI................................................... 112 5.2.2. Porównanie klastrowego cdlinux.pl do klastrów Top500................................... 113 6. Podsumowanie.................................................................................................................... 114 7. Bibliografia......................................................................................................................... 116 8. Załączniki............................................................................................................................118 Spis ilustracji...................................................................................................................... 118 Spis tabel............................................................................................................................ 119 Spis diagramów.................................................................................................................. 120 4 1. Wstęp Linux jest nowoczesnym systemem operacyjnym, który zdobywa coraz szersze kręgi użytkowników na całym świecie informatycznym. Jest ceniony przede wszystkim za swoją politykę dotyczącą oprogramowania – większość jest rozprowadzana na licencji GNU General Public License, której głównym przesłaniem jest darmowe rozpowszechnianie oprogramowania w postaci kodu źródłowego. Kolejną zaletą jest jego wysoka jakość ukazująca się przez wydajność oraz stabilność. Obecnie najczęściej używanymi systemami operacyjnymi na stacjach roboczych są produkty firmy Microsoft serii Windows, jednak nie wszyscy użytkownicy komputerów się na nie decydują. 1.1. Porównanie systemów Linux i Microsoft Windows System operacyjny Linux nie jest łatwy do zainstalowania na stacji roboczej przez przeciętnego użytkownika komputera PC. Problemy wynikają przede wszystkim z odmienności samego systemu od Microsoft Windows. Poniżej zestawiono kilka różnic wpływających ujemnie na łatwość instalacji Linuxa. Podstawowym problemem dla wielu jest inny układ dysków twardych i ich partycji. W systemach operacyjnych DOS oraz Windows (poza serią NT i pochodnymi) partycje wszystkich dysków fizycznych dostępne są w postaci pojedynczej listy i identyfikowane są poprzez kolejne litery alfabetu (A:, B:, C:, ...), natomiast w Linuxie partycje dostępne są poprzez nazwę zawierającą w sobie numer dysku twardego oraz partycji względem tego dysku. Obydwa rozwiązania mają swoje wady i zalety. Rozwiązanie firmy Microsoft cechuje prostota (jeżeli istnieje jeden dysk twardy w komputerze, jego pierwsza partycja będzie zawsze dostępna pod nazwą C:), jednak w przypadku częstej zmiany konfiguracji dyskowej komputera, rodzą się problemy. Druga partycja dysku, do tej pory dostępna pod nazwą D:, po dołożeniu drugiego dysku do komputera będzie dostępna pod nazwą E:, natomiast jej miejsce zajmie pierwsza partycja dołożonego dysku. W rozwiązaniu linuxowym administrator musi więcej zwrócić uwagi na poprawne zaadresowanie partycji w systemie (nazwa identyfikująca partycję zawiera numer dysku oraz numer partycji względem dysku), jednak dzięki temu nazwa ta nie zmienia się po dostawieniu, bądź usunięciu innych dysków do/z systemu komputerowego. 5 Nowością w Linuxie względem Windows jest większa liczba partycji do przygotowania. Instalując system Windows należy jedynie wskazać, na której partycji ma być zainstalowany system. Podczas instalacji systemu Linux, użytkownik stoi przed zadaniem określenia partycji podstawowej, ewentualnie partycji przeznaczonych na części drzewa katalogów (np. /usr, /home, etc.) oraz tzw. partycji wymiany, która składa się wraz z pamięcią RAM na pamięć wirtualną systemu operacyjnego. Dodatkowo, występujące w systemie Linux narzędzia służące do zarządzania dyskami twardymi oferują więcej możliwości, niż ich odpowiedniki z innych popularnych systemów. Zwiększa to zagubienie „świeżego” użytkownika. Instalację systemu operacyjnego Linux cechuje większa elastyczność w doborze komponentów. Wprawdzie w większości dystrybucji tegoż systemu operacyjnego dla użytkownika przygotowanych jest kilka zestawów komponentów, co upraszcza wybór, jednak bogaty asortyment dostarczanego oprogramowania powoduje, iż domyślna instalacja może zajmować bardzo dużą przestrzeń dysku twardego. Skłania to użytkowników do eksperymentowania z doborem komponentów do instalacji, co może spowodować frustrację przez nieuruchamiający się, bądź wybrakowany i przez to nieużywalny systemem operacyjny. Z drugiej strony, dla doświadczonych użytkowników dowolność ta jest bardzo pożądana. Innym problemem jest niewielka jeszcze ilość użytkowników Linuxa, która dobrze opanowała „sztukę” jego instalacji. O ile w obliczu problemów z instalacją systemu Windows możemy liczyć na pomoc ze strony większości znajomych posiadających komputery (w domyśle: używających Windowsa), o tyle spotkawszy się z problemami przy instalacji Linuxa musimy sobie często poradzić sami, bądź szukać odpowiedzi w Internecie, czy prosić o pomoc lokalnego „guru” Linuxa, który nie zawsze ma ochotę udzielać pomocy. Wyżej opisane „wady” mogą powodować problemy tylko na początku użytkowania systemu operacyjnego. W rzeczywistości są to zalety, które zatrzymują przy Linuxie osoby, które raz go wypróbowały. 1.2. Dystrybucje uruchamiane z wymiennych nośników Przedstawione wyżej powody zrodziły potrzebę zaistnienia dystrybucji systemu Linux, które albo wyeliminują problemy związane ze zbyt dużą dowolnością przy instalacji, bądź wyeliminują całkowicie instalację. W odpowiedzi powstały dystrybucje systemu Linux 6 mieszczące się całkowicie na jednym egzemplarzu nośnika (ewentualnie na dwóch w przypadku dyskietek 1.4MB), które uruchomione z tego nośnika stawały się działającym systemem operacyjnym. Jedną z takich dystrybucji Linuxa była PocketLinux [PKTLNX]. Użyto sformułowania była, gdyż obecnie najświeższą wersją jest 2.51, która ukazała się w 1998 roku. Oparta jest o jądro Linuxa w wersji 2.0.35 (2.0.39 w przypadku wersji -fix-3), obsługuje szereg kart sieciowych, modem, popularne systemy plików (łącznie z vfat znanym z produktów serii Windows firmy Microsoft), standardowe porty szeregowe (równoległe nie są obsługiwane), mysz na porcie PS/2. Posiada bogate oprogramowanie, jak na tak niewielką objętość, które umożliwia automatyczną konfigurację i diagnozę sieci, edycję plików, zdalną pracę, zarządzanie komputerem. Polecenie help udziela krótkiego, lecz treściwego wyjaśnienia dla początkujących. Istnieją niewielkie, jak na obecne warunki, wymagania pamięciowe, czyli około 7 megabajtów pamięci operacyjnej oraz pamięć w postaci pliku, czy partycji wymiany, które to pliki system potrafi sam automatycznie tworzyć na partycjach, a partycje wymiany potrafi wykrywać. Od czasów świetności PocketLinuxa rozwinęła się technologia, popularne nośniki zyskały na pojemności, dostępności, niezawodności. Obecnie standardowym wyposażeniem każdego komputera jest napęd CD-ROM, czyli urządzenie odczytujące nośnik w postaci dysku optycznego bez możliwości zapisu. Pojemności największych płyt CD-ROM sięgają 800MB, co jest wielkością prawie 600 razy większą, niż pojemność dawniej popularnej dyskietki 1.4MB. Z biegiem czasu oprogramowanie zwiększało swoją objętość, zatem i dystrybucje Linuxa, nawet te nieinstalowane, wymagały coraz większych pojemności nośników. Mając do dyspozycji podłoże technologiczne, powstały dystrybucje systemu operacyjnego Linux uruchamiane z CD-ROMu. Ten typ dystrybucji nosi nazwę „live CD”. Uruchamianie systemu z CD-ROMu przebiega podobnie, jak uruchamianie z dyskietki i jest opisane szerzej w rozdziale dotyczącym uruchamiania systemu będącego przedmiotem pracy. 7 Istnieje kilka projektów mających na celu wytworzenie dystrybucji Linuxa uruchamianej z CD-ROMu. Przykładami są: • Knoppix • Eagle Linux • Phrealon • cdlinux.pl 1.3. Dystrybucja cdlinux.pl Cdlinux.pl [CDLINUXPL] jest systemem operacyjnym, o który oparta jest niniejsza praca. Został on wytworzony jako przedmiot pracy dyplomowej Michała Wróbla pt. „Modyfikacja systemu Linux dla stacji bezdyskowych” [WRÓB]. System ten mieści się na jednej płycie CD-ROM, z której można go bezpośrednio uruchomić bez instalacji na dysku twardym. W trakcie pisania niniejszej pracy, cdlinux.pl rozprowadzany jest w dwóch wersjach: duży i mały. Wersja duży zajmuje całą płytę CD-ROM, natomiast mały został zaprojektowany z myślą o płytach CD-ROM o średnicy 8cm. Płyty takie do niedawna jeszcze były w sprzedaży w wersji do 250 megabajtów, jednak obecnie najczęściej spotykanymi rozmiarami są 210 megabajtów. System operacyjny klastrowy cdlinux.pl został oparty o wersję cdlinux.pl-mały-0.5.7-pre2. Wersja ta pozbawiona jest dużych aplikacji i środowisk pracy, np. menadżera okien KDE, aplikacji biurowych (w tym OpenOffice.org). Zdecydowano, iż nie będą one potrzebne w najczęstszych przypadkach użycia konstruowanego klastra, a w razie pilnej potrzeby można system łatwo o nie wzbogacić. 1.4. Dystrybucja klastrowy cdlinux.pl Klastrowy cdlinux.pl jest dystrybucją systemu Linux, która pozwala na budowanie jednorodnego klastra obliczeniowego, w którym zwielokrotniona jest pamięć operacyjna, pamięć masowa, moc obliczeniowa. Do korzystania z takiego klastra nie są wymagane specjalnie projektowane dla niego aplikacje, gdyż fakt istnienia wielu procesorów w klastrze jest dla aplikacji ukryty. Klaster cdlinux.pl można przyrównać do jednego komputera z wieloma procesorami, który pracuje pod kontrolą systemu operacyjnego typu Symmetric Multi Processing (SMP). Jądro systemu SMP nie wyróżnia żadnego z procesorów spomiędzy innych – obciążenie jest rozkładane w miarę możliwości równomiernie pomiędzy wszystkie 8 procesory. Podobnie klaster cdlinux.pl stara się zrównoważyć obciążenie każdego ze swoich węzłów, przy czym obciążenie jest rozumiane zarówno jako zajętość pamięci, jak i obciążenie CPU (Central Processing Unit, głównego procesora obliczeniowego systemu komputerowego). Przy równoważeniu obciążenia brana jest pod uwagę znamionowa pojemność pamięci operacyjnej jak i znamionowa szybkość CPU. Zasadniczą różnicą między porównywanymi rozwiązaniami jest to, że SMP składa się z wielu procesorów na wspólnej szynie danych, natomiast w klastrze cdlinux.pl procesory są w odrębnych komputerach, a zatem połączone na wyższej warstwie komunikacyjnej – poprzez sieć komputerową. Z tego tytułu komunikacja między procesorami jest o kilka rzędów mniej sprawna w klastrze, niż w SMP oraz synchronizacja jest utrudniona. Technologią użytą w celu wzbogacenia Linuxa o wsparcie dla klastrów jest mechanizm stworzony w projekcie openMosix, któremu poświęcony zostanie osobny rozdział. Do skonstruowania klastra w oparciu o klastrowy cdlinux.pl wystarczy jedna płyta CD-ROM. System operacyjny z niej uruchomiony jest centralnym węzłem klastra (nazywanym dalej kontrolerem klastra). Proces jego uruchomienia nie odbiega daleko od procesu uruchamiania zwykłego cdlinux.pl. Po zainicjowaniu systemu, uruchomione zostają pozostałe komputery mające wejść w skład klastra. Komputer taki jest albo skonfigurowany do uruchomienia systemu operacyjnego przez sieć (jeżeli karta sieciowa oraz płyta główna komputera na to pozwalają), bądź stosowana jest dyskietka startowa, która zastępuje część ładującą systemu, która powinna być na karcie sieciowej. Komputer wykrywa kontroler klastra poprzez uruchomiony na tym ostatnim serwer bootp. Z tegoż serwera węzeł dowiaduje się, skąd ma pobrać program ładujący oraz jądro systemu operacyjnego (otrzymuje adres serwera tftp) i wzbogacony o tę wiedzę, pobiera ww. składowe systemu. Po uruchomieniu nowo pozyskanego jądra, skrypty startowe montują udziały sieciowego systemu plików NFS w trybie „tylko do odczytu” z kontrolera klastra, tworzą wirtualne dyski w pamięci RAM (ramdyski) i oddają kontrolę nad inicjacją systemu do standardowych skryptów inicjacyjnych cdlinux.pl. Po zakończeniu inicjacji system operacyjny uruchomiony na węźle funkcjonuje bardzo podobnie do systemu operacyjnego kontrolera klastra. Pod koniec procesu uruchamiania systemu operacyjnego, inicjowany jest podsystem openMosix, przy czym proces ten jest prawie identyczny zarówno na kontrolerze, jak i na 9 węzłach, gdyż żaden z elementów klastra nie jest wyróżniony z punktu widzenia pracy klastra. Inicjacja podsystemu openMosix polega na wydaniu odpowiedniego rozkazu do jądra systemu (przez interfejs sysctl) oraz na uruchomieniu daemona omdiscd, który odpowiedzialny jest za automatyczne dołączanie węzłów do klastra. Dodatkowo na kontrolerze klastra uruchomiony zostaje daemon openmosixcollector, który wspomaga pracę programu realizującego pulpit kontrolny klastra, openmosixview. W dalszych częściach pracy przedstawiono szczegółowo system openMosix oraz pewne rozwiązania z nim związane w klastrowym cdlinux.pl. Następnie omówiono proces uruchamiania klastra ze szczególnym naciskiem na elementy różniące go od cdlinux.pl oraz jego budowę. W ostatniej części pracy znajdują się wyniki testów wydajności zbudowanego systemu operacyjnego. 10 2. Środowisko klastrowe openMosix 2.1. Klastry obliczeniowe Pomysł klastrów komputerowych powstał w wyniku zapotrzebowania na dużą skalowalną moc obliczeniową uzyskaną kosztem niedrogiego sprzętu. Tym niedrogim sprzętem mogą być popularne obecnie komputery PC zakupione na poczet budowy klastra, a mogą to być również stacje robocze końcowych użytkowników. Użytkownicy przez większą część czasu nie potrzebują wielkich mocy obliczeniowych swoich stacji roboczych do wykonywania pracy, więc nie są one dociążane. Z drugiej strony, okazjonalnie miewają potrzeby krótkich, lecz intensywnych obliczeń i wtedy dociążają swoje stacje do granic wytrzymałości. Nasuwa się spostrzeżenie, iż praca przebiegałaby bardziej wydajnie, gdyby komputery były częścią większej całości – nagłe zapotrzebowanie na moc obliczeniową byłoby rozkładane na większą ilość komputerów, czyli między innymi na niedociążane zwykle stacje robocze. Tradycyjnie skomplikowanymi obliczeniami zajmowały się korporacyjne superkomputery – maszyny zaprojektowane do konkretnej wydajnej pracy nad pewnymi zagadnieniami matematycznymi, fizycznymi, chemicznymi, czy rozrywkowymi (komputery grające w szachy). Superkomputery były i są bardzo kosztowne, gdyż nie należą do produktów masowych, tworzone są na zamówienie. Ich wysoka cena zawężała grono użytkowników do dużych korporacji, czy uniwersytetów. Ponadto, w obliczu obecnego szybkiego rozwoju techniki, nawet superkomputery mogą szybko stać się zbyt wolne i zbyt przestarzałe jak na cenę, którą należało za nie zapłacić. Tych wszystkich wad pozbawione są klastry obliczeniowe, które przede wszystkim są zbudowane z tanich komputerów, a ponadto są łatwe w rozbudowie. 2.1.1. Podstawowe pojęcia Podstawową jednostką klastra jest węzeł, czyli pojedyncza maszyna (komputer) wchodząca w jego skład. Węzły są połączone między sobą przez sieć komputerową. Topologie połączeń mogą być bardzo zróżnicowane zależnie od środowiska, w którym klaster pracuje. W pracowni komputerowej będzie to przeważnie sieć LAN Ethernet bądź TokenRing, na odległych maszynach porozrzucanych po sieci metropolitarnej MAN może to być ATM czy 11 sieci DSL, natomiast w ogólności, gdy maszyny połączone są ze sobą przez Internet, sieci są dowolnego rodzaju i nie ma to większego znaczenia. Klastry zwykle są zaprojektowane w sposób, który umożliwia ich łatwą rozbudowę o kolejne węzły - skalowanie. Niektóre rozwiązania pozwalają nawet na swobodne podłączanie i odłączanie węzłów podczas pracy klastra. Fakt ten oraz duże zróżnicowanie sprzętu, który wchodzić może w skład heterogenicznego (zbudowanego z komponentów różnych typów) klastra powodują, iż mechanizmy rządzące klastrem mają trudne zadanie zapewnienia wysokiej wydajności całego organizmu. 2.1.2. Klasyfikacja klastrów Można wyodrębnić trzy podstawowe typy klastrów [OMHOWTO]: klastry odpornena-awarie (ang. fail-over cluster), klastry rozkładające obciążenie (ang. load-balancing cluster) i klastry wysokiej wydajności obliczeniowej, czyli HPC (ang. High Performance Computing cluster). Klastry odporne-na-awarie polegają na połączeniu w sieć dwóch lub większej ilości komputerów. Z logicznego punktu widzenia, oprócz połączenia ogólnego przeznaczenia (np. transmisji danych), występuje również połączenie kontrolne, tzw. heartbeat (ang. bicie serca), czyli sposób sprawdzania, czy komputery nadal działają. Jeżeli tego typu klaster wykonuje jakąś usługę, to wykonuje ją w rzeczywistości tylko jeden z komputerów wchodzących w jego skład. Pozostałe tylko obserwują, czy ten jeden nie przestanie działać. Jeżeli to nastąpi, jeden z pozostałych zajmuje jego miejsce w wykonywaniu usługi. Oczywiście usług może być wiele, niekoniecznie jeden z węzłów musi być przeznaczony do wykonywania wszystkich usług jednocześnie. Gdy w klastrze rozkładającym obciążenie nadchodzi żądanie usługi, jest ono kierowane do najmniej obciążonego węzła klastra. Ma to zastosowanie najczęściej w przypadku farmy serwerów WWW, gdzie wszystkie węzły mają dostęp do bazy danych, skąd czerpią zawartość stron do zaprezentowania użytkownikowi. Klastry rozkładające obciążenie są też przeważnie klastrami odpornymi-na-awarie, tylko że zwykle posiadają więcej węzłów. Klastry HPC są zaprojektowane z myślą o wysokiej wydajności przetwarzania danych. Łączą w sobie cechy obydwu wyżej wymienionych typów klastrów, jednak zasadniczym mechanizmem ich działania jest zrównoleglanie wykonywania programów – podprogramy nie 12 muszą zawsze czekać na wykonanie poprzednich, mogą być równolegle wykonywane na innych węzłach klastra. Programy wykonywane na klastrach HPC są zwykle projektowane specjalnie pod dany typ klastra, a czasami nawet pod konkretną topologię sieciową, która łączy jego węzły. 2.1.3. Typy budowy klastrów HPC Jeżeli mówi się o przetwarzaniu równoległym w klastrach, ma się na myśli raczej klastry HPC. Ze względu na mechanizmy równoległego przetwarzania można wyodrębnić kilka rodzajów klastrów HPC: Non-Uniform Memory Access, Distributed Shared Memory, Parallel Virtual Machine, Message Passing Interface. 2.1.3.1. NUMA Non-Uniform Memory Access (NUMA), czyli Nie-Jednolity Dostęp do Pamięci [NUMA], nie jest stricte oznaczeniem typu klastra, a raczej rodzaju pojedynczej maszyny, która jednak bardzo podobna jest w budowie do klastra. NUMA oznacza maszynę, która ma wiele procesorów (CPU) i pamięć, której różne regiony mają różne czasy dostępu z punktu widzenia poszczególnych CPU. Można przyjąć, że w maszynie jest kilka szyn danych. Do każdej z szyn podłączone są jeden lub więcej CPU oraz pamięci. W maszynie NUMA istnieje pojęcie węzłów i w omawianym założeniu węzłem będzie jedna szyna danych wraz z otoczeniem, czyli podłączonymi do niej procesorami oraz pamięciami. Mając to na uwadze, z punktu widzenia procesora z węzła A, pamięć w węźle A będzie lokalna (ang. local), natomiast pamięć w węźle B będzie odległa (ang. remote). Klasyfikację taką przeprowadza się w ten sposób dlatego, że czas dostępu z procesorów z węzła A do pamięci węzła B będzie większy, niż czas dostępu do pamięci w obrębie jednego węzła. Analogia do klastra polega na tym, że w NUMA też występują węzły z procesorami jako oddzielne jednostki, w obrębie których nie ma zróżnicowania co do dostępu do pamięci. Zasadniczą różnicą jest to, że w klastrze każdy węzeł pracuje pod kontrolą osobnego systemu operacyjnego z własną kontrolą dostępu do pamięci, zasobów wejścia/wyjścia, etc. W systemie NUMA jeden system operacyjny zarządza wszystkimi węzłami, czyli wszystkimi procesorami. Różnicą są też przepływności komunikacyjne między węzłami. W systemie NUMA węzły są częścią jednego komputera, zatem przepływności będą dużo wyższe niż w 13 klastrze, gdzie węzły znajdują się na osobnych komputerach połączonych siecią komputerową. Obecnie głównymi implementacjami maszyn NUMA są komputery IBM NUMA-Q, Compaq Wildfire, SGI MIPS64. W systemie operacyjnym Linux istnieje wsparcie dla NUMA, jednak obecnie tylko w gałęziach kodu 2.5.X oraz 2.6.X. 2.1.3.2. DSM Distributed Shared Memory (DSM) jest pojęciem opisującym pewną warstwę abstrakcji implementowaną zarówno w oprogramowaniu, jak i sprzęcie, która ma zapewnić dostęp do fizycznie rozproszonej pamięci [CHANDRA]. Polega to głównie na wymianie porcji danych między węzłami klastra i przedstawienie ich przez API (Application Programming Interface, interfejs programistyczny) do aplikacji. Sprzętowe systemy DSM charakteryzują się zapewnieniem spójności danych na poziomie poszczególnych linii pamięci podręcznej oraz replikacją danych w pamięci podręcznej procesorów. Dotyczy to szybkiej wymiany niewielkiej porcji danych, gdyż pamięć podręczna jest o kilka rzędów mniej pojemna, niż pamięć operacyjna. Z drugiej strony, programowe rozwiązania DSM polegają na wymianie dużych obszarów pamięci operacyjnej kosztem wolniejszej komunikacji. Mimo, iż rozwiązania programowe stosuje się przeważnie w rozproszonych środowiskach z luźno powiązanymi węzłami, niektóre programowe mechanizmy mają potencjalnie zastosowanie tam, gdzie procesory są ze sobą ściśle powiązane. Jest tak na przykład w przypadku aplikacji, gdzie każdy procesor pracuje na dużych zestawach danych i wtedy replikacja ma miejsce w pamięci głównej całych zestawów. Istnieje dużo projektów informatycznych dotyczących programowych rozwiązań DSM. Listę zbierającą część z nich można znaleźć w [DSMWWW]. 2.1.3.3. MPI oraz PVM Message Passing Interface (MPI) i Parallel Virtual Machine (PVM), czyli odpowiednio Interfejs Przesyłania Wiadomości i Równoległa Maszyna Wirtualna, są to podobne rozwiązania programowe oferujące wsparcie dla przetwarzania rozproszonego. Komunikacja między węzłami klastra opartego na MPI i PVM polega na przesyłaniu tzw. wiadomości, czyli paczek danych o ściśle określonej strukturze. Poprzez wiadomości przesyłane jest sterowanie jak i dane do wykonywanego programu. Podczas gdy PVM jest konkretnym pakietem 14 oprogramowania (dostępnym w [PVMWWW]), MPI jest otwartym standardem, którego najpopularniejszymi implementacjami są MPICH [MPICHWWW], LAM/MPI [LAMWWW]. 2.2. Środowisko openMosix jako klaster HPC Dzięki projektowi openMosix istnieje możliwość zbudowania klastra w oparciu o oprogramowanie typu opensource (otwarte źródło), co dodatkowo zwiększa dostępność klastrów. Projekt openMosix wywodzi się z projektu Mosix, który został zapoczątkowany w roku 1977 w Hebrew University of Jerusalem przez profesora Amnona Baraka. Celem Mosixa było przekształcenie zbioru komputerów, niekoniecznie tego samego typu, w jeden wydajny klaster obliczeniowy. Odbywało się to na zasadzie dokonania zmian w jądrze systemu operacyjnego mających na celu zbudowanie klastra SSI (patrz niżej) oraz planisty, który potrafi przenosić procesy między węzłami klastra w zależności od obciążenia węzła. Mosix pracował nawet na takich maszynach, jak PDP11/45, czy VAX, pod kontrolą systemu operacyjnego AT&T UNIX 6, BSD/OS 3.0. System operacyjny GNU/Linux został wybrany jako platforma rozwojowa kolejnego wcielenia systemu Mosix w roku 1999. W roku 1999 dr Moshe Bar objął stanowisko drugiego menedżera projektu Mosix. W roku 2002, w wyniku różnicy zdań profesora Baraka oraz dr Bara co do komercyjnej przyszłości projektu Mosix, dr Moshe Bar odłączył się od projektu zakładając firmę Qlusters Inc. i jednocześnie zapoczątkował projekt openMosix bazując na Mosixie. Główną cechą różniącą Mosixa od openMosixa była licencja, na jakiej oprogramowanie było rozprowadzane. Mosix był komercyjnym produktem, natomiast openMosix, jak sama nazwa sugeruje, od samego początku rozprowadzany był na licencji GNU, czyli wolny od opłat, ze źródłem kodu powszechnie dostępnym. Obecnie istnieją obydwa projekty – Mosix oraz openMosix, jednak z wypowiedzi dr Moshe Bara z 2002 roku wynika, iż około 97% użytkowników Mosixa zaczęło używać openMosixa. 2.2.1. Single System Image Pojęcie Single System Image (SSI) można zdefiniować jako „iluzję stworzoną przez oprogramowanie lub sprzęt przedstawiającą zbiór elementów obliczeniowych jako jeden logiczny zasób” [PFISTER]. Według Pfistera, w klastrze wyodrębnić można różne poziomy SSI – część podsystemów rozpozna klaster jako SSI, a część nie. Aby dobrze 15 scharakteryzować openMosixa jako SSI, należy rozpatrzyć różne poziomy SSI z różnych perspektyw, zwłaszcza z perspektywy procesu, użytkownika, systemu plików. 2.2.1.1. Perspektywa procesu W systemie operacyjnym UNIX mówi się o programie jako o wykonywalnym pliku, natomiast jego uruchomiona instancja to proces. Przestrzeń procesów to zbiór informacji o wszystkich działających procesach w systemie. W tradycyjnych systemach nie-SSI, każda maszyna posiada własną przestrzeń procesów, która jest zarządzana oddzielnie i niezależnie od innych maszyn. W openMosixie istnieje dla danego procesu pojęcie UHN – Unique Home Node, czyli Unikalnego Węzła Domowego. Jest to węzeł, na którym proces został uruchomiony. Każdy proces zostaje podzielony na 2 części: systemową oraz użytkownika. Część systemowa zawsze pozostaje na UHN, natomiast część użytkownika może migrować na inne węzły. Mimo to, z punktu widzenia użytkownika UHN proces znajduje się w jednej przestrzeni procesów. Przestrzeń tę tworzą dla UHN wszystkie inne węzły klastra. Proces może być w pełni zarządzany z UHN, nawet jeżeli w danym momencie został migrowany na węzeł inny niż UHN. Dla końcowego użytkownika fakt migracji jest przezroczysty, dlatego mówi się o SSI, czyli iluzji pojedynczego systemu z perspektywy przestrzeni procesów. Aby równomiernie rozłożyć obciążenie na węzłach klastra, openMosix stara się ocenić obciążenie każdego z węzłów. W przypadku węzłów posiadających taką sama moc obliczeniową i tyle samo pamięci operacyjnej, zadanie to nie byłoby trudne. Sprowadzałoby się to do oceny obciążenia każdego z węzłów w oparciu o procentową zajętość CPU oraz pamięci operacyjnej i porównania obciążeń. Jednak w heterogenicznym środowisku nie jest to takie łatwe. Przy dodawaniu węzłów do klastra openMosix stara się ocenić moc obliczeniową każdego z węzłów, by następnie móc wprowadzać korekty do algorytmu obliczania obciążenia węzłów. Na podstawie danych pozyskanych według takich kryteriów, openMosix próbuje migrować procesy z bardziej obciążonych węzłów na mniej obciążone. 2.2.1.2. Perspektywa użytkownika Z perspektywy użytkownika zarządzanie procesami odbywa się tak samo, jak na pojedynczej stacji roboczej. Użytkownik nie musi wiedzieć, na którym węźle w danym momencie dany proces pracuje, żeby mu wysłać sygnał. Po prostu wysyła sygnał do procesu na UHN, a openMosix zajmuje się dostarczeniem go do odpowiedniego węzła do części 16 systemowej procesu. Równie ważny jest fakt automatycznej migracji procesów celem równoważenia obciążenia. Użytkownik może ingerować w proces migracji, jednak jest to całkowicie opcjonalne. Ingerencja może polegać na zakazaniu lub nakazaniu migracji a'priori, czy też wręcz na przemieszczaniu procesów między poszczególnymi węzłami. Jeżeli jednak użytkownik zdecyduje się nie wnikać w szczegóły pracy klastra, openMosix zajmie się tym za niego. Kolejnym zadaniem, przy którym użytkownik, a dokładniej – administrator jest wyręczany, jest proces dodawania i usuwania węzłów do/z klastra. Tradycyjnie lista węzłów klastra musiała być zachowana w pliku na każdym z węzłów i uaktualniana przy dodawaniu/usuwaniu węzłów. Obecnie jednym z narzędzi openMosixa jest daemon omdiscd, który jeżeli jest uruchomiony na każdym z węzłów, zajmuje się automatycznym kompletowaniem klastra. Nie istnieje potrzeba administracyjnego formułowania listy węzłów, gdyż daemon omdiscd, przez zastosowanie ruchu sieciowego multicast, wykryje wszystkie węzły i spowoduje, że każdy z nich uzna pozostałe jako części klastra. Przy automatycznym dodawaniu węzła również ma miejsce ocenianie jego mocy obliczeniowej i zasobów pamięciowych, celem wykorzystania tej wiedzy następnie w algorytmie równoważenia obciążenia. 2.2.1.3. Perspektywa systemu plików System plików jest kluczowym elementem pracy procesu. Programy są często tak zaprojektowane, by korzystały z systemu plików do odczytywania i zapisywania danych. Jeżeli dany proces zostanie uruchomiony na UHN i stworzy tam plik /tmp/plik, lecz w wyniku migracji znajdzie się później na innym węźle, to gdy będzie chciał odwołać się do stworzonego wcześniej pliku, okaże się, że go tam nie ma, gdyż został na UHN, gdzie proces nie jest w danym momencie wykonywany. Innym, bardziej ogólnym problemem, jest potrzeba współdzielenia przez wiele węzłów (spośród których każdy ma być UHN dla własnych procesów) tych samych zasobów systemów plików. Zwykle można to osiągnąć przez korzystanie z sieciowego systemu plików NFS, jednak system ten jest daleki od doskonałości. Po pierwsze, występują tradycyjne dla NFS problemy z pamięcią podręczną, znacznikami czasowymi, prawami dostępu do plików, a po drugie, jest to zewnętrzny mechanizm powodujący dodatkowy ruch w sieci. W systemie openMosix istnieje kilka mechanizmów, które zajmują się wyżej wymienionymi problemami. 17 Pierwszym, najbardziej ogólnym sposobem, jest przechwytywanie operacji wejścia/wyjścia. Operacje te są przechwytywane przez węzeł, na którym w danym momencie wykonywany jest proces i kierowane są do UHN, gdzie istnieją fizycznie zasoby, do których proces się odwołuje. Można sobie łatwo wyobrazić, iż proces ten jest stosunkowo wolny, gdyż wymaga narzutu spowodowanego przez przekierowywanie żądań wejścia/wyjścia do UHN, obsługiwanie ich tam i powrót sterowania do węzła, na którym wykonywany jest proces. Drugim, bardziej eleganckim sposobem jest wykorzystanie oMFS, czyli sieciowego systemu plików openMosix File System. 18 2.2.2. openMosix File System oMFS jest systemem plików podobnym w użyciu do NFS [NFSHOWTO], jednak pozbawionym uciążliwych cech NFS związanych z pamięcią podręczną, znacznikami czasowymi, prawami dostępu do plików, etc. Dzięki zamontowaniu systemu plików oMFS na danym węźle, każdy proces uruchomiony na nim otrzymuje dostęp do dowolnego pliku na dowolnym węźle klastra. Wyjątek stanowią zawartości katalogów /proc węzłów oraz pliki specjalne, np. pliki urządzeń – do tych plików umieszczonych na węzłach nie można uzyskać dostępu przez oMFS. Idea oMFS została zobrazowana na diagramie nr . Zakłada się, że w klastrze istnieją węzły o numerach ID 1, 2, 5. Przedstawiono uproszczoną zawartość katalogu głównego każdego z węzłów oraz zawartość zamontowanego systemu oMFS w katalogu /mfs jednego z węzłów. 1 === | `-bin `-etc `-home `-usr 2 === | `-bin `-boot `-etc `-home 5 === | `-etc `-home `-sbin `-usr (dowolny) ========= | ... | `-mfs | `-1 | `-bin | `-etc | `-home | `-usr `-2 | `-bin | `-boot | `-etc | `-home `-5 `-etc `-home `-sbin `-usr Diagram 1. Połączenia między węzłami klastra w obrębie oMFS 19 Widać jak każdy z węzłów ma dostęp do systemów plików każdego z pozostałych węzłów klastra. Oprócz tej ogólnej zasady, w katalogu /mfs znajdują się również następujące specjalne katalogi, które są de facto niemodyfikowalnymi dowiązaniami symbolicznymi do katalogów reprezentujących systemy plików różnych węzłów. Ich znaczenie zależne jest od nazwy: • /mfs/here - bieżący węzeł • /mfs/home - węzeł UHN • /mfs/magic - jest to bieżący węzeł, jeżeli ścieżka użyta jest przy wywołaniu systemowym tworzącym plik (creat bądź open z opcją O_CREAT), a w innym przypadku jest to węzeł, na którym ostatnio proces stworzył plik przez oMFS; mechanizm przydatny przy wykorzystywaniu plików tymczasowych • /mfs/lastexec - węzeł, na którym proces ostatnio z powodzeniem wykonał wywołanie systemowe execve • /mfs/selected - węzeł zaznaczony (ang. selected) przez dany proces lub jednego z jego przodków przez zapisanie liczby do pliku /proc/self/selected. System plików oMFS jest obecnie wyposażony w mechanizm DFSA – Direct File System Access, czyli bezpośredni dostęp do systemu plików. Umożliwia on przezroczysty dostęp do zasobów systemu plików UHN dla wywołań systemowych procesu wykonywanego na innym węźle przez system plików oMFS. Bez uruchomionego mechanizmu DFSA, oMFS nadal będzie udostępniał zdalne systemy plików, jednak uruchomione na węzłach procesy nie będą mogły z nich przezroczyście korzystać. Co więcej, dzięki DFSA openMosix dokonuje oceny, czy bardziej korzystnie jest kontynuować wykonywanie danego procesu zdalnie i udostępniać mu dane przez sieć, czy przywołać go z powrotem do UHN, gdzie dane są dostępne lokalnie. Zalecane jest łączenie w klaster openMosix komputerów, które pracują pod kontrolą tak samo skonfigurowanego podsystemu openMosix w jądrze. Ma to znaczenie w szczególności dla pracy DFSA. Należy ponadto zwrócić uwagę na to, by na każdym z węzłów numery użytkowników (UID) oraz grup (GID) były takie same dla tych samych nazw użytkowników i grup. Również nie należy się przejmować wynikiem polecenia df, podającego rozmiar oraz zajętość zamontowanych systemów plików w systemie operacyjnym, gdyż często ma miejsce błędny odczyt pojemności i zajętości zamontowanego oMFS. 20 2.3. Konfiguracja openMosixa Konfiguracja systemu openMosix polega przede wszystkim na ustaleniu składu klastra. Wszystkie węzły muszą posiadać taką samą informację co do listy wszystkich węzłów klastra. Istnieją dwa podejścia do ustalenia tej konfiguracji – tradycyjnie, w sposób statyczny, oraz w sposób dynamiczny. 2.3.1. Konfiguracja statyczna Tradycyjnie listę węzłów klastra definiuje się w pliku /etc/openmosix.map. Składnia tego pliku jest nieskomplikowana. Pojedyncza linia pliku definiuje jedną (lub więcej w przypadku przedziału) relację „jeden do jednego” między numerami IP węzłów klastra a ich numerami ID wewnątrz openMosixa. Możliwe jest także definiowanie relacji „jeden do wiele” dzięki słowu kluczowemu ALIAS (patrz niżej). Każda linia musi zawierać 3 pola: • numer ID węzła (ew. pierwszy numer ID w przedziale) • numer IP węzła (ew. pierwszy numer IP przedziału) lub nazwa z systemowej bazy danych DNS /etc/hosts odpowiadająca temu węzłowi • ilość węzłów w przedziale. Jak wspomniano wyżej, pojedyncza linia może definiować pojedynczą relację, lub grupę relacji między przedziałem numerów ID, a równej liczebności przedziałem numerów IP. Jeżeli trzecie pole linii, czyli liczba definiująca ilość węzłów w przedziale, będzie równa 1, wówczas definiowane jest pojedyncze mapowanie IP ↔ ID. Jeżeli jednak liczba ta jest większa niż 1, podany we wcześniejszych polach nr ID oraz nr IP stają się pierwszymi numerami z przedziału o liczebności określonej przez ową liczbę. Należy zwrócić uwagę na zasadę, że gdy definiowany jest przedział, drugie pole musi być koniecznie numerem IP – nie może być to nazwa z /etc/hosts. Trzecie pole może również zająć specjalny parametr – słowo kluczowe ALIAS. W przypadku napotkania na taką wartość, parser pliku konfiguracyjnego traktuje relację jako przypisanie kolejnego numeru IP do danego numeru ID węzła. Numer ID występujący w linii ze słowem ALIAS musi występować również w innej linii bez tego słowa. 21 Składnię najlepiej zobrazuje przykład. Zakładając, iż w systemowej bazie danych DNS znajdującej się w pliku /etc/hosts zdefiniowane są nazwy: 10.10.10.1 wezel1.domena.com 10.10.10.3 wezel3.domena.com to następujące trzy zawartości pliku konfiguracyjnego /etc/openmosix.map będą sobie równoważne: 1 2 3 4 wezel1.domena.com 10.10.10.2 wezel3.domena.com 10.10.10.4 (a) 1 1 1 1 1 2 3 4 10.10.10.1 10.10.10.2 10.10.10.3 10.10.10.4 (b) 1 1 1 1 10.10.10.1 (c) 4 1 Diagram 2. Trzy równoważne zawartości pliku konfiguracyjnego /etc/openmosix.map Wszystkie trzy definiują cztery relacje między numerami ID węzłów 1, 2, 3, 4, a numerami IP odpowiednio 10.10.10.1, 10.10.10.2, 10.10.10.3, 10.10.10.4. Poniższe linie obrazują użycie słowa kluczowego ALIAS: 1 2 3 4 4 10.10.10.1 10.10.10.2 10.10.10.3 10.10.10.4 192.168.0.1 1 1 1 1 ALIAS Diagram 3. Użycie słowa kluczowego ALIAS w pliku konfiguracyjnym /etc/openmosix.map 22 Zdefiniowano w ten sposób adres IP 192.168.0.1 jako drugi adres (oprócz 10.10.10.4) należący do węzła o ID 4. Aby zainicjować węzeł, czyli dołączyć go do klastra openMosixa, należy użyć polecenia setpe: # setpe -w -f /etc/openmosix.map Należy w ten sposób zainicjować każdy -f /sciezka/do/pliku/openmosix.map nie z jest węzłów. podany, Jeżeli parametr konfiguracja jest pobierana ze standardowego wejścia. Aby odłączyć dany węzeł od klastra, należy wykonać polecenie: # setpe -off W systemie operacyjnym Debian, o który jest oparty cdlinux.pl oraz klastrowy cdlinux.pl, inicjacja oraz wyłączenie openMosixa ma miejsce w skrypcie inicjacyjnym /etc/init.d/openmosix. 2.3.2. Konfiguracja dynamiczna – automatyczne odkrywanie Przy niewielkiej ilości komputerów przeistoczenie ich w węzły klastra nie nastręcza dużej trudności – wystarczy na każdym z nich wygenerować krótki plik /etc/openmosix.map. Jednak wraz ze zwiększającą się liczbą węzłów klastra, proces ten jest coraz bardziej uciążliwy. Ponadto w idealnym systemie SSI nowe węzły powinny dołączać się do klastra bez potrzeby ingerencji użytkownika i bez zakłócenia pracy klastra. Podobnie powinno być z odłączaniem się węzłów od klastra. W systemie openMosix z pomocą przychodzi daemon omdiscd, czyli openMosix Discovery Daemon. Jest to program działający w tle i jeżeli zostanie uruchomiony na każdym z węzłów, klaster w ten sposób obsługiwany będzie posiadał właściwość swobodnego przyłączania i odłączania węzłów. Program ten, po zainicjowaniu, wysyła okresowo pakiety IP typu multicast (kierowane do grup hostów), dzięki którym inne instancje omdiscd wiedzą o jego istnieniu. Po wykryciu następuje wymiana informacji węzła z resztą klastra i następnie węzeł zostaje dołączony do klastra tak, jak gdyby jego adres IP mieścił się w pliku /etc/openmosix.map na wszystkich węzłach. 23 Interesującym programem użytkowym jest program showmap. Pozwala on na wyświetlenie listy węzłów klastra, co jest szczególnie przydatne przy opieraniu się na mechanizmie omdiscd. Jego składnia użycia jest trywialna – nie przyjmuje żadnych parametrów z linii poleceń: # showmap My Node-Id: 0x0052 Base Node-Id -----------0x0052 0x0001 Address ---------------172.0.0.82 172.0.0.1 Count ----1 1 Diagram 4. Wynik działania programu showmap Z treści wyniku programu zrozumieć należy, iż został on uruchomiony na węźle o numerze ID 0x0052, natomiast cały klaster składa się z dwóch węzłów o numerach ID 0x0052 i 0x0001. Są to reprezentacje szesnastkowe liczb, podczas gdy w przedstawieniu dziesiętnym jest to ID 82 oraz 1. Węzły o tych ID mają na interfejsach, przez które łączą się z klastrem, numery IP odpowiednio 172.0.0.82 oraz 172.0.0.1. Warto zauważyć, iż automatycznie przydzielone przez omdiscd numery ID węzłom klastra pokrywają się z ostatnimi dwoma członami numerów IP tych węzłów. Gdyby zdefiniowany w /etc/openmosix.map został przedział węzłów, trzeci parametr powyższego wyniku, czyli Count, miałby wartość różną od 1. Sytuacja taka ma również miejsce, gdy używany jest mechanizm automatycznego wykrywania, gdzie numery ID (które są obliczane z numerów IP) węzłów następują po sobie. Dla przykładu, jeżeli klaster składa się z dwóch węzłów o numerach IP 192.168.1.10 oraz 192.168.1.11, wynik polecenia showmap może wyglądać następująco: # showmap My Node-Id: 0x010a Base Node-Id Address Count ------------ ---------------- ----0x010a 192.168.1.10 2 Diagram 5. Wynik działania showmap dla numerów ID węzłów następujących po sobie 24 2.4. Oprogramowanie monitorujące openMosixview Oprócz możliwości monitorowania i sterowania klastrem z powłoki systemowej Linuxa, istnieje możliwość wykorzystania w tym celu interfejsu graficznego. Obecnie najbogatszym w funkcjonalność tego typu oprogramowaniem jest pakiet openMosixview [OMVWWW]. Pozwala on na łatwe monitorowanie każdego z węzłów klastra pod kątem wykorzystania jego mocy obliczeniowej, pamięci, ilości procesów uruchomionych, sprawności rozkładania obciążenia, etc. Pozwala na zdalne zarządzanie węzłami klastra przez graficzny interfejs, umożliwia ręczną migrację procesów na dowolne węzły klastra, pozwala kontrolować automatyczną migrację i przedstawia wyniki graficznie. Pakiet openMosixview zawiera następujące programy: • openMosixview - główna aplikacja służąca do monitorowania oraz zarządzania • openMosixprocs - narzędzie służące do zarządzania procesami • openMosixcollector - daemon zbierający statystyki pracy klastra • openMosixanalyzer - program przedstawiający statystyki pracy klastra w postaci wykresów • openMosixhistory - program wyświetlający listę procesów pracujących w klastrze w funkcji czasu • openMosixmigmon - narzędzie graficznie przedstawiające węzły oraz pracujące na nich procesy 2.4.1. Zdalne zarządzanie węzłami Bardzo użyteczną cechą openMosixview jest możliwość zdalnego zarządzania węzłami klastra. Aby tego dokonać, openMosixview używa standardowych mechanizmów UNIXowych – otwiera sesję na zdalnym systemie operacyjnym przez sieć przy użyciu protokołów zdalnej pracy rsh lub ssh. Pierwszy z protokołów jest w obecnych czasach rzadko używany, gdyż jego zdolności uwierzytelniania klientów są bardzo ograniczone. Opierają się one na adresie IP, bądź nazwie hosta, z której następuje połączenie i na nazwie użytkownika, który nawiązuje połączenie. Występuje również warunek, by połączenie mogło być nawiązywane tylko z portów o numerach poniżej 1024. Na maszynach klasy UNIX ogranicza to właściciela nawiązującego połączenie procesu do administratora, co powinno zapewnić, iż nazwa użytkownika nie 25 będzie fałszowana. Oczywiście ten typ uwierzytelniania ma zastosowanie tylko w zamkniętych środowiskach, na przykład w pracowni komputerowej szkoły, gdzie wykluczona jest modyfikacja systemu przez złośliwego użytkownika. Drugi z protokołów, czyli ssh, jest potomkiem rsh, jednak ze wsparciem dla szyfrowania. Dzięki zastosowaniu szyfrowania, protokół został wzbogacony o szereg możliwych mechanizmów uwierzytelniania, na przykład przez hasło, czy przez klucz publiczny. Drugą zaletą szyfrowania jest fakt, iż cała transmisja między serwerem, a klientem, jest utajniona. Uzyskuje się to dzięki szyfrowaniu symetrycznemu kluczem sesyjnym, czyli takim, który jest wybierany przez obydwie strony przed nawiązaniem szyfrowanego połączenia i niszczony zaraz po rozwiązaniu połączenia. Mechanizm uwierzytelniania w oparciu o klucz publiczny znalazł zastosowanie w klastrowym cdlinux.pl w programie openMosixview. Polega on na użyciu wygenerowanej uprzednio pary kluczy kryptografii asymetrycznej według algorytmu RSA lub DSA. Klucz publiczny z owej pary zostaje umieszczony na serwerze, natomiast klucz prywatny pozostaje u klienta. Gdy klient próbuje się podłączyć do serwera i ustanowić połączenie szyfrowane, obydwa klucze, prywatny i publiczny, są użyte do zweryfikowania, iż klient ma prawo dostępu do serwera. Na podstawie jednego z kluczy nie jest możliwe wygenerowanie w rozsądnym czasie pasującego do niego drugiego klucza, zatem o ile klucz prywatny jest zabezpieczony u klienta, taka metoda uwierzytelniania jest bezpieczna. W wersji programu ssh, która została użyta w klastrowym cdlinux.pl, konfiguracja uwierzytelniania w oparciu o klucz publiczny jest następująca [MAN1]. Gdy wygenerowane zostaną klucze za pomocą narzędzia ssh-keygen, powstają dwa pliki: jeden zawiera klucz prywatny, drugi – klucz publiczny. Jeżeli wybranym protokołem jest RSA, są to domyślnie pliki ~/.ssh/id_rsa i ~/.ssh/id_rsa.pub, natomiast jeżeli protokołem jest DSA, pliki noszą nazwy ~/.ssh/id_dsa i ~/.ssh/id_dsa.pub (znak „~” oznacza katalog domowy użytkownika). Jak wspomniano wcześniej, klucz publiczny zostaje na serwerze i powinien być umieszczony w pliku ~/.ssh/authorized_keys, natomiast klucz prywatny pozostaje u klienta i domyślnie jest pobierany z pliku ~/.ssh/id_dsa lub ~/.ssh/id_rsa. Jeżeli klient pragnie mieć możliwość wyboru między wieloma kluczami, należy nazwę pliku z kluczem podawać przy logowaniu się dzięki parametrowi -i nazwapliku do programu ssh. 26 Aby uprościć problem, w klastrowym cdlinux.pl jest używana jedna para kluczy dla każdego z węzłów klastra. Na kontrolerze klastra umieszczony jest klucz prywatny, natomiast klucz publiczny przebywa w katalogu, który w pozostałych węzłach klastra zostanie skopiowany jako ~/.ssh/. Skutkiem tego z kontrolera klastra można będzie otworzyć sesję na każdym z węzłów klastra bez podawania hasła. Jest to nieodzowne dla działania programu openMosixview, który polega właśnie na otwieraniu sesji na zdalnym komputerze (węźle klastra) bez ingerencji użytkownika. 2.4.2. Główne okno programu Po uruchomieniu openMosixview zostaje zaprezentowane główne okno programu, gdzie w górnej części widać menu, poniżej ikony uruchamiające niektóre funkcje dostępne przez menu, dalej są paski symbolizujące pracę klastra. Każdy z pasków przedstawia pewne dane dotyczące danego węzła klastra, natomiast pierwszy pasek pokazuje dane dotyczące pracy całego klastra (specjalne znaczenie jego pól podano poniżej w nawiasach): • numer ID węzła (ew. słowo all oznaczające, że chodzi o pracę całego klastra) • numer IP węzła (ew. słowo all-nodes) • szacowana moc obliczeniowa węzła (ew. sprawność mechanizmu rozkładania obciążenia w klastrze) • obciążenie węzła (ew. ogólne obciążenie klastra) • zajętość pamięci operacyjnej węzła (ew. ogólna zajętość pamięci klastra) • całkowita pamięć węzła (ew. całego klastra) • ilość CPU węzła (ew. ilość wszystkich CPU w klastrze) Wszystkie z powyższych pól są aktualizowane na bieżąco – domyślnie co 5 sekund, przy czym parametr ten można zmienić w polu oznaczonym refresh. Gdy nowe węzły zostają dołączone do klastra, powstają dla nich nowe paski w oknie programu. Gdy węzły opuszczają klaster, paski nie są usuwane, natomiast w pierwszym polu numer ID danego węzła zmienia tło z zielonego na czerwone, żeby oznaczyć, że węzeł o tym ID już nie działa. 27 Ilustracja 1. Główne okno programu OpenMosixview Pole opisane wyżej jako szacowana moc obliczeniowa węzła jest przedstawione graficznie jako suwak. Dzięki temu można tę moc administracyjnie zmieniać przez przemieszczanie suwaka. Pozwala to na modelowanie obciążenia poszczególnych węzłów klastra, na przykład gdy któreś węzły mają być mniej obciążone przez podsystem openMosix – administrator może życzyć sobie więcej niewykorzystanej mocy obliczeniowej na którymś węźle, by zapewnić szybszy czas reakcji na uruchamianie nowych procesów. Pole określające numer IP węzła jest przyciskiem. Po jego naciśnięciu otwarte zostaje okno dialogowe, które umożliwia zdalne zarządzanie węzłami klastra. Tym samym sposobem można również zarządzać węzłem, na którym openMosixview jest uruchomiony. Ponadto, można zarządzać wszystkimi węzłami jednocześnie poprzez użycie przycisku w pierwszym pasku głównego okna, który w polu IP ma wpisane all-nodes. Omawiane okno dialogowe widać na ilustracji nr 2. Ilustracja 2. Okno umożliwiające zdalne zarządzanie węzłem klastra 28 W nowo otwartym oknie dialogowym można kontrolować następujące parametry, które w większości odpowiadają rozkazom wydawanym przez narzędzie mosctl: • auto-migration on/off – automatyczna migracja procesów z węzła; odpowiada rozkazowi mosctl automigration • talk to other nodes – przekazywanie w tle przez węzeł informacji statystycznych dotyczących obciążenie, zużycia pamięci, etc., innym węzłom; odpowiada rozkazowi mosctl quiet • local procs stay – lokalne procesy nie są automatycznie migrowane, a te, które zostały wcześniej zmigrowane, są ściągnięte z powrotem do UHN; procesy, które zmigrowały na dany węzeł wcześniej, są nadal podatne na automatyczną migrację zgodnie z ustawieniem parametru auto-migration; odpowiada rozkazowi mosctl bring lub mosctl lstay • send away guest procs – procesy, które zmigrowały na dany węzeł, zostają wydalone; odpowiada rozkazowi mosctl expel • start/stop – uruchamianie, bądź zatrzymanie podsystemu openMosix Można nacisnąć dowolną ilość przycisków, gdyż zmiany przez to wprowadzone zostaną zastosowane dopiero po zatwierdzeniu wszystkiego przyciskiem Apply. Po tym openMosixview nawiązuje połączenie z węzłem, na którym mają być dokonane zmiany, przez rsh/ssh i wykonuje na zdalnym węźle określone polecenia. Po skończeniu wykonywania poleceń połączenie zostaje rozwiązane. 2.4.3. Zarządzanie procesami przez openMosixprocs Programem również wchodzącym w skład openMosixview jest openMosixprocs. Jest to program, który powinien być zainstalowany na każdym z węzłów – nie tylko na tym, na którym będzie uruchomiony openMosixview. Program służy do wyświetlania listy procesów danego węzła podobnie do narzędzia systemowego top z zaznaczeniem numerów węzłów, na których aktualnie wykonywane są poszczególne procesy. 29 Oprócz wyświetlania, na każdym procesie z listy wykonać można szereg operacji. Podstawowymi są takie naturalne, jak zabicie procesu, czy modyfikacja jego priorytetu (ang. niceness), jednak większość stanowią operacje specyficzne dla openMosixa. Są to: • send to home node – wysłanie procesu do UHN • send to best node – wysłanie procesu do węzła, który najlepiej go obsłuży z punktu widzenia równoważenia obciążenia klastra • lock process – zablokuj proces, czyli zakaż procesowi migracji na inne węzły • unlock process – odblokuj proces, czyli pozwól zablokowanemu wcześniej procesowi na migrację na inne węzły • log process – nakaż logowanie informacji o danym procesie • send SIGSTOP – wyślij sygnał SIGSTOP do procesu, co powinno spowodować jego zatrzymanie (lecz nie zabicie) • send SIGCONT – wyślij sygnał SIGCONT do procesu zatrzymanego wcześniej sygnałem SIGSTOP w celu wznowienia jego wykonywania. Poniższe ilustracje przedstawiają okno główne programu openMosixprocs (ilustracja nr 3) oraz okno, które się pojawia podwójnym kliknięciu na którejś z pozycji listy procesów (ilustracja nr 4). Ilustracja 3. Główne okno programu OpenMosixprocs 30 Ilustracja 4. Okno programu OpenMosixprocs umożliwiające wykonanie operacji na danym procesie 2.4.4. Statystyki Program openMosixcollector jest daemonem, który nie jest konieczny do pracy klastra. Zapewnia on jednak zbieranie informacji o pracy klastra. Wystarczy, jeżeli zostanie uruchomiony na jednym z węzłów klastra, by rejestrować informację o pracy każdego z jego węzłów: obciążenie, zajętość pamięciową, wszystkie procesy uruchomione na węzłach, etc. Dane zgromadzone przez openMosixcollector mogą być następnie wykorzystane off-line przez programy openMosixanalyzer oraz openMosixhistory. 31 Pierwszy z wyżej wymienionych programów dokonuje analizy pracy klastra i prezentuje na wykresach obciążenie całego klastra, jak i jego poszczególnych węzłów w funkcji czasu. Podobne statystyki są dostępne dla zużycia pamięci. Dodatkowo openMosixanalyzer pozwala na aktualizację wykresów na bieżąco, co pomaga wykryć od razu anomalie w działaniu klastra. Oprócz możliwości wyświetlania danych na ekranie dostępne są także funkcje wydruku. Główne okno programu openMosixanalyzer widoczne jest na ilustracji nr 5. Ilustracja 5. Główne okno programu OpenMosixAnalyzer Drugi z procesorów zebranych danych – openMosixhistory – pozwala na zestawienie w postaci listy procesów działających na każdym z węzłów w funkcji czasu. Wyświetlane są jedynie procesy, dla których węzłem UHN był węzeł, na którym został uruchomiony openMosixcollector. Dane te nie mają charakteru skalarnego, zatem nie mogą być przedstawione na prostym wykresie dwuwymiarowym. Funkcja czasu rozstała zrealizowana jako suwak, który wybiera interesujący moment, po czym w umieszczonym poniżej polu wyświetla się lista procesów pracujących w klastrze w danym momencie. Dodatkowo można wyświetlać procesy tylko zadanego właściciela, którego wybiera się z rozwijanej listy. 32 Ilustracja 6. Główne okno programu openMosixHistory 2.4.5. Graficzny monitoring i zarządzanie - openMosixmigmon Ostatnim elementem pakietu jest program openMosixmigmon. Jest to program przedstawiający graficznie węzły klastra. Węzeł UHN procesu openMosixmigmon jest wyświetlony w centrum, natomiast pozostałe węzły rozmieszczone są naokoło. Wszystkie procesy, dla których węzeł centralny jest węzłem UHN, zaznaczone są małymi kwadratami naokoło węzła, na którym obecnie są wykonywane. Inicjalnie wszystkie kwadraty powinny być skupione przy węźle centralnym (swoim UHN), natomiast po migracji kwadrat procesu przenosi się w sąsiedztwo węzła, na który zostaje zmigrowany i nakreślona zostaje linia między kwadratem przy nowym węźle, a centralnym. Oprócz monitoringu openMosixmigmon wspiera zarządzanie procesami. Można tego dokonać poprzez kliknięcie na kwadracie symbolizującym proces i przeciągnięcie go w okolicę innego węzła. Proces ten zostanie zmigrowany, o ile jest to możliwe, na wskazany węzeł. Dla ułatwienia migracji wielu procesów, kwadraty można zaznaczać, tym samym tworząc grupy kwadratów-procesów, które można jednocześnie przeciągnąć wskaźnikiem myszy do innego węzła. Jest możliwość stworzenia w ten sposób do dziesięciu grup, każdej 33 oznaczonym innym kolorem wybieranym przyciskami na górze ekranu. Zaznaczenia grupy dokonuje się przez zakreślenie prostokątnego obszaru lewym przyciskiem myszy, bądź przez zaznaczenie poszczególnych kwadratów prawym przyciskiem myszy. Na ilustracji nr 7 widać klaster składający się z dwóch węzłów o ID równych 266 oraz 267. Na pierwszym z nich uruchomiony został openMosixmigmon, dlatego węzeł ten jest w centrum. Wszystkie procesy, dla których węzeł centralny jest UHN, są wykonywane na nim. Ilustracja 7. Okno programu openMosixMigmon. Wszystkie procesy są na węźle domowym 34 Na ilustracji nr 8 widać ten sam klaster, jednak część procesów z węzła 266 została zmigrowana na węzeł 267. Procesy zostały podzielone na klika grup oznaczonych różnymi kolorami. Ilustracja 8. Okno programu openMosixMigmon. Procesy podzielone zostały na kilka grup (oznaczonych różnymi kolorami). Część z procesów została zmigrowana na drugi węzeł klastra. 2.5. Wykorzystanie środowiska openMosix w klastrowym cdlinux.pl W systemie operacyjnym będącycm przedmiotem pracy użyto technologii openMosix jako środowiska klastrowego. Jądro systemu Linux zostało odpowiednio zmodyfikowane oraz zainstalowane zostały narzędzia przestrzeni użytkownika wspomagające zarządzanie klastrem. Dołożono wszelkich starań, aby proces tworzenia klastra przy starcie systemów operacyjnych wchodzących w jego skład był jak najbardziej zautomatyzowany. 35 Zastosowano konfigurację dynamiczną klastra opartą o daemon omdiscd, który jest konfigurowany do pracy zawsze na interfejsie eth0 węzłów. Wyjątkiem jest kontroler klastra, na którym interfejs jest „odgadywany” z konfiguracji podanej przez użytkownika w programie yahade. Wykorzystano system plików oMFS, który na każdym z węzłów klastra montowany jest przy uruchamianiu systemu w katalogu /mfs. Pracę oMFS wspomaga algorytm DFSA. Dodatkowo, dla zapewnienia systemów plików dla węzłów zastosowano mechanizm NFS. Głównym powodem, dla którego zdecydowano się nie polegać wyłącznie na oMFS, był brak wsparcia w systemie Liux dla uruchamiania systemu operacyjnego przez sieć w oparciu o oMFS. Szczegóły inicjacji podsystemu openMosix oraz jego budowy zebrane zostały w następnych częściach pracy. 36 3. Uruchamianie systemu operacyjnego Tradycyjnie system operacyjny Linux uruchamiany jest, jak każdy inny system operacyjny, z szybkiego, wysoko pojemnego nośnika z możliwością zapisu, na przykład z dysku twardego. W przypadku cdlinux.pl jest to nośnik bez możliwości zapisu oraz o stosunkowo niewielkiej prędkości odczytu – CD-ROM. Z tego powodu proces uruchamiania różni się, zwłaszcza w fazach początkowych, od przeciętnej dystrybucji Linuxa. Proces uruchamiania systemu klastrowy cdlinux.pl zaprojektowano na podobieństwo cdlinux.pl – został wzbogacony o dodatkowe funkcje specyficzne dla funkcjonowania klastra oraz uruchamiania systemu operacyjnego przez sieć komputerową. W niniejszym rozdziale omówiono szczegółowo proces uruchamiania się wykonanego w ramach pracy systemu operacyjnego. Przedstawiono sposób uruchamiania w dwóch wersjach: kontrolera klastra oraz jegnego z pozostałych węzłów klastra. Dodatkowo zamieszczono opisy ważniejszych technologii użytych w budowie systemu. 3.1. Uruchamianie kontrolera klastra Możliwe jest wyodrębnienie kilku faz uruchamiania kontrolera klastra systemu operacyjnego klastrowy cdlinux.pl: • wczytanie programu ładującego Linuxa (SYSLINUX) przez mechanizm El Torito, • uruchomienie jądra Linuxa wraz z początkowym ramdiskiem (initrd), • przygotowanie systemów plików na podstawie obrazów z CD-ROMu, • oddanie kontroli do standardowych skryptów inicjacyjnych zapożyczonych z dystrybucji Debian, pomiędzy którymi uruchomiony zostaje konfigurator yahade, • uruchomienie rozszerzeń względem cdlinux.pl, czyli np. serwerów dhcpd, atftpd, portmap, skonfigurowanie serwera NFS, zainicjowanie podsystemu openMosix. W poniższej części zostaną szczegółowo omówione powyższe fazy. Szczególny nacisk zostanie położony na elementy różniące się od systemu operacyjnego cdlinux.pl. 37 3.1.1. Wczytanie programu ładującego Linuxa System operacyjny ładowany jest z płyty CD-ROM. Tradycyjnie komputery PC potrafiły uruchamiać system operacyjny z dyskietki bądź z dysku twardego. Uruchamianie z CD-ROMu umożliwia standard El Torito. 3.1.1.1. El Torito El Torito jest specyfikacją opracowaną w roku 1994 przez dwie firmy: Phoenix Technologies i IBM [ELTORITO]. Jest rozszerzeniem oryginalnej specyfikacji nośnika danych CD-ROM (czyli ISO 9660) polegającym, między innymi, na dodaniu funkcjonalności uruchamiania systemu z CD-ROMu. W rzeczywistości omawiana specyfikacja jest bogatsza, lecz obecne systemy komputerowe rzadko cechują się kompletnymi jej implementacjami. Standard ISO 9660 przewiduje istnienie na początku sesji CD-ROMu deskryptorów woluminów (volume descriptors), które opisują kolejne woluminy zawierające dane dostępne w systemach operacyjnych dzięki sterownikom napędów CD-ROM. Pierwszy Deskryptor Woluminu (Primary Volume Descriptor) znajduje się w sektorze nr 0x10 (16 dziesiętnie, licząc od początku sesji), za nim znajduje się szereg innych deskryptorów, który jest zakończony tzw. Terminatorem Zestawu Deskryptorów Woluminu (Volume Descriptor Set Terminator). Specyfikacja El Torito określa, iż deskryptor odpowiedzialny za uruchamianie systemu, czyli Rekord Ładujący, ma się znajdować zaraz za Pierwszym Deskryptorem Woluminu, czyli w sektorze nr 0x11 (17 dziesiętnie). Deskryptor ten wskazuje na Katalog Uruchomieniowy (Boot Catalog), który zawiera elementy opisujące jeden lub więcej obrazów uruchomieniowych (boot images). Każdy taki obraz może być wczytany do pamięci w celu inicjacji za jego pomocą systemu operacyjnego, jak i może być użyty do emulacji dyskietki, dysku twardego. Należy zauważyć, iż dany obraz może nie emulować żadnego nośnika danych – tryb brak emulacji (no emulation), – wtedy jest on tylko nosicielem kodu inicjującego system operacyjny. Z drugiej strony, obraz może nie mieć statusu uruchamialnego i wtedy nie zawiera żadnego kodu inicjującego, a emulacja polega na umieszczeniu go jako ostatniego urządzenia widzialnego przez BIOS (np. za stacjami dysków elastycznych i dyskami twardymi). 38 Konfiguracja z pojedynczym obrazem uruchomieniowym Konfiguracja zwykłego CD-ROMu Sektor 0 Sektor 0 System (nieużywany) Sektor 16 Sektor 16 Sektor 17 Deskryptory Woluminów System (nieużywany) Pierwszy Deskryptor Rekord Ładujący ... Terminator Zestawu Deskryptorów Obraz CD-ROM Katalog Uruchomieniowy pierwsza pozycja Obraz CD-ROM Obraz Ładowalny Obraz CD-ROM Obraz CD-ROM Diagram 6. Struktura płyty CD-ROM zwykłej oraz w formacie El-Torito [ELTORITO] Wiele możliwych obrazów uruchomieniowych stwarza możliwość wyboru obrazu do uruchomienia przez BIOS. Przewidywany były np. możliwości uruchamiania kilku wersji programów, czy też całych systemów operacyjnych, znajdujących się w różnych obrazach uruchomieniowych, różniących się np. językiem. Uruchamiany byłby taki obraz, który pasowałby charakterystyką do systemu BIOS danego komputera. Autorowi nie są znane przypadki implementacji takiej funkcjonalności w przeciętnych systemach komputerowych. 39 3.1.1.2. SYSLINUX Aby uruchomić system operacyjny z CD-ROMu, musi zostać włączony z płyty program ładujący. W przypadku cdlinux.pl, jak i klastrowy cdlinux.pl, jest to program SYSLINUX dostępny z serwisu WWW dostępnego w [SYSLINUXWWW]. SYSLINUX jest rozbudowanym projektem. Jego podstawowa odmiana pozwala na uruchamianie systemu operacyjnego Linux spod systemu operacyjnego MS-DOS z systemu plików typu FAT. Pozwala na przekazywanie opcji do jądra systemu Linux podobnie, jak popularny program ładujący lilo, jednak jest bardzo wygodny w sytuacjach, gdzie niepożądana jest ingerencja w rekordy ładujące dysku twardego tak, jak by to było w przypadku korzystania z lilo. System operacyjny uruchamiany poprzez SYSLINUX wymaga jedynie stworzenia pliku konfiguracyjnego w systemie plików FAT, czyli np. używanym przez MS-DOS/Windows – jego ingerencja w istniejące struktury jest minimalna. Konfiguracja programu SYSLINUX zadawana jest przez plik konfiguracyjny syslinux.cfg. Zdefiniowany może być w nim jeden, bądź więcej wariantów uruchomienia systemu operacyjnego Linux. Pojedynczy wariant opisywany jest przez szereg dyrektyw, spośród których część jest specyficzna dla danego wariantu, natomiast pozostałe mogą być globalne. Globalne dyrektywy umieszcza się na początku pliku konfiguracyjnego, natomiast specyficzne dla danego wariantu uruchomienia występują po dyrektywie LABEL, która też identyfikuje wariant przez unikalną nazwę. Przy uruchamianiu kontrolera klastra użyty został program stanowiący jedną z gałęzi SYSLINUXa – ISOLINUX. Jest to odmiana pozwalająca na uruchamianie Linuxa z CD-ROMu poprzez mechanizm El Torito (opisany wyżej). Uruchamiany program ładujący działa w trybie braku emulacji, czyli wczytany jest kod programu (który ma dostęp do danych w obrazie ładującym poprzez przerwanie INT 13h), lecz obraz ładujący nie jest użyty do emulacji dyskietki, czy też twardego dysku. Konfiguracja ISOLINUXa następuje poprzez plik konfiguracyjny isolinux.cfg. Jego składnia jest identyczna ze składnią pliku konfiguracyjnego bazowej części programu, czyli z plikiem syslinux.cfg, która przybliżona została powyżej. 40 Ilustracja 9. Ekran powitalny podczas uruchamiania klastrowego cdlinux.pl Po wczytaniu do pamięci, ISOLINUX przedstawia użytkownikowi możliwość wyboru między różnymi zdefiniowanymi w pliku konfiguracyjnym wariantami uruchomienia. Każdy z wariantów skojarzony jest z plikiem zawierającym jądro Linuxa oraz ewentualnie z plikiem zawierającym obraz początkowego ramdisku (initrd). Po dokonaniu wyboru pliki te są ładowane do pamięci i uruchamiane jest jądro Linuxa. Na ilustracji nr 9 widać ekran powitalny klastreowego cdlinux.pl. Jest to de facto ekran programu ISOLINUX, który po oczekiwaniu na wybór obrazu do uruchomienia, zaczął uruchamiać domyślny obraz, czyli zimage z początkowym ramdiskiem z pliku root.gz. 41 3.1.2. Uruchomienie jądra Linuxa Proces uruchamiania jądra Linuxa nie różni się istotnie od przebiegu uruchamiania jądra w przeciętnych dystrybucjach Linuxa. Cechą wyróżniającą jest tu obecność początkowego ramdisku – initrd [INITRD]. Rozwiązanie oparte o initrd wprowadza dwufazowy tryb inicjacji Linuxa. Program uruchamiający jądro Linuxa ma możliwość stworzenia i załadowania ramdisku (dostępnego jako urządzenie /dev/initrd), który jeżeli załadowany obrazem systemu plików, może być zamontowany jako główny system plików na zakończenie inicjacji jądra. W przeciętnych scenariuszach uruchomienia Linuxa w tym punkcie uruchamiany jest program /sbin/init, który odpowiada za uruchomienie szeregu skryptów przygotowujących środowisko pracy systemu operacyjnego. W omawianym rozwiązaniu, kontrola oddawana jest do programu /linuxrc, jeżeli taki istnieje w systemie plików zamontowanym z ramdisku. Program /linuxrc powinien przygotować docelowy główny system plików, do zamontowania którego być może potrzebne są dodatkowe sterowniki załadowane z początkowego ramdisku. Po zakończeniu jego działania, bądź w trakcie, nowo przygotowany system plików montowany jest jako główny, natomiast dotychczasowy przenoszony jest do katalogu /initrd, jeżeli taki istnieje (w przeciwnym przypadku nie jest możliwe odzyskanie pamięci zużytej na initrd). Po tych operacjach uruchamiany jest /sbin/init. Linux rozpoznaje następujące opcje przekazane w linii poleceń, które wpływają na charakterystykę initrd: initrd=nazwa-pliku Określa plik do załadowania jako zawartość urządzenia /dev/initrd. Opcja ta jest rozpoznawalna przez wszystkie popularne programy ładujące jądro Linuxa – również przez SYSLINUX. Plik w ten sposób przekazany może być skompresowany przez gzip (popularny kompresor systemów UNIX). noinitrd Opcja ta wyłącza dwufazowy tryb uruchamiania, mimo iż urządzenie /dev/initrd jest zainicjowane danymi przez program ładujący. Jako że initrd nie jest montowany jako (główny) system plików, jego zawartość mogą stanowić dowolne dane. Są one dostępne w trybie tylko-do-odczytu przez 42 urządzenie /dev/initrd, z tym że odczyt może nastąpić tylko raz. Po zamknięciu dostępu do urządzenia pamięć zużywana przez initrd jest zwalniana. root=nazwa-urządzenia Określa urządzenie, które ma zostać użyte jako źródło docelowego systemu plików montowanego po zakończeniu działania programu /linuxrc. 3.1.3. Przygotowanie systemów plików W systemie operacyjnym cdlinux.pl zdecydowano się na hybrydowy sposób przechowywania poszczególnych części systemu plików na CD. System klastrowy cdlinux.pl korzysta również z tej struktury wzbogacając ją o dodatkowe katalogi. Poniżej zestawiono wszystkie części systemu plików, z których konstruowany jest klastrowy cdlinux.pl: • katalogi /home, /dev oraz /isolinux zostały przechowane w oryginalnej formie (/isolinux i niektóre pliki z /dev są potrzebne dla programu ładującego ISOLINUX), • katalogi /bin, /boot, /etc, /lib, /root, /sbin, /slave2, /var zostały skompresowane do pojedynczego pliku każdy przy użyciu programów tar i gzip, • katalogi /cdlinux/lib, /cdlinux/usr2, /cdlinux/var, /usr są umieszczone na odrębnych systemach plików cramfs zapisanych w odpowiednich plikach w katalogu /cramfs na CD-ROMie. Część katalogów wymienionych w ostatnim punkcie znajduje się w podkatalogu /cdlinux, gdyż w oryginalnej dystrybucji cdlinux.pl-duży znajdują się one na płycie CD, która jest montowana w katalogu /cdlinux i w tej postaci dostępne są w systemie. Zarówno nośnik CD, jak i system plików cramfs wspierają jedynie tryb tylko-doodczytu, zatem zasobów tam rezydujących nie można w działającym systemie operacyjnym modyfikować. Części systemu, które wymagają możliwości modyfikacji, czyli katalogi wymienione w pierwszych dwóch punktach powyżej, są podczas inicjacji systemu kopiowane do ramdisków. Pierwsza faza przygotowania systemów plików ma miejsce w initrd i jest przeprowadzona przez skrypt /linuxrc. Główny system plików jest stworzony jako ramdisk (w urządzeniu /dev/ram4), zamontowany w katalogu /ramdisk, po czym rozpakowane zostają do niego katalogi /bin, /etc, /lib, /sbin oraz skopiowane są katalogi /dev, /home. Dalej, stworzony 43 jest ramdisk (w urządzeniu /dev/ram1), na którym powstaje system plików ext2. Do tego ramdiska rozpakowane jest archiwum zawierające katalog /slave2. Następnie, jeżeli użytkownik zdecyduje, iż system nie ma podczas pracy korzystać z CD, kopiowane są do ramdiska obrazy systemów plików cramfs z katalogami /cdlinux/lib, /cdlinux/var. Po zakończeniu pracy programu /linuxrc, głównym systemem plików zostaje ramdisk zamontowany dotychczas w katalogu /ramdisk i kontrola przekazana jest do programu /sbin/init. W wyniku jego działania uruchamiane są skrypty z katalogu /etc/init.d, z których jednym z pierwszych jest skrypt /etc/init.d/join. Stanowi on drugą fazę przygotowania systemu plików. W wyniku jego działania tworzony jest ramdisk na urządzeniu /dev/ram5, który jest zamontowany jako system plików tmpfs i rozpakowany jest do niego katalog /root z płyty CD. Podobnie rozpakowany jest katalog /var (na ramdisku /dev/ram6). Następnie jeżeli użytkownik chciał, by system pracował bez płyty CD, stworzone zostają ramdiski /dev/ram2 i /dev/ram3, na które zostają skopiowane obrazy katalogów /usr i /cdlinux/usr2, po czym wszystkie skopiowane na ramdiski obrazy systemów plików zostają zamontowane w katalogach: /cdlinux/lib, /cdlinux/usr2, /cdlinux/var, /slave2, /usr. Jeżeli użytkownik życzył sobie, by system pracował z CD-ROMu, systemy plików /cdlinux/lib, /cdlinux/var, /cdlinux/usr2, /cdlinux/var oraz /usr zamontowane są bezpośrednio z CD-ROMu, co pozwala zaoszczędzić pamięć. Na diagramach przedstawiono strukturę katalogów podczas pracy systemu w oparciu o CD-ROM (diagram nr 7) i bez jego pomocy (diagram nr 8). / `-cdrom `-slave2 `-usr `-root `-var `-cdlinux `-lib `-usr2 `-var <<<<<<- /dev/ram4 /dev/cdrom /dev/ram1 /cdrom/cramfs/usr /dev/ram5 /dev/ram6 <- /cdrom/cramfs/lib <- /cdrom/cramfs/usr2 <- /cdrom/cramfs/var Diagram 7. Sposób montowania katalogów przy pracy z CD-ROM 44 / `-slave2 `-cramfs | `-ram2 | `-ram3 `-usr `-root `-var `-cdlinux `-lib `-usr2 `-var <- /dev/ram4 <- /dev/ram1 <<<<<- /dev/ram2 /dev/ram3 /cramfs/ram3/usr /dev/ram5 /dev/ram6 <- /cramfs/lib <- /cramfs/ram2/usr2 <- /cramfs/var Diagram 8. Sposób montowania katalogów przy pracy bez CD-ROM 3.1.4. Konfigurator yahade Jednym z programów uruchamianych przez /sbin/init jest program yahade (Yet Another Hardware Detector). Stanowi on część oryginalnego systemu operacyjnego cdlinux.pl i służy do wykrycia sprzętu zainstalowanego w komputerze, ew. załadowania wcześniej zapisanej konfiguracji na dyskietce oraz do interakcji z użytkownikiem w celu pozyskania pewnych szczegółów konfiguracyjnych. W systemie klastrowy cdlinux.pl program ten został rozbudowany o opcje specyficzne dla pracy kontrolera klastra. Po ustaleniu konfiguracji sieci komputerowej, program edytuje pliki konfiguracyjne dla serwerów dhcpd, atftpd, NFS oraz sshd, dla podsystemu openMosix oraz kilka ustawień systemowych (np. pliki /etc/hosts), gdyż ich poprawna praca w strukturach klastra jest uzależniona od adresów IP oraz nazw interfejsów sieciowych. Serwer dhcpd służy do implementacji protokołu bootp, za pomocą którego będzie konfigurowany węzeł klastra uruchamiany przez sieć komputerową. Przyznaje on między innymi adresy sieciowe węzłom w sposób dynamiczny – za każdym uruchomieniem węzła może on otrzymać inny adres sieciowy. Inną jego funkcją jest informowanie węzła o adresie sieciowym serwera tftp, z którego pobrane będzie jądro węzła i potrzebne ku temu pliki. W tych celach serwer dhcpd musi znać konfigurację sieciową kontrolera klastra. Serwer atftpd realizuje usługę tftp, czyli trywialny protokół transferu plików. Nazwa pochodzi od jego prostoty – do przesyłania danych nie jest wymagane uwierzytelnienie użytkownika. Służy on w klastrze do serwowania węzłowi programu ładującego jądro Linuxa 45 (PXELINUX), jego plików konfiguracyjnych, jak i stowarzyszonych z nim plików (np. właściwe jądro Linuxa). Do uruchamianego jądra Linuxa węzła przekazywany jest adres udziału NFS, który zostanie zamontowany jako główny system plików. Z kolei udział ten znajduje się na kontrolerze klastra, którego konfiguracja sieciowa musi być znana programowi ładującemu. Z tego powodu yahade edytuje zawartość udostępnianą przez atftpd będącą konfiguracją programu ładującego jądro Linuxa uruchamianego przez sieć węzła. Serwer NFS jest używany w klastrze do montowania części kontrolera klastra jako systemu plików węzła klastra. Konfiguracja serwera mogłaby nie być uzależniona od adresu sieciowego kontrolera klastra, jednak w celu minimalizacji zagrożenia wynikającego z możliwości korzystania z udziałów NFS przez niepowołanych użytkowników sieciowych, ustalane są prawa dostępu do tych udziałów na podstawie adresów sieciowych. Uprawnienia do montowania udziałów zostają nadane tylko tym adresom, które znajdują się w podsieci przeznaczonej dla kontrolera klastra i jego węzłów. Ponadto od IP serwera uzależniona zostaje konfiguracja montowania systemów plików przez NFS przez węzeł klastra (ustawiona w pliku /slave2/etc/fstab). Serwer sshd, realizujący protokół ssh, służy do wykonywania poleceń na zdalnym komputerze w sieci komputerowej. Dawniej w systemach klasy UNIX popularny był protokół rsh, czyli remote shell. Pozwalał on również na zdalną pracę, jednak mankamentem było ograniczenie praw dostępu dla tej usługi, gdyż było to możliwe jedynie w oparciu o adresy sieciowe klientów, porty źródłowe, nazwę użytkownika pozyskaną przez usługę auth. Takie rozwiązanie miało zastosowanie praktyczne jedynie w zamkniętych środowiskach, np. w pracowniach komputerowych, gdzie wszystkie maszyny były zaufane. Protokół ssh oferuje znacznie bogatsze metody uwierzytelniania klientów bazujące na kryptografii asymetrycznej. Co więcej, całkowita transmisja między klientem a serwerem jest szyfrowana za pomocą kryptografii symetrycznej, co daje potencjał wysokiego bezpieczeństwa zdalnej pracy. W systemie operacyjnym klastrowy cdlinux.pl serwer sshd używany jest do sterowania węzłami przez kontroler klastra – ręcznie, poprzez wywołanie programu ssh i otworzenie sesji na zdalnym węźle, bądź niejawnie przez program wizualizacyjny openmosixview. W tym drugim przypadku istotnym szczegółem jest, by połączenie szyfrowane ustanawiane było przy pomocy pary kluczy kryptograficznych: prywatnego i publicznego, a w tym celu zostać 46 stworzone muszą odpowiednie wpisy dla każdego numeru IP, który może przyjąć węzeł klastra (patrz rozdział 2). Zmiana konfiguracji openMosix nie zależy od numeru IP, a raczej od nazwy interfejsu sieciowego kontrolera klastra używanego do podłączenia go do klastra. Ma to znaczenie w przypadku komputerów z więcej niż jednym skonfigurowanym interfejsem sieciowym. Podłączenie do klastra może nastąpić tylko na jednym z nich. Jest to ostatni skonfigurowany w yahade interfejs. Jego nazwę program zapisuje do pliku /etc/openmosix/openmosix.config. 3.1.5. Uruchomienie rozszerzeń względem cdlinux.pl Pod koniec procesu uruchamiania systemu operacyjnego, włączone zostają serwery dhcpd, atftpd, portmap, skonfigurowany zostaje serwer NFS (wyeksportowane zostają udziały). Zainicjowany zostaje podsystem openMosix, co między innymi pociąga za sobą uruchomienie daemona automatyzującego dołączanie węzłów do klastra – omdiscd. Włączany jest też program openmosixcollector, który służy do zbierania danych dla programu wizualizacyjnego openmosixview. Po zakończeniu pracy wszystkich skryptów inicjacyjnych systemu operacyjnego, uruchomione zostają użytkownikowi otworzenie sesji w systemie. 47 wirtualne terminale umożliwiające 3.2. Uruchamianie węzła klastra Proces uruchamiania węzła w klastrze odbiega znacząco od sposobu znanego z innych dystrybucji. Węzeł nie musi dysponować dyskiem twardym, a nawet napędem CD-ROM. W idealnym przypadku wystarczy odpowiednia karta sieciowa, jednak karty takie są rzadkością w obecnych systemach komputerowych, więc najczęściej będzie potrzebny napęd dysków elastycznych. Możliwe jest wyodrębnienie kilku faz uruchamiania węzła klastra systemu operacyjnego klastrowy cdlinux.pl: • wczytanie programu ładującego zgodnego z PXE z pamięci ROM karty sieciowej, lub z dyskietki w postaci programu emulującego PXE, • wyszukanie przez PXE serwera bootp w sieci komputerowej, po czym następuje pobranie z niego konfiguracji sieciowej węzła oraz danych odnośnie serwera tftp, z którego należy pobrać program ładujący jądro Linuxa, • pobranie programu ładującego jądro Linuxa, czyli programu PXELINUX, z serwera tftp, • PXELINUX wczytuje konfigurację uruchamiania Linuxa z tego samego serwera tftp, pobiera z niego brakujące pliki (przede wszystkim jądro systemu operacyjnego), po czym uruchamia jądro z opcją montowania głównego systemu plików przez NFS, • uruchomienia jądra, w trakcie czego montowany jest główny system plików z NFS, • oddanie sterowania do standardowego mechanizmu uruchamiania Linuxa – /sbin/init, • uruchomienie kilku dodatkowych skryptów inicjacyjnych zajmujących się przygotowaniem reszty systemu plików, różnicujących konfigurację poszczególnych węzłów, etc. 3.2.1. Środowisko PXE (Pre Execution Environment) Nazwa ta określa standard ustanowiony przez firmę Intel, który opisuje proces uruchamiania komputera w oparciu o sieć komputerową. PXE jest częścią projektu Wired for Management (WfM), sporządzonego przez grupy badawcze firmy Intel w połowie lat 90-tych XX wieku [PXESPEC]. Projekt skupia się na zautomatyzowaniu zdalnego zarządzania 48 komputerami PC spiętymi w sieć. W skład projektu wchodzą takie elementy, jak użycie sieci jako urządzenia inicjacyjnego (boot device), zdalne budzenie (włączanie) komputera (remote wake-up), zarządzanie zużyciem energii (power management). Poniższy diagram przedstawia w uproszczeniu komunikację klienta z serwerem podczas negocjacji PXE: serwer DHCP klient PXE serwer uruchamiania DHCP Discover na port 67 Zawiera tagi rozszerzające PXEClient Rozszerzone DHCP Offer na port 68 zawiera: tagi rozszerzające serwera PXE + numer IP dla klienta [+ inne tagi opcji DHCP] DHCP Request na port 67 zawiera: tagi rozszerzające PXEClient [+ inne tagi opcji DHCP] Odpowiedź DHCP Ack na port 68 Boot Service Discover na port 67 lub 4011 zawiera: tagi rozszerzające PXEClient [+ inne tagi opcji DHCP] Odpowiedź Boot Service Ack na port źródłowy klienta zawiera: nazwę pliku NBP - programu uruchamiającego przez sieć (ang. network bootstrap program) [+ tagi rozszerzające serwera PXE] Rozkaz pobrania NBP na port 69 (usługa TFTP) lub na port MTFTP poznany z odpowiedzi Boot Service Ack Pobranie NBP na port klienta Diagram 9. Schemat negocjacji PXE: komunikacja klienta z serwerem [PXESPEC] 49 W systemie operacyjnym klastrowy cdlinux.pl w miejscu serwera DHCP i serwera uruchamiania (ang. boot server) jest jeden host – kontroler klastra. Usługę serwera DHCP oraz częściowo serwera uruchamiania pełni program ISC DHCPD, natomiast pozostałą część serwera uruchamiania stanowi serwer atftpd. Z niego pobierany jest program uruchamiający przez sieć NBP (Network Boot Program), a konkretnie PXELINUX. 3.2.2. Nawiązanie komunikacji węzła z kontrolerem klastra Po uruchomieniu węzła, możliwe są dwie drogi działania. Jeżeli w systemie komputerowym węzła obecna jest karta sieciowa wspierająca standard PXE, następuje przekazanie do niej sterowania przez BIOS i kod zawarty w pamięci ROM karty sieciowej rozpoczyna negocjację PXE opisaną powyżej. Jeżeli jednak karta sieciowa nie wspiera PXE, proces uruchamiania przebiega standardowym trybem, czyli system operacyjny wyszukiwany jest na nośnikach fizycznych. W takim przypadku należy system komputerowy skonfigurować tak, by urządzeniem inicjacyjnym stał się napęd dysków elastycznych. W napędzie powinna znaleźć się dyskietka przygotowana do emulacji systemu PXE. W systemie operacyjnym klastrowy cdlinux.pl zdecydowano się użyć w tym celu programu NetBoot ([NETBOOT]). Mankamentem takiego rozwiązania jest wymóg konstruowania osobnej dyskietki dla każdego typu karty sieciowej, która ma być używana w węźle klastra. Program NetBoot umożliwia przygotowanie obrazu dyskietki w oparciu o sterownik systemu operacyjnego DOS do wymaganego typu karty sieciowej. Sterowniki takie są dostarczane zawsze z kartami sieciowymi. Obraz taki należy nagrać w trybie surowym (raw) na dyskietkę, najlepiej używając w systemie Linux programu dd. Tak przygotowana dyskietka jest gotowa do uruchomienia z niej emulacji podsystemu PXE. Dalej proces uruchamiania systemu operacyjnego węzła przebiega tak samo, jak w przypadku wykorzystania karty sieciowej z systemem PXE. W pierwszym kroku negocjacji PXE, odnajdywany jest pracujący na kontrolerze klastra serwer bootp. W przypadku omawianego systemu operacyjnego jest to serwer ISC DHCPD. Jako że protokół PXE działa w oparciu o protokół dhcp bez ograniczania jego pierwotnej funkcjonalności, możliwe jest wykorzystanie w tym celu serwera dhcp ogólnego przeznaczenia. Dyrektywami potrzebnymi do przekazania węzłowi odpowiednich informacji 50 dotyczących dalszego procesu uruchamiania są next-server oraz filename. Pierwsza z nich określa adres serwera uruchamiania (boot server), czyli serwera który bierze udział w drugiej części negocjacji PXE. Jest to między innymi usługa tftp (serwer plików), z którego pobierany jest program z pliku. Nazwę tego pliku określa druga z omawianych dyrektyw serwera dhcpd, czyli filename. 3.2.2.1. Opis usługi Dynamic Host Configuration Protocol (dhcp) Usługa ta dostarcza parametry konfiguracyjne hostom (komputerom) w sieci IP [RFC2131]. DHCP składa się z dwóch komponentów: z protokołu służącego do dostarczania parametrów konfiguracyjnych do hosta oraz z mechanizmu przydzielania adresów sieciowych dla hostów. DHCP jest zbudowane w oparciu o model klient-serwer. Wyznaczony serwer DHCP przydziela adresy sieciowe i dostarcza parametry konfiguracyjne dynamicznie konfigurowanym hostom – klientom. Host kliencki nie powinien zachowywać się jak serwer – nie powinien odpowiadać na zapytania innych hostów. Gdyby tak się stało, czyli gdyby w sieci wystąpiło więcej serwerów DHCP, niż jeden, pojawiłoby się ryzyko powstania konfliktów konfiguracji. Wprawdzie przy przydziale adresów sieciowych dla hostów istnieje mechanizm sprawdzania, czy adres przydzielony wcześniej któremuś z hostów jest nadal potrzebny, jednak hosty nie muszą być w stanie zawsze „obronić” dzierżawy swojego adresu, a tym samym mogłyby powstać duplikaty przydziałów adresów w sieci. DHCP wspiera trzy mechanizmy przydziału adresów sieciowych: • automatyczna alokacja Klientowi przydzielany jest adres na stałe. • dynamiczna alokacja Klientowi przydzielany jest adres na skończony okres czasu lub do czasu, gdy klient sam zwolni dzierżawę adresu • ręczna alokacja Adresy przydzielane są administracyjnie do danych hostów, jednak DHCP służy jako nośnik tej informacji Dana sieć może wykorzystywać jeden lub więcej powyższych mechanizmów w zależności od polityki adresacji wprowadzonej przez administratora sieci. 51 Dynamiczna alokacja jest jedynym z mechanizmów pozwalającym na ponowne użycie adresu, który nie jest już wykorzystywany przez klienta, dla którego został on poprzednio przydzielony. Z tego powodu dynamiczna alokacja jest szczególnie użyteczna do przydzielania adresów klientom, którzy będą podłączeni do sieci tymczasowo lub w przypadku, gdy ograniczona ilość adresów sieciowych musi zostać rozdzielona między większą ilość hostów, dla których nie istnieje potrzeba zachowania stałego adresu. Ręczna alokacja jest przydatna, gdy wybór konfiguracji sieciowej hostów nie ma być sterowany mechanizmami DHCP, a pożądane jest nie dopuszczenie do ewentualnych błędów powstałych wskutek wprowadzania konfiguracji oddzielnie na każdym hoście. Format pakietów DHCP jest oparty o format wiadomości BOOTP (opis formatu znajduje się w RFC951), by zachować możliwość współdziałania istniejących klientów BOOTP z serwerami DHCP, a w szczególności by zachować działanie agenta przekazywania (proxy) BOOTP. Stosowanie agentów przekazywania BOOTP eliminuje potrzebę występowania serwera DHCP na każdym fizycznym segmencie sieci. Użytym w systemie operacyjnym klastrowy cdlinux.pl serwerem DHCP jest ISCDHCPD. Jego konfiguracja zawarta jest domyślnie w pliku /etc/dhcpd.conf, którego składnia jest bardzo bogata. W poniższym opisie skupiono się jedynie na dyrektywach wykorzystywanych w omawianym systemie. • allow bootp Określa, czy serwer ma odpowiadać na zapytania BOOTP • option domain-name "mojadomena.pl" Określa domenę dla klientów • option subnet-mask X.X.X.X Określa maskę podsieci dla klientów • option broadcast-address X.X.X.X Określa adres broadcast dla klientów • option domain-name-servers X.X.X.X Określa adresy serwerów DNS dla klientów (może być więcej, niż jeden adres – wtedy powinny być oddzielone przecinkami) • option routers X.X.X.X Określa domyślną bramę dla klientów 52 • range dynamic-bootp X.X.X.X Y.Y.Y.Y Określa przedział domknięty adresów IP, które mają być przydzielone dynamicznie klientom. Flaga dynamic-bootp oznacza, że adresy mogą być przydzielone zarówno klientom DHCP, jak i klientom BOOTP • next-server X.X.X.X Określa adres IP serwera, z którym ma przebiegać kolejna faza konfiguracji hosta – w przypadku systemu klastrowy cdlinux.pl będzie to adres serwera tftp • filename "/etc/tftpboot/pxelinux.0" Określa nazwę pliku, która ma być pobrana z serwera w kolejnej fazie konfiguracji hosta (patrz dyrektywa next-server) • subnet X.X.X.X netmask Y.Y.Y.Y { } Definicja podsieci określonej przez adres sieci X.X.X.X i maskę podsieci Y.Y.Y.Y. Między nawiasami klamrowymi znajdą się dyrektywy specyficzne dla danej podsieci spośród tych wymienionych wyżej. Aby serwer dhcpd uruchomił się poprawnie, wszystkie podsieci zdefiniowane na interfejsach sieciowych hosta muszą być pokryte dyrektywami subnet. 3.2.2.2. Opis usługi Trivial File Transfer Protocol (tftp) Jest to prosty protokół zaprojektowany do przesyłu plików i pracuje wykorzystując protokół UDP (User Datagram Porotocol) stosu TCP/IP [RFC1350]. Jako że ideą przyświecającą skonstruowaniu omawianego protokołu była prostota, nie posiada on wielu funkcji, którymi charakteryzuje się ftp. Potrafi on jedynie czytać i zapisywać pliki (bądź pocztę) z/na zdalny serwer. W szczególności nie posiada wsparcia do sporządzania listy zawartości katalogów oraz dla uwierzytelniania użytkowników. Typ pakietu jest zakodowany w pierwszym dwubajtowym słowie każdego pakietu. W transmisji tftp występują pakiety pięciu typów: 1. żądanie czytania (read request, RRQ), 2. żądanie zapisu (write request, WRQ), 3. dane (DATA), 4. potwierdzenie (acknowledegment, ACK), 5. błąd (ERROR). 53 Każda operacja przesyłu pliku rozpoczyna się od żądania odczytu (RRQ), bądź zapisu (WRQ) pliku, które również jest żądaniem ustanowienia połączenia. W obydwu tych żądaniach znajdują się nazwy plików, które mają być zapisane lub odczytane na/z serwera. Jeżeli serwer zgodzi się na przesył, połączenie zostaje ustanowione i dane zostają przesłane w blokach 512 bajtowych (DATA). Każdy blok danych musi zostać potwierdzony przez drugą stronę pakietem potwierdzającym (ACK). Nie występuje tutaj pojęcie okna przesuwnego – każdy przesłany blok danych musi być potwierdzony przed przesłaniem kolejnego bloku. Blok danych o rozmiarze mniejszym, niż 512 bajtów, oznacza koniec przesyłanego pliku, a co za tym idzie, koniec transmisji. Jeżeli w czasie trwania połączenia wystąpi błąd, przesyłany jest na drugą stronę pakiet informujący o błędzie (ERROR). W systemie operacyjnym klastrowy cdlinux.pl funkcję serwera tftp pełni program atftpd (ftp://ftp.mamalinux.com/pub/atftp/). Programu nie konfiguruje się przez plik konfiguracyjny – wszelkie parametry podaje się z linii poleceń. Najważniejsze parametry zestawiono poniżej. • --daemon Sprawia, że program odłącza się od sterującego terminala i przechodzi w pracę w tle • --port <n> Określa, na którym porcie UDP serwer ma nasłuchiwać. Jeżeli parametr ten nie jest podany, przyjmowany jest standardowy port usługi tftp, czyli 69/udp. • --retry-timeout <n> Określa, ile sekund serwer ma czekać na potwierdzenie pakietu (ACK) przed retransmisją. Domyślnie jest to 5 sekund. Na okres ten ma również wpływ polecenie 'timeout' klienta tftp. • --mcast-addr <wartość> Określa adres, listę, bądź przedział adresów, które mają zostać wykorzystane do transmisji multicast. Domyślną wartością jest przedział 239.255.0.0-255 • --mcast-port <wartość> Określa port, listę, bądź przedział portów UDP, które mają zostać wykorzystane do transmisji multicast. Domyślną wartością jest 1758 • --maxthread <n> Określa maksymalną ilość współbieżnych wątków. Domyślną wartością jest 100 54 • --verbose[=<n>] Opcja bez parametrów zwiększa poziom logowania, a z parametrem określa konkretny poziom logowania. Poziomy są standardowymi nazwami systemu syslog. Domyślnie jest to LOG_NOTICE, czyli liczbowo 5. • [<katalog>] Określa ścieżkę do katalogu, w którym przechowywane jest całe repozytorium tftp. Domyślną wartością jest /tftpboot. Należy pamiętać o tym, że jako że serwer atftpd pracuje z uprawnieniami użytkownika nobody, katalog repozytorium powinien być przygotowany tak, by serwer mógł czytać i ew. modyfikować jego zawartość przez użytkownika nobody. 3.2.3. PXELINUX – druga odsłona SYSLINUXa W ostatnim kroku negocjacji PXE pobierany jest z serwera tftp plik z kodem wykonywalnym, po czym kod ten jest uruchamiany. W przypadku systemu operacyjnego klastrowy cdlinux.pl, kodem tym jest program PXELINUX, czyli jedna z gałęzi pakietu SYSLINUX [SYSLINUXWWW], która tym razem odpowiedzialna jest za uruchamianie systemu operacyjnego poprzez sieć w wyniku działania protokołu PXE. Składnia pliku konfiguracyjnego PXELINUXa jest taka sama, jak SYSLINUXa. Położenie tego pliku nie jest ściśle określone i może zależeć od klienta próbującego się uruchomić poprzez PXE, a konkretnie od adresu fizycznego karty sieciowej, bądź od przyznanego mu numeru IP. Wszystkie potencjalne pliki konfiguracyjne muszą znajdować się w katalogu pxelinux.cfg, który znajduje się w tym samym katalogu, co plik z kodem PXELINUXa o nazwie pxelinux.0. W omawianym systemie ścieżką do tego pliku jest /etc/tftpboot/pxelinux.0, zatem katalog z plikami konfiguracyjnymi będzie oczekiwany w /etc/tftpboot/pxelinux.cfg/. 55 Nazwa samego pliku konfiguracyjnego poszukiwana jest przez klienta w następujący sposób. Najpierw szukany jest plik o nazwie będącej adresem fizycznym karty sieciowej klienta (małe litery i cyfry, każdy oktet oddzielony myślnikami). Następnie, jeżeli taki nie zostanie odnaleziony, potencjalną nazwą pliku jest adres IP przydzielony klientowi w postaci heksadecymalnej (wielkie litery i cyfry, wszystkie koło siebie). Jeżeli i taki plik nie zostanie znaleziony, próbowane są nazwy powstałe przez usunięcie ostatniego znaku poprzedniej nazwy. Na samym końcu następuje próba pobrania pliku o nazwie default. Dla przykładu, jeżeli klientem będzie komputer o adresie karty sieciowej 00:11:22:33:44:EF i przydzielonym adresie IP 172.0.0.100 (w reprezentacji heksadecymalnej: AC000064), kolejne sprawdzane nazwy pliku konfiguracyjnego przedstawia poniższa lista: • /etc/tftpboot/pxelinux.cfg/00-11-22-33-44-ef • /etc/tftpboot/pxelinux.cfg/AC000064 • /etc/tftpboot/pxelinux.cfg/AC00006 • /etc/tftpboot/pxelinux.cfg/AC0000 • /etc/tftpboot/pxelinux.cfg/AC000 • /etc/tftpboot/pxelinux.cfg/AC00 • /etc/tftpboot/pxelinux.cfg/AC0 • /etc/tftpboot/pxelinux.cfg/AC • /etc/tftpboot/pxelinux.cfg/A • /etc/tftpboot/pxelinux.cfg/default Z pobranego pliku konfiguracyjnego PXELINUX odczytuje nazwę pliku zawierającego jądro Linuxa oraz listę parametrów, które mają być przekazane w linii poleceń do uruchamianego jądra. Pliki zawierające jądra oraz ewentualne początkowe ramdiski (initrd) powinny znajdować się gdzieś w /etc/tftpboot – ścieżki do tych plików (podawane przez dyrektywę image= oraz initrd= w pliku konfiguracyjnym) są konstruowane względem tego katalogu. Poniżej zaprezentowano zawartość ekranu komputera uruchamiającego się przez PXE z kontrolera klastra. Pierwszy fragment (diagram nr 10) przedstawia proces uruchamiania przy użyciu programu Netboot [NETBOOT] emulującego PXE wczytanego z dyskietki (obsługującego kartą zgodną z NE2000), natomiast drugi fragment (diagram nr 11) obrazuje 56 uruchamianie przy udziale karty sieciowej Intel EtherExpress 100 wspierającej środowisko PXE. Netboot driver for NE2000, version 11.4.3 BIOS options: none Packet driver for NE2000, version 11.4.3 Packet driver skeleton copyright 1988-93, Crynwr Software. This program is freely copyable; source must be available; NO WARRANTY. See the file COPYING.DOC for details; send FAX to +1-315-268-9201 for a copy. Packet driver interrupt is 0x62 (98) Interrupt number 0x9 (9) I/O port 0x300 (768) My Ethernet address is 00:00:B4:3F:2D:1C Found packet driver at int 62, irq 09 BOOTP: Sending request (press ESC to abort): ..ok Local IP: 192.168.1.11 Server IP: 192.168.1.10 () Gateway IP: 192.168.1.10 Loading /etc/tftpboot/pxelinux.0 Options: Blocksize 1432, Filesize 11168, Timeout 15 Block 8 ok Starting image... PXELINUX 2.04 (Debian, 2003-06-11) Copyright (C) 1994-2003 H. Peter Anvin UNDI data segment at: 9309B340 UNDI data segment size: 0000 UNDI code segment ad: 9309E9F0 UNDI code segment size: 0000 PXE entry point found (we hope) at 9E9F:0185 My IP address seems to be C0A8010B 192.168.1.11 ip=192.168.1.11:192.168.1.10:192.168.1.10:255.255.255.0 TFTP prefix: /etc/tftpboot/ Trying to load: pxelinux.cfg/C0A8010B Trying to load: pxelinux.cfg/C0A8010 Trying to load: pxelinux.cfg/C0A801 Trying to load: pxelinux.cfg/C0A80 Trying to load: pxelinux.cfg/C0A8 Trying to load: pxelinux.cfg/C0A Trying to load: pxelinux.cfg/C0 Trying to load: pxelinux.cfg/C Trying to load: pxelinux.cfg/default Loading vmlinuz-2.4.25-Debian-om..........................Ready. Failed to free base memory, error FF01-03FF-F000FE6E Uncompressing Linux... OK, booting the kernel. Linux version 2.4.25-Debian-om (root@cdlinux) (gcc version 3.3.5 (Debian 1:3.3.5-2)) #2 sob lis 20 21:48:51 CET 2004 ... Diagram 10. Uruchamianie się Linuxa poprzez emulację PXE programem NetBoot 57 Intel(R) Boot Agent FE v4.1.15 Copyright (C) 1997-2004, Intel Corporation CLIENT MAC ADDR: 00 02 B3 2C 4E 35 CLIENT IP: 192.168.1.12 MASK: 255.255.255.0 GATEWAY IP: 192.168.1.10 DHCP IP: 192.168.1.10 PXELINUX 2.04 (Debian, 2003-06-11) Copyright (C) 1994-2003 H. Peter Anvin UNDI data segment at: 000945B0 UNDI data segment size: 0000 UNDI code segment at: 0009DA60 UNDI code segment size: 0000 PXE entry point found (we hope) at 9DA6:0106 My IP address seems to be C0A8010C 192.168.1.12 ip=192.168.1.12:192.168.1.10:192.168.1.10:255.255.255.0 TFTP prefix: /etc/tftpboot/ Trying to load: pxelinux.cfg/C0A8010C Trying to load: pxelinux.cfg/C0A8010 Trying to load: pxelinux.cfg/C0A801 Trying to load: pxelinux.cfg/C0A80 Trying to load: pxelinux.cfg/C0A8 Trying to load: pxelinux.cfg/C0A Trying to load: pxelinux.cfg/C0 Trying to load: pxelinux.cfg/C Trying to load: pxelinux.cfg/default Loading vmlinuz-2.4.25-Debian-om..........................Ready. Uncompressing Linux... OK, booting the kernel. Linux version 2.4.25-Debian-om (root@cdlinux) (gcc version 3.3.5 (Debian 1:3.3.5-2)) #2 sob lis 20 21:48:51 CET 2004 ... Diagram 11. Uruchamianie się Linuxa w oparciu o kartę sieciową wspierającą PXE 3.2.4. Uruchomienie jądra z nfsroot Pojęcie nfsroot oznacza sposób uruchamiania jądra Linuxa z zamontowaniem głównego systemu plików przez NFS. Jest to również pewien mechanizm zaimplementowany w jądrze Linuxa [NFSROOT]. Wymaga on obecności w jądrze wsparcia dla NFS (z oczywistych powodów nie może być ono skompilowane jako moduł jądra), dla stosu TCP/IP, sterowników do karty sieciowej obecnej w systemie komputerowym oraz ewentualnie wsparcia dla konfiguracji systemu poprzez sieć (przez dhcp/bootp). Po zainicjowaniu co najmniej jednej karty sieciowej podczas uruchamiania jądra Linuxa oraz nadaniu jej numeru IP, możliwe staje się pod koniec zamontowanie udziału NFS. Po zamontowaniu dalsza inicjacja systemu operacyjnego przebiega standardowo. 58 Linux rozpoznaje następujące opcje przekazane w linii poleceń, które wpływają na charakterystykę nfsroot: root=/dev/nfs Opcja ta jest potrzebna by zainicjować pseudo-urządzenie /dev/nfs. Według oficjalnej dokumentacji użycie tej opcji jest wymagane, by jądro wiedziało, iż ma użyć udziału NFS jako głównego systemu plików. Jest to w obecnych wersjach jądra Linuxa nieprawdą, wystarczy użycie parametru nfsroot=, co też zostało uczynione w omawianym systemie operacyjnym. nfsroot=[<ip-serwera>:]<katalog-główny>[,<opcje-nfs>] Jest to najważniejsza opcja nfsroot. Definiuje ona szereg parametrów potrzebnych do zamontowania udziału NFS jako katalogu głównego. Pierwszym z nich jest adres IP serwera NFS, można gp jednak pominąć – wtedy użyty będzie parametr podany w opcji ip=. Kolejnym parametrem jest ścieżka do katalogu na serwerze NFS, który ma zostać zamontowany. Trzecim parametrem jest zestaw opcji NFS, z jakimi ma być udział zamontowany. ip=<ip-klienta>:<ip-serwera>:<ip-bramy>:<maska>:<hostname>:<urządzenie>:<autoconf> Parametry określają szczegóły konfiguracji TCP/IP klienta. Znaczenie opcji jest zgodne z ich nazwami. Wyjaśnienia wymagają parametry urządzenie oraz autoconf. Pierwszy z nich określa nazwę urządzenia sieciowego, które ma zostać skonfigurowane, natomiast drugi z nich określa, czy automatyczna konfiguracja ma przebiegać przy użyciu protokołu bootp, czy rarp – wartości odpowiednio 'bootp' i 'rarp'. Jeżeli któreś z pól pozostawione zostaną puste, ich wartości zostaną pobrane z serwera automatycznej konfiguracji (bootp bądź rarp). Jeżeli opcja ta nie zostanie podana w linii poleceń jądra, wszystkie pola zostaną uznane za puste, co zaowocuje w automatycznej konfiguracji. 59 3.2.4.1. Opis protokołu NFS NFS, czyli Sieciowy System Plików (Network File System) został opracowany przez SUN Microsystems i jest systemem plików pozwalającym na współdzielenie plików w sieci komputerowej [NFSD] [NFSHOWTO]. Został zaimplementowany przy użyciu czterech protokołów, z których każdy oparty jest na ONC-RPC (Open Network Computing Remote Procedure Call), czyli na protokole zdalnego wywoływania procedur, również opracowanym przez SUN. Czasami jest on zwany SUN-RPC. Wspomniane cztery protokoły to: • NFS Podstawowy protokół dostępu do plików, który pozwala na tworzenie, wyszukiwanie, odczytywanie i zapisywanie plików. Charakteryzuje go bezstanowość (ang. stateless), czyli jedyną informacją, która jest magazynowana na serwerze, jest zawartość systemu plików, który został udostępniony w sieci przez NFS. W szczególności serwer nie przechowuje informacji dotyczącej stanu klientów (nie musi istnieć logiczne połączenie klienta z serwerem). Protokół NFS jest nie tylko bezstanowy, jest również idempotentny. Oznacza to, że jeżeli dana wiadomość dotrze w dwóch kopiach, druga odebrana będzie traktowana jako NO-OP (brak operacji). Cecha ta pozwala używać protokołu w oparciu o tak zawodny protokół komunikacyjny, jak UDP/IP (bezpołączeniowy, bezpotwierdzeniowy). • MOUNTD Protokół ten jest używany do nawiązania połączenia z sieciowym systemem plików, którego uchwyt może później być użyty przez protokół NFS do operacji na plikach. Dla odmiany, protokół ten wymaga, by serwer przechowywał informację dotyczącą stanu klientów – serwer musi pamiętać o udziałach zamontowanych przez poszczególnych klientów. W skład protokołu wchodzi rozkaz odmontowania uprzednio zamontowanego udziału sieciowego systemu plików, co nakazuje usunięcie informacji o fakcie zamontowania systemu plików z serwera. • SM Monitor Stanu (ang. Status Monitor) jest protokołem służącym do monitorowania stanu poszczególnych węzłów sieci komputerowej. Celem jest okresowe badanie, 60 czy dany węzeł nie został zrestartowany, by powiadomić o tym fakcie inne węzły, które łączą się, bądź wyraziły uprzednio chęć połączenia się z węzłem przez NFS. • NLM Sieciowy Menadżer Rygli (Network Lock Manager) jest protokołem oferującym wsparcie dla rygli plików i rekordów (file/record locks). Rygle są mechanizmem służącym do zapobiegania jednoczesnemu dostępowi do zasobów. Protokół NLM bazuje na SM – po zrestartowaniu klienta zostają zwolnione stworzone przez niego rygle, a z drugiej strony, po zrestartowaniu serwera jest on informowany o istniejących ryglach. W jądrze Linuxa funkcjonuje podsystem knfsd, który implementuje protokoły NFS (linux/fs/nfsd) oraz NLM (linux/fs/lockd). Kod NLM zawiera wsparcie dla klienta SM, lecz serwer realizujący SM działa w przestrzeni użytkownika jako proces statd. Protokół MOUNTD jest obsługiwany przez serwer działający jako proces mountd, również w przestrzeni użytkownika. Serwer mountd komunikuje się z serwerem NFS w jądrze poprzez interfejs programistyczny bazujący na wywołaniach systemowych (ang. system call). Ważnym elementem SUNRPC jest portmapper. Jest to usługa informująca o portach, na których są dostępne inne usługi SUNRPC. Usługa ta jest realizowana przez daemon portmap. Portmapper jest dostępny na porcie 111 (TCP i UDP), natomiast pozostałe usługi mogą otwierać porty o dowolnych numerach, po czym rejestrują te numery w portmapperze, by klienty mogły je odnaleźć. Aby uzyskać spis usług zarejestrowanych w portmapperze, należy wykonać polecenie: # rpcinfo -p program wer. proto 100000 2 tcp 100000 2 udp port 111 111 portmapper portmapper Diagram 12. Wynik programu rpcinfo przed włączeniem usług NFS Powyższy wynik daje uruchomienie polecenia na świeżo uruchomionym portmapperze, bez zarejestrowanych innych usług. Po włączeniu daemonów nfsd oraz mountd, wynik wyglądać może następująco: 61 # rpcinfo -p program wer. proto 100000 2 tcp 100000 2 udp 100003 2 udp 100003 3 udp 100005 1 udp 100005 1 tcp 100005 2 udp 100005 2 tcp 100005 3 udp 100005 3 tcp port 111 111 2049 2049 812 815 812 815 812 815 portmapper portmapper nfs nfs mountd mountd mountd mountd mountd mountd Diagram 13. Wynik programu rpcinfo po włączeniu usług NFS Jak widać, uruchomionych zostało kilka instancji daemona mountd, co zaowocowało w zajęciu przez niego szeregu portów. Dzięki usłudze portmapper można wszystkie te instancje łatwo odnaleźć. Pliki udostępniane są przez NFS w sieci komputerowej w formie udziałów. Udziały są to poddrzewa systemu plików serwera, które są w pewien sposób wyeksponowane na dostęp z sieci – mówi się o eksporcie udziałów. Miejscem, w którym się definiuje listę udziałów do eksportu jest plik /etc/exports. Każda linia pliku jest definicją pojedynczego udziału. Jej postać przedstawia się następująco: katalog host1(opcja,opcja,...) host2(opcja,opcja,...) ... gdzie: katalog Katalog przeznaczony do wyeksportowania. Może to być cały system plików, ale nie musi. Należy zauważyć, że katalog jest eksportowany wraz z wszystkimi plikami i podkatalogami w nim zawartymi, ale należącymi do tego samego systemu plików. host1, host2, ... Definicja hostów klienckich, które mają mieć dostęp do udziału. Definicje mogą zawierać nazwy DNS bądź adresy IP. Te ostatnie powinny być zapisane w postaci adres/maska. 62 opcja,opcja,... Modyfikatory domyślnego sposobu eksportowania udziałów. Definiują między innymi: • prawa dostępu do udziałów ro = tryb tylko do odczytu, rw = pełny dostęp, no_subtree_check = wyłącza mechanizm subtree_check, który służy do sprawdzania, czy dany plik należy do katalogu wyeksportowanego jako udział NFS; ma to znaczenie zwłaszcza dla wyeksportowanych katalogów, które są tylko częścią systemu plików – z drugiej strony ma znaczenie dla wydajności, która wzrasta wraz z wyłączeniem funkcji, • translacje UIDów (identyfikatorów użytkownika) przy operacji na plikach – domyślnie operacje wykonywane na udziale przez użytkownika root są zamieniane na użytkownika nobody; opcja no_root_squash wyłącza tą translację, • synchroniczność protokołu sync = żądanie jest potwierdzone dopiero po zakończeniu jego realizacji, async = żądanie jest potwierdzone bez oczekiwania na zakończenie jego realizacji by zwiększyć wydajność). • ukrywanie zamontowanych uprzednio systemów plików domyślnie jeżeli wyeksportowane są dwa systemu plików, z których jeden (system B) zamontowany jest w podkatalogu drugiego (systemu A), to po zamontowaniu przez NFS systemu A, w podkatalogu, w którym był zamontowany B, nie będzie nic i trzeba będzie jawnie zamontować system B w kliencie; opcja nohide umożliwia dostęp do systemu B do podkatalogu systemu A bez jawnego montowania udziału systemu B. 63 Plik /etc/exports jest czytany przy inicjacji serwera NFS, jednak aby w trakcie jego pracy nakazać mu zaznajomić się z bieżącą wersją pliku, należy wysłać sygnał SIGHUP do serwera nfs poleceniem: # kill -HUP <nr_procesu_nfsd> lub skorzystać z polecenia: # exportfs -ra które dodatkowo synchronizuje zawartość pliku /var/lib/nfs/xtab z /etc/exports. W pliku /var/lib/nfs/xtab serwer NFS przechowuje informacje o aktualnie wyeksportowanych udziałach, zatem powyższe polecenie zajmuje się usunięciem z niego wpisów, które już nie istnieją w /etc/exports. Aby skorzystać z udziału NFS, należy go na hoście klienckim zamontować. Używa się w tym celu standardowego polecenia mount, dla którego jako źródło należy podać adres serwera NFS oraz katalog do zamontowania: # mount -t nfs -o opcje adres.serwera.nfs:/katalog /kat/docel gdzie: adres.serwera.nfs adres sieciowy serwera NFS; może zostać podany w formie nazwy DNS albo numeru IP /katalog katalog wyeksportowany z serwera NFS, który ma zostać zamontowany /kat/docel katalog na hoście klienckim, gdzie ma zostać zamontowany udział NFS opcje rozpoznawanych jest szereg opcji, z których najciekawszymi są: • soft opcja ta pozwala, by w razie awarii serwera NFS, jądro hosta klienckiego po jakimś 64 czasie (określonym przez opcję timeo=czas) zgłosiło błąd dostępu aplikacji klienckiej operującej na pliku przez NFS, by praca aplikacji mogła zostać od razu wznowiona; nie jest zalecane korzystanie z tej opcji, gdyż istnieje wtedy wielkie prawdopodobieństwo utraty danych w przypadku awarii serwera NFS; • hard w racie awarii serwera NFS, aplikacja kliencka zawiśnie aż do czasu, gdy serwer NFS zacznie znowu działać; nie będzie możliwe jej przerwanie lub zabicie, jeżeli nie zostanie również podana opcja intr 3.2.5. Zakończenie inicjacji węzła Jądro Linuxa uruchamiane jest z parametrem nakazującym zamontowanie głównego systemu plików z serwera NFS. Zamontowane drzewo nie jest kopią drzewa katalogów kontrolera klastrów – części się pokrywają, jednak występujące między kontrolerem a węzłem różnice konfiguracyjne wymagają odrębności niektórych katalogów. Między innymi występuje katalog /readonly, w którym znajdują się katalogi, których zawartość będzie następnie skopiowana do ramdisku. Po zamontowaniu systemu plików kontrola jest oddawana do standardowego programu inicjującego system operacyjny /sbin/init. W skład skryptów inicjacyjnych wchodzi kilka dodatkowych, spośród których jeden służy do przygotowania systemu plików. Jest to skrypt uruchamiany jako pierwszy i mieści się on w pliku /etc/init.d/preparefs. Jego zadaniem jest stworzenie ramdisku, zamontowanie go do katalogu /ramdisk, oraz skopiowanie do niego katalogów /dev, /etc, /root, /var z katalogu /readonly. Dzięki temu katalogi te staną się modyfikowalne, a zostaną zainicjowane plikami z szablonu dostępnego w trybie tylko-doodczytu. Pozostałe katalogi, czyli /boot, /bin, /cdlinux, /lib, /sbin, /usr występują w systemie w trybie tylko-do-odczytu. Kolejnym dodatkowym skryptem jest program /etc/init.d/preparehostname. Jego zadaniem jest zróżnicowanie nazwy hosta w systemie operacyjnym węzła względem domyślnej, która brzmi cdlinux. Nazwa ta jest 65 konstruowana z nazwy cdlinux oraz z ostatniej liczby numeru IP, którą węzeł otrzyma od serwera DHCP/BOOTP. Pozostałe zmiany inicjacji węzła dotyczą kolejności wykonywania standardowych skryptów zapożyczonych z dystrybucji Debian. Kluczowe porcje systemu muszą być zamontowane z serwera NFS bardzo wcześnie, zatem skrypty montujące wszelkie systemy plików zostały przesunięte na początek kolejności. Są to skrypty: • /etc/init.d/mountall.sh • /etc/init.d/mountkernfs • /etc/init.d/mountvirtfs • /etc/init.d/mountnfs.sh Dodatkowo, aby zadziałał ostatni skrypt, który jest odpowiedzialny za montowanie udziałów NFS, zaraz przed nim zostaje uruchomiony skrypt konfigurujący sieć. Przy uruchomieniu jądra montowany przez NFS jest tylko podstawowy mały system plików. Pozostała część musi być zamontowana oddzielnie. Ma to związek z tym, że montowane udziały muszą być w różnych katalogach na kontrolerze klastra, gdyż zależy od tego sposób archiwizacji danych na płycie i sposób uruchamiania. W przypadku uruchamiania z CD-ROMu, bez ładowania całości do RAMu, katalog /cdlinux istnieje w całości na CD-ROMie, natomiast reszta, dla przyspieszenia działania systemu, w ramdisku. Z tego tytułu program /etc/init.d/mountnfs.sh montuje skonfigurowane w /slave2/etc/fstab udziały: • /cdlinux • /usr • /cdlinux/lib • /cdlinux/usr2 • /cdlinux/var Pozostałe skrypty uruchamiane są tak samo, jak na kontrolerze klastrów. Nie są uruchamiane części oprogramowania specyficzne dla serwerowej części kontrolera klastra, czyli nie jest uruchamiany serwer tftp, dhcp, NFS. Również nie jest uruchamiany daemon openMosixcollector, który służy do zbierania statystyk pracy klastra, jednak pracuje tylko na kontrolerze klastra. 66 4. Budowa systemu operacyjnego Budowę systemu operacyjnego Klastrowy cdlinux.pl oparto o dystrybucję systemu operacyjnego cdlinux.pl-mały w wersji 0.5.7-pre2, gdyż jest to w okresie pisania pracy najświeższa wersja. Jako że nośnik CD-ROM jest nośnikiem nie umożliwiającym zapisu w sposób swobodny, wymagane było sporządzenie kopii roboczej systemu operacyjnego na dysku twardym. Po włączeniu cdlinux.pl z płyty CD-ROM, zainstalowano system na dysku twardym przy użyciu programu cdlcenter – opcji Instalacja na dysku twardym. Z powodu drobnego błędu w programie instalacyjnym (program cdlcenter-hdinstall.sh), a dokładniej w komponencie wizualizującym proces kopiowania, proces instalacji ulegał zawiśnięciu. Po zabiciu procesu odpowiedzialnego za wizualizację, instalacja została wznowiona. 4.1. Doinstalowane oprogramowanie Klastrowy cdlinux.pl wymaga nieco więcej oprogramowania zainstalowanego, niż podstawowa wersja cdlinux.pl, zatem zainstalowano je z paczek w pierwszej kolejności za pomocą narzędzia apt-get. Doinstalowane oprogramowanie zestawiono poniżej wraz z opisem: atftpd – serwer realizujący protokół tftp, który użyty zostanie do transferu początkowej części systemu operacyjnego podczas uruchamiania komputera przez sieć z kontrolera klastra dhcp – serwer realizujący protokół bootp, który użyty zostanie w celu przekazywania informacji do stacji uruchamiającej się przez sieć przez protokół PXE (Pre eXecution Environment) nfs-common, nfs-kernel-server oraz portmap – komponenty wzbogacające system operacyjny o obsługę sieciowego systemu plików NFS openmosixview – oprogramowanie służące do monitorowania oraz zarządzania pracą klastra opartego o openMosix. Paczka ta wymagała instalacji paczki openmosix, która zawiera narzędzia przestrzeni użytkownika (userland tools) do 67 kontroli podsystemu openMosix, jednak zdecydowano się pobrać wersję źródłową narzędzi z http://www.openmosix.org i skompilować ją. Powodem takiej decyzji jest wymóg, by narzędzia openMosixa były dopasowane na poziomie kompilacji do bieżącej wersji jądra. make, patch, libc6-dev, libncurses5-dev, linux-kernel-headers, libssl-dev, etc. – komponenty umożliwiające „nakładanie” łat na źródła aplikacji, własną ich kompilację, etc. g++, czyli kompilator C++ wraz z bibliotekami, wymagane do kompilacji wspomnianych wcześniej narzędzi przestrzeni użytkownika openMosix iproute, tcpdump – narzędzia wspierające konfigurację i testowanie klastra 4.2. Przygotowanie jądra Po zainstalowaniu powyższego oprogramowania możliwe się stały pewne operacje na źródłach aplikacji – w tym źródłach jądra Linuxa, – między innymi ich łatanie oraz kompilacja. Jako że zamiana systemu operacyjnego Linux na system wspierający klastry openMosix polega przede wszystkim na modyfikacji jego jądra, uczyniono to w następnej kolejności. Oryginalna dystrybucja cdlinux.pl-mały 0.5.7-pre2 pracuje pod kontrolą jądra linux2.4.25-Debian. W okresie pisania niniejszej pracy jest to najnowsze jądro Linuxa. Projekt openMosix mieści się w internetowym serwisie dostępnym pod adresem http://www.openmosix.org i stamtąd też można pobrać łaty na czyste – „waniliowe” (vanilla) – źródła jądra Linuxa. Najświeższe łaty były w tym serwisie dostępne na jądro linux-2.4.22 (łata o nazwie openMosix-2.4.22), czyli o 3 wersje wcześniejsze, niż to, o które zaplanowano oprzeć system operacyjny klastrowy cdlinux.pl. Nie było to zadowalające rozwiązanie, jednak przeprowadzone zostały długotrwałe próby „założenia” łaty openMosix-2.4.22 na jądro linux2.4.25. W przypadku łat, które nie wprowadzają ekstensywnych zmian w jądrze, nałożenie łaty na inną wersję jądra nie nastręcza większych problemów. Problem dopasowania zmienianych przez łatę fragmentów kodu sprowadza się w takich przypadkach do niewielkiej 68 zmiany numerów linii, które adresuje łata, czy też bezpośredniego otoczenia zmienianych linii. Łata openMosix, jednak, okazała się ingerować bardzo głęboko w struktury jądra. Nie stanowiłoby to poważnego problemu, gdyby samo jądro Linuxa nie uległo gruntownym zmianom pomiędzy wersjami 2.4.22 i 2.4.25. Fakty te zadecydowały o wszczęciu poszukiwania innego rozwiązania. Z pomocą przyszedł serwis internetowy dostępny pod adresem [TUOM]. Mieści się tam nieoficjalny projekt wsparcia środowiska openMosix – przede wszystkim oferuje on łaty dla wszystkich najnowszych wersji jądra Linuxa, łącznie z wersją 2.6.x. Pobrano łatę o nazwie patch-2.4.25-om-2040415, która jest łatą wzbogacającą źródło Linuxa w wersji 2.4.25 o podsystem openMosix. Łaty tej nie można było „założyć” na jądro linux-2.4.25-Debian w sposób trywialny. Jądro to różni się od „waniliowego” jądra Linuxa pewnymi drobnymi poprawkami oraz obecnością pewnych sterowników urządzeń. Przerobienie łaty, jednak, nie nastręczyło tak poważnych problemów, jakie miały miejsce przy próbie „nałożenia” łaty openMosix-2.4.22 na jądro linux-2.4.25. Tak powstało jądro systemu operacyjnego klastrowy cdlinux.pl o nazwie linux-2.4.25-Debian-om. Sufiks „om” jest skrótem od „openMosix”. 4.2.1. Wsparcie dla NFS w cramfs Systemem plików, na którym rezyduje większość plików cdlinux.pl, jest cramfs. Jest to prosty system plików napisany przez Linusa Torvaldsa charakteryzujący się kompresją danych oraz brakiem możliwości zapisu. Okazało się, niestety, iż cechuje go jeszcze jedna, bardzo uciążliwa właściwość — nie jest możliwe montowanie udziału NFS powstałego przez wyeksportowanie zamontowanego systemu plików cramfs. Wnikliwa analiza NFS ukazała przyczynę takiego zachowania. W jądrze Linuxa funkcjonuje VFS (Virtual File System) [LINUXFS] [LVFSL], czyli warstwa abstrakcji ujednolicająca dostęp do zasobów systemu plików. Obiektami w VFS są: Pliki. Pliki są jednostkami, z których można czytać i w których można zapisać dane. Można je też odwzorować w pamięci. Strukturą, która opisuje plik, jest struct file. 69 I-węzły. I-węzeł opisuje podstawowy obiekt w systemie plików – może być to plik, katalog, dowiązanie symboliczne, etc. Każdy i-węzeł posiada w obrębie swojego systemu plików unikalny numer. I-węzły są reprezentowane przez strukturę struct inode. W większości przypadków z plikami związane są i-węzły, przy czym w ogólności jest to relacja „wiele do wiele”. Istnieją pliki, które nie posiadają związanych ze sobą i-węzłów (np. gniazda internetowe, potoki nienazwane), a także odwrotnie — i-węzły, które nie posiadają związanych ze sobą plików (np. dowiązania symboliczne). Pliki, oprócz stałych informacji, zawierają również informacje o stanie pliku, np. wskaźnik pozycji odczytu/zapisu w pliku. Systemy plików. Są to obiekty stanowiące zbiór i-węzłów wchodzących w skład systemu plików, począwszy od i-węzła katalogu głównego (/). Opisywane są przez strukturę zwaną superblokiem – struct superblock. Istnieje ścisła korelacja między superblokami, a numerami urządzeń – każdy system plików, do którego następuje odwołanie, musi mieć niepowtarzalny numer urządzenia, na którym rezyduje (np. numer dysku twardego wraz z numerem partycji). Nazwy. Dostęp do i-węzłów w systemie plików uzyskuje się najczęściej poprzez nazwy (inny sposób to np. trawersowanie listy i-węzłów począwszy od i-węzła głównego katalogu poznanego z superbloku). Dla różnych systemów plików odzwierciedlenie nazwy na i-węzeł jest mniej lub bardziej czasochłonne, jednak zawsze wymaga to przeszukania plików będących katalogami. Z tego powodu istnieje w VFS warstwa pamięci podręcznej nazw opisywana przez strukturę zwaną dcache. Jest to struktura mająca postać drzewa, które jest poddrzewem drzewa nazw systemu plików. Elementy tej struktury, czyli obiekty struct dentry, są pośrednikami między plikami a i-węzłami. Dla każdego otwieranego pliku tworzony jest obiekt dentry związany z tym plikiem (również z i-węzłem związanym z tym plikiem) oraz obiekty dentry dla wszystkich przodków w drzewie plików otwieranego pliku. Wynika z tego, że dla każdego otwieranego pliku istnieją w pamięci obiekty dentry oraz inode związane z nim oraz z każdym jego przodkiem. NFS jednoznacznie identyfikuje zasoby systemów plików przez tzw. uchwyty plików (file handle). Nie jest sprecyzowane, jaka powinna być struktura uchwytu – jest definiowana 70 odrębnie przez każdy system plików. Niemniej jednak powinna zawierać takie dane, by serwer był w stanie jednoznacznie zidentyfikować wymagany zasób, czyli np. numer urządzenia, na którym rezyduje system plików, numer i-węzła, ew. numer i-węzła katalogu będącego jego bezpośrednim przodkiem. Często w uchwycie przechowywany jest tzw. pokolenie (generation). Jest to numer związany z i-węzłem systemu plików, który powinien ulec zmianie przy każdej modyfikacji i-węzła. Służy to wykryciu sytuacji, gdy przechowywane w kliencie NFS dane o pliku stają się nieaktualne z powodu zmiany danego pliku na serwerze NFS bez powiadomienia o tym klienta (np. z powodu zaniku łączności). Aby dojść na podstawie uchwytu do i-węzła, serwer NFS używa metod, które oferują poszczególne systemy plików. Metody te zamieniają uchwyt na dentry i na odwrót. Jeżeli stworzony został obiekt dentry i plik, do którego odnosi się obiekt odnosi, posiada i-węzeł, to z dentry związany jest obiekt inode. Nazwy tych metod to fh_to_dentry oraz dentry_to_fh, przy czym fh jest skrótem of file handle. Ich implementacja jest różna dla każdego systemu plików, przy czym mogą one w ogóle nie zostać zaimplementowane dla danego systemu plików. W takim przypadku jest on nieużyteczny jako udział serwera NFS. Właśnie taki przypadek ma miejsce w systemie plików cramfs. Spotkawszy się z brakiem reakcji twórcy systemu cramfs na prośby o wsparcie dla NFSa, autor zaimplementował brakujące metody samodzielnie. Na diagramie nr 14 znajduje się dotyczący nich kod źródłowy dodany do pliku linux/fs/cramfs/inode.c. Metodę cramfs_dentry_to_fh zaprojektowano w ten sposób, by tworzyła uchwyt do pliku składający się z dwóch lub trzech słów 32-bitowych. Pierwszym słowem jest numer i-węzła pliku, drugim jest pole generation. Jeżeli metoda zostaje uruchomiona z parametrem need_parent ustawionym na wartość różną od zera, wtedy trzecie słowo uchwytu zawiera numer i-węzła bezpośredniego przodka pliku w hierarchii katalogów. Typ uchwytu przekazywany jest przez wartość zwracaną przez metodę. Jest to zawsze wartość 3. Metodę cramfs_fh_to_dentry zaprojektowano, by przeprowadzała operację odwrotną. Na podstawie uchwytu, w którym zapisane są numery i-węzła oraz generation, wyszukuje dany i-węzeł w systemowej tablicy dcache. Na znalezionym numerze przeprowadza szereg testów (między innymi sprawdza, czy numer generation i-węzła równa się temu z uchwytu). Jeżeli wszystko się zgadza, metoda zwraca obiekt typu dentry. 71 ... #include <linux/nfsd/nfsfh.h> ... static struct dentry * cramfs_fh_to_dentry(struct super_block *sb, __u32 *fh, int len, int fhtype, int parent) { struct inode *in = NULL; struct list_head *lp; struct dentry *result; if (fhtype != 3) return ERR_PTR(-ESTALE); if (len < 2) return ERR_PTR(-ESTALE); in = iget(sb, ino_t_to_u32(fh[0])); if (!in || is_bad_inode(in) || in->i_generation != fh[1]) { if (in) iput(in); in = NULL; } if (!in) return ERR_PTR(-ESTALE); } spin_lock(&dcache_lock); for (lp = in->i_dentry.next; lp != &in->i_dentry ; lp = lp->next) { result = list_entry(lp, struct dentry, d_alias); if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) { dget_locked(result); result->d_vfs_flags |= DCACHE_REFERENCED; spin_unlock(&dcache_lock); iput(in); return result; } } spin_unlock(&dcache_lock); result = d_alloc_root(in); if (result == NULL) { iput(in); return ERR_PTR(-ENOMEM); } result->d_op = sb->s_root->d_op; result->d_flags |= DCACHE_NFSD_DISCONNECTED; return result; static int cramfs_dentry_to_fh(struct need_parent) { if (*lenp < 2) { return 255; } } dentry *de, __u32 *fh, int *lenp, fh[0] = ino_t_to_u32(de->d_inode->i_ino); fh[1] = de->d_inode->i_generation; *lenp = 2; if (need_parent && de->d_parent) { *lenp = 3; fh[2] = ino_t_to_u32(de->d_parent->d_inode->i_ino); } return 3; Diagram 14. Poprawki źródła jądra Linuxa rozbudowujące system plików cramfs o wsparcie dla NFS 72 int Zmodyfikowano również strukturę super_operations, by dodatkowe funkcje zostały rozpoznawane przez jądro: static struct super_operations cramfs_ops = { read_inode: make_bad_inode, statfs: cramfs_statfs, fh_to_dentry: cramfs_fh_to_dentry, dentry_to_fh: cramfs_dentry_to_fh, }; Diagram 15. Ciag dalszy poprawek źródła jądra Linuxa rozbudowujących system plików cramfs o wsparcie dla NFS 4.2.2. Opcje kompilacji jądra Linuxa Źródła jądra Linuxa linux-2.4.25-Debian pobrano przez narzędzie apt-get jako kernelsource-2.4.25. „Założono” na nie łatę rozbudowującą jądro o podsystem openMosix oraz ww. łatę poprawiającą wsparcie dla systemu plików cramfs, po czym skompilowano. Zestaw opcji kompilacji jądra zmieniono względem konfiguracji jądra oryginalnego cdlinux.pl. Zmiany te zestawiono poniżej. Tabela 1. Zestawienie opcji kompilacji ważnych dla jądra rozbudowanego o openMosix 73 Opcja kompilacji źródła jądra Linuxa Opis opcji CONFIG_MOSIX=y Wsparcie dla podsystemu openMosix. CONFIG_MOSIX_SECUREPORTS=y openMosix używa w celach wewnętrznych portów TCP i UDP. Połączenia użytkowników na te porty są niedozwolone. Jednak jeżeli dany węzeł jest dostępny w sieci pod innymi numerami IP, niż te, o których openMosix wie, połączenia na te IP i numery zastrzeżonych portów są dozwolone. Ustawienie opisywanej opcji na ‘y’ sprawia, że połączenia na zastrzeżone porty dla wszystkich numerów IP są niedozwolone. CONFIG_MOSIX_DISCLOSURE=1 Ilość danych ujawnianych przez procesy, które są uruchamiane jako goście na zdalnych węzłach: 0 – zero informacji 1 – tylko PID (oraz TGID, jeżeli różny od PID) 2 – PID(/TGID), UID, GID 3 – PID(/TGID), UID, GID, PGRP, SESSION, COMMAND CONFIG_MOSIX_FS=y Wsparcie dla klastrowego sieciowego systemu plików oMFS (openMosix File System) CONFIG_MOSIX_DFSA=y Wsparcie dla DFSA (Direct File System Access). CONFIG_MOSIX_PIPE_EXCEPTIONS Wsparcie dla powiadamiania programu o tym, =y że ktoś chce odczytywać z pipe’a. Poprzez odpowiednią konfigurację danego pipe’a przy użyciu mechanizmu ioctl (komenda TCSBRK), można określić, czy próba czytania, bądź fakt nie istnienia czytelników pipe’a będzie kończyła się zgłoszeniem wyjątku. CONFIG_MOSIX_NO_OOM=y Wyłączenie funkcji jądra Linuxa polegającej na zabijaniu procesów w obliczu niedoboru pamięci. W przypadku openMosixa takie zdarzenie może mieć miejsce, gdy procesy wracają w większej ilości na węzeł macierzysty, gdyż jądro często przeszacowuje rozmiar pamięci, który jest potrzebny dla procesów. CONFIG_BLK_DEV_RAM_SIZE=1638 Zwiększenie maksymalnego rozmiaru 4 ramdisku do 16384 bajtów. Domyślnym rozmiarem jest 8192 bajtów, co okazało się niewystarczające w implementacji klastrowego cdlinux.pl. 74 Poniższe opcje polegają na wbudowaniu w jądro tych komponentów, które istniały w cdlinux.pl, lecz były zbudowane jako moduły. W klastrowym cdlinux.pl jest to niemożliwe, gdyż komponenty te są potrzebne przy uruchamianiu systemu przez sieć — jądro już na samym początku musi mieć wsparcie dla sieci, sieciowych systemów plików, etc. Tabela 2. Zmodyfikowane opcje kompilacji jądra Opcja kompilacji źródła jądra Linuxa Opis opcji CONFIG_UNIX=y Wsparcie dla gniazdek (sockets) domeny UNIX. CONFIG_IP_PNP=y Wsparcie dla automatycznej konfiguracji sieci w jądrze Linuxa (urządzenia, adresy, trasy). CONFIG_IP_PNP_BOOTP=y Wsparcie dla pobierania adresu IP przy automatycznej konfiguracji jądra Linuxa z serwera BOOTP. CONFIG_NFS_FS=y Wsparcie dla sieciowego systemu plików NFS (Network File System). W klastrowym cdlinux.pl węzły są po części uruchamiane z udziałów systemu NFS. CONFIG_ROOT_NFS=y Wsparcie dla montowania jako głównego (root) systemu plików, czyli katalogu /, udziału NFS. CONFIG_NFSD=y Wsparcie dla funkcjonowania Linuxa jako serwera NFS. Funkcjonalność ta jest wymagana jedynie na kontrolerze klastra, ale postanowiono zachować jednolitą konfigurację jąder kontrolera klastra i jego węzłów. CONFIG_SUNRPC=y Opcje włączane automatycznie przy dodaniu CONFIG_LOCKD=y wsparcia dla systemu plików NFS, bądź dla serwera NFS. CONFIG_XXX=y Sterowniki dla szeregu kart sieciowych Ethernet, które były oryginalnie budowane jako moduły, a obecnie muszą być wbudowane w jądro. Po ustawieniu konfiguracji kompilacji zgodnie z powyższym zestawieniem, skompilowano i zainstalowano jądro wraz z modułami poleceniami: # make dep clean bzImage modules modules_install # cp arch/i386/boot/bzImage /boot/vmlinuz-2.4.25-Debian-om # cp System.map /boot/System.map-2.4.25-Debian-om Diagram 16. Procedura instalacji skompilowanego jądra Linuxa 75 4.3. Przygotowanie programu ładującego ISOLINUX Oryginalny cdlinux.pl uruchamiany jest przy użyciu programu ISOLINUX. W tym celu na płycie umieszczany jest katalog /isolinux, który zawiera właściwy kod wykonywalny programu, pliki pomocnicze, konfiguracyjne oraz plik jądra wraz initrd. Aby system operacyjny klastrowy cdlinux.pl korzystał z nowo skompilowanego jądra, dokonano zmian w katalogu /isolinux. Katalog ten nie jest kopiowany z CD-ROMu przy instalacji cdlinux.pl na dysk twardy, zatem należy wykonać to manualnie. Katalog ten zawiera pliki: • boot.cat, isolinux.bin, isolinux.cat – pliki z kodem ISOLINUXa • intro.msg, syslogo.lss – pliki zawierające wiadomość startową oraz logo • isolinux.cfg – plik konfiguracyjny • root.gz – skompresowany initrd • zimage – plik jądra Aby zmienić zachowanie ISOLINUXa wyedytowano plik konfiguracyjny isolinux.cfg. Jego treść po zmianach kosmetycznych (nazwa uruchamianego systemu) przedstawiona została na diagramie nr 17. prompt 1 timeout 100 say cdlinux.pl klastrowy label linux display intro.msg kernel zimage append initrd=root.gz ramdisk_size=65536 root=/dev/ram4 label noram kernel zimage Diagram 17. Zawartość pliku isolinux.cfg Podobnie zmieniono plik intro.msg, którego zawartość po zmianie przedstawia diagram nr 18. <Ctrl-W> <Ctrl-X>syslogo.lss <Ctrl-D>Dystrybucja systemu GNU/Linux - cdlinux.pl klastrowy <Ctrl-R> Diagram 18. Zawartość pliku intro.msg 76 Jak widać powyżej, ISOLINUX został skonfigurowany, by uruchomić jądro systemu Linux z pliku zimage. Parametry przekazane do jądra wyglądają następująco: initrd=root.gz ramdisk_size=65536 root=/dev/ram4 co spowoduje, że głównym system plików zostanie ramdisk o maksymalnym rozmiarze wynoszącym 65536 bajtów wczytany do urządzenia /dev/ram4 z pliku root.gz. W tym początkowym systemie plików znajdują się między innymi moduły jądra ze sterownikami do urządzeń blokowych i ich kontrolerów, z których w następnej kolejności montowane są systemy plików. Po kompilacji jądra, a dokładniej jego części modułowej, przeniesiono wymagane moduły do initrd’a używanego do uruchomienia klastrowego cdlinux.pl. Jest on zapisany w pliku będącym obrazem systemu plików ext2, zatem aby dokonać w nim zmian należy go rozkompresować oraz zamontować przy użyciu urządzenia /dev/loop, co jest osiągalne nie wprost poprzez polecenia: # gunzip isolinux/root.gz # mkdir -p /tmp/initrd # mount -o loop -t ext2 isolinux/root /tmp/initrd Moduły znajdowały się w katalogu /tmp/initrd/lib/modules/2.4.25/ initrd'a. Nazwa tego katalogu pochodzi od wersji jądra; w cdlinux.pl była to 2.4.25. Wersja jądra przygotowywanego klastrowego cdlinux.pl brzmi 2.4.25-Debian-om, zatem katalog dla modułów w przygotowywanym systemie plików będzie nosił nazwę /tmp/initrd/lib/modules/2.4.25-Debian.om/. Do tego katalogu przeniesiono część zawartości katalogu /lib/modules/2.4.25-Debian-om, w którym znajdują się zainstalowane wcześniej moduły nowo skompilowanego jądra Linuxa. Przeniesiono tylko takie moduły, które występowały w oryginalnym systemie plików initrd, za wyjątkiem modułów lockd.o oraz unix.o, gdyż odpowiadający im kod został wkompilowany do jądra za sprawą opcji kompilacji jądra CONFIG_LOCKD=y oraz CONFIG_UNIX=y. Funkcjonalność ta jest potrzebna do pracy NFS, która ma miejsce jeszcze przed zamontowaniem docelowego głównego systemu plików. Dokonano zmian w programie, który jest uruchamiany po zamontowaniu initrd. Jest to zawsze program o nazwie /linuxrc. W oryginalnym initrd cdlinux.pl program ten został napisany przez Michała Wróbla, natomiast w klastrowym cdlinux.pl został wzbogacony przez autora pracy o wsparcie dla katalogu /slave2 na osobnym ramdisku. Również stworzony 77 zostaje katalog /initrd, który jest miejscem, do którego przerzucany jest system plików używany w initrd, by można go było następnie odmontować i zwolnić tym samym pamięć. Na diagramie nr 19 przedstawiono fragmenty /linuxrc wraz z zaznaczonymi dodanymi liniami tłustym drukiem. Omawiane zmiany mają wpływ na proces uruchamiania się kontrolera klastra, a dokładniej na algorytm realizowany przez program /etc/init.d/join. Zostanie to opisane w dalszej części pracy. Po tych zmianach odmontowano initrda i skompresowano go do użycia w przez ISOLINUX: # umount /tmp/initrd # rmdir /tmp/initrd # gzip -9nf isolinux/root Następnie nowo skompilowane jądro systemu, które zostało zapisane do /boot/vmlinuz-2.4.25-Debian-om, zostało skopiowane do pliku zimage w katalogu isolinux, by uruchomił je ISOLINUX podczas ładowania systemu. Sam katalog isolinux należy skompresować i otrzymaną nazwę isolinux.tgz przenieść do katalogu /cdlinux/, gdyż w tym miejscu będzie go szukał program tworzący obraz płyty: # cp -f /boot/vmlinuz-2.4.25-Debian-om isolinux/zimage # tar czvf /cdlinux/isolinux.tgz isolinux/ 78 echo -en $"Tworzenie ramdiskow" dd if=/dev/zero of=/dev/ram4 bs=1k count=$RAMSIZE >/dev/null 2>/dev/null echo -en $"." mke2fs $NODES -m0 /dev/ram4 $RAMSIZE -q >/dev/null 2>/dev/null echo -en $"." RAMSIZE=25600 NODES="-N 10000" dd if=/dev/zero of=/dev/ram1 bs=1k count=$RAMSIZE >/dev/null 2>/dev/null echo -en $"." mke2fs $NODES -m0 /dev/ram1 $RAMSIZE -q >/dev/null 2>/dev/null echo -en $"." echo # Tworzy odpowiednie katalogi -/dev/ram4 - root file system echo -en $"Kopiowanie plikow dla glownego systemu plikow..." bash ./progress.sh 2>/dev/null& mkdir /ramdisk mount -n -t ext2 /dev/ram4 /ramdisk mkdir /ramdisk/tmp mkdir /ramdisk/proc mkdir /ramdisk/mnt mkdir /ramdisk/mnt/floppy mkdir /ramdisk/mnt/cdrom mkdir /ramdisk/usr mkdir /ramdisk/cdlinux mkdir /ramdisk/cdlinux/lib mkdir /ramdisk/cdlinux/usr2 mkdir /ramdisk/cdlinux/usr3 mkdir /ramdisk/mnt/ram2 mkdir /ramdisk/slave2 mkdir /ramdisk/initrd mount -n -t ext2 /dev/ram1 /ramdisk/slave2 cd /ramdisk tar xfz /cdrom/bin.tgz >/dev/null 2>/dev/null tar xfz /cdrom/etc.tgz >/dev/null 2>/dev/null tar xfz /cdrom/lib.tgz >/dev/null 2>/dev/null tar xfz /cdrom/sbin.tgz >/dev/null 2>/dev/null tar xfz /cdrom/slave2.tgz >/dev/null 2>/dev/null cp -dpR /cdrom/dev /ramdisk cp -dpR /cdrom/home /ramdisk cp /bin/colrm /ramdisk/bin cp /bin/expr /ramdisk/bin chmod a+wxt /ramdisk/tmp chmod 555 /ramdisk/proc cd / if [ $COPY -eq 1 ]; then mkdir /ramdisk/cramfs cp /cdrom/cramfs/lib /ramdisk/cramfs cp /cdrom/cramfs/var /ramdisk/cramfs fi cd / kill $! >/dev/null 2>/dev/null cd / umount /ramdisk/slave2 umount /ramdisk umount /dev/$CDDRV >/dev/null 2>/dev/null Diagram 19. Treść skryptu /linuxrc 79 4.4. Przygotowanie systemów plików Jednym z pierwszych skryptów, który jest uruchamiany przez /sbin/init, jest program /etc/init.d/join. Zadaniem tego skryptu jest przygotowanie poszczególnych systemów plików – zamontowanie ich z CD-ROMu w przypadku pracy systemu z CD-ROMu, i/lub kopiowaniu obrazów systemów plików do ramdisków i montowaniu ich stamtąd. Jest to skrypt stworzony dla systemu cdlinux.pl i zmodyfikowany dla potrzeb systemu klastrowy cdlinux.pl. Zmiany polegają na dodaniu wsparcia dla katalogu /slave2 montowanego jako osobny system plików na oddzielnym ramdisku. Również tworzony jest katalog /mfs, który będzie punktem montowania systemu plików oMFS. Fragment wykonanego skryptu obrazujący zmiany zamieszczono na diagramie nr 20. mount -n -o remount,rw / [ -f "/initrd/cdrom/etc.tgz" ] && \ umount /initrd/cdrom COUNT=1 CDFOUND=1 ... mkdir /root mount -t tmpfs /dev/ram5 /root tar xfz /cdrom/root.tgz -C /root mkdir /var mount -t tmpfs /dev/ram6 /var tar xfz /cdrom/var.tgz -C /var mkdir /cdlinux/var mkdir /mfs mount -n -t ext2 /dev/ram1 /slave2 if [ -f /cramfs/lib ]; then mkdir /cramfs/ram3 Diagram 20. Skrypt /etc/init.d/join, który przygotowuje system plików 80 4.5. Narzędzia openMosix Do projektu openMosix zalicza się zestaw narzędzi, które między innymi służą do inicjacji klastra, zarządzania nim, diagnostyki. Pobrano je w postaci źródłowej przez serwis internetowy [OMWWW]. Skompilowano je i zainstalowano następującymi poleceniami: # ./configure -–with-kerneldir=/usr/src/linux # make # make install # # This file can be used to change the default behaviour of the # openMosix startup-script. # # Force autodiscovery-daemon to start, even with a valid # .map-file AUTODISC=1 # Specify which network interface the autodiscovery-daemon # should listen to AUTODISCIF=eth0 # Set the values of /proc/hpc/admin/overheads # OVERHEADS= # Set the values of /proc/hpc/admin/mfscosts # MFSCOSTS= # Set the openMosix node-id of this node # MYOMID= # Set maximum number of gateways between openMosix nodes # (see man setpe) # MOSGATES= # # # # Pass the following value to mosctl setspeed when starting the node man mosctl for details NODESPEED=10000 # Processes are allowed to migrate to other nodes. MIGRATE=yes # Allow guest processes to arrive. BLOCK=no # Don't use MFS MFS=yes Diagram 21. Zawartość pliku konfiguracyjnego narzędzi openMosix - /etc/openmosix/openmosix.cfg Narzędzia inicjujące podsystem openMosix mają swój plik konfiguracyjny w /etc/openmosix/openmosix.cfg. Na diagramie nr 21 przedstawiono jego zawartość dla kontrolera klastra i dla węzła. W stanie wyjściowym są identyczne, z tym że na 81 kontrolerze klastra plik ten jest modyfikowany przez konfigurator yahade przystosowany do klastrowego cdlinux.pl. Zmieniany tam jest parametr AUTODISCIF zgodnie z nazwą interfejsu sieciowego używanego do podłączenia kontrolera do klastra. 4.6. Zmiany dokonane przez yahade Przy uruchamianiu kontrolera klastra konieczne jest dokonanie pewnych zmian w konfiguracji, które są spowodowane niezdeterminowaną przy budowie systemu konfiguracją sieciową. Zajmuje się tym konfigurator yahade, który został zmodyfikowany względem wersji tegoż programu z cdlinux.pl. Program wzbogacono o edycję i generację plików konfiguracyjnych różnych usług kontrolera klastra oraz plików definiujących zachowanie węzła klastra przy uruchamianiu. Interfejs sieciowy służący do połączenia z klastrem jest rozpoznawany po tym, iż jest to ostatni skonfigurowany ręcznie interfejs w programie yahade. Plikami, które yahade zmienia, bądź tworzy, są (oprócz tych przetwarzanych przez oryginalną wersję): • /etc/default/dhcp Jest to konfiguracja skryptu inicjującego serwer DHCP. Zmiana polega na ustawieniu obecnego w pliku parametru INTERFACES, który określa, na których interfejsach sieciowych serwer DHCP ma działać. Wartość tego parametru zostaje ustalona zgodnie z nazwą interfejsu oznaczonego, jako służący do połączenia z klastrem. • /etc/dhcpd.conf Jest to plik konfiguracyjny serwera DHCP. Zostają w nim zapisane następujące dyrektywy (przykład dla interfejsu skonfigurowanego 192.168.1.10/24, czyli z maską podsieci 255.255.255.0): 82 numerem IP allow bootp; option domain-name "cdlinux.cluster"; next-server 192.168.1.10; filename "/etc/tftpboot/pxelinux.0"; Diagram 22. Przykładowy nagłówek wygenerowanego przez yahade pliku dhcpd.conf oraz po jednej sekcji subnet dla każdego skonfigurowanego ręcznie interfejsu sieciowego: subnet 192.168.1.0 netmask 255.255.255.0 { option subnet-mask 255.255.255.0; option routers 192.168.1.10; range dynamic-bootp 192.168.1.11 192.168.1.254; } Diagram 23. Przykładowa sekcja subnet wygenerowanego przez yahade pliku dhcpd.conf Przedział IP przeznaczony dla dynamicznego przydzielania IP węzłom wybierany jest przez pewien algorytm. Polega on na tym, by użyć przestrzeni adresów w obrębie zdefiniowanej podsieci powyżej adresu IP samego serwera, a jeżeli jest to ostatni IP podsieci, to należy użyć przestrzeni adresów w obrębie podsieci poniżej adresu IP serwera. • /etc/tftpboot/pxelinux.cfg/default Plik ten definiuje konfigurację programu PXELINUX uruchamiającego jądro Linuxa na węźle klastra. Zmiana przeprowadzona przez yahade polega na zdefiniowaniu numeru IP serwera NFS przekazanego do jądra węzła klastra przez parametr nfsroot=. Węzeł jest uruchamiany z głównym systemem plików montowanym przez NFS, więc musi znać tą informację przed uruchomieniem. Przykładową konfigurację PXELINUX przedstawia diagram nr 24. DEFAULT l2425Dom LABEL l2425Dom KERNEL vmlinuz-2.4.25-Debian-om APPEND nfsroot=192.168.1.10:/slave2 IPAPPEND 1 Diagram 24. Przykładowa zawartość pliku konfiguracyjnego /etc/tftpboot/pxelinux.cfg/default 83 • /slave2/etc/fstab Jest to konfiguracja systemów plików węzła klastra. Poszczególne systemy plików montowane są głównie przez NFS, do czego wymagana jest znajomość numeru IP bądź nazwy sieciowej serwera. Zdecydowano się na podawanie numerów IP, gdyż jest to najmniej zawodny sposób i najszybciej działający. Podobnie jak przy konfiguracji jądra węzła przy użyciu parametru linii poleceń nfsroot=, wymagane tu jest podanie adresu serwera NFS, czyli kontrolera klastra. Diagram nr 25 przedstawia przykład. 192.168.1.10:/slave2 /dev/ram4 proc /dev/fd0 192.168.1.10:/cdlinux 192.168.1.10:/usr 192.168.1.10:/cdlinux/lib 192.168.1.10:/cdlinux/usr2 192.168.1.10:/cdlinux/var mfs / /ramdisk /proc /mnt/floppy /cdlinux /usr /cdlinux/lib /cdlinux/usr2 /cdlinux/var /mfs nfs ext2 proc auto nfs nfs nfs nfs nfs mfs defaults,ro defaults defaults user,noauto defaults defaults defaults defaults defaults noauto 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 Diagram 25. Zawartość pliku /slave2/etc/fstab będącego konfiguracją systemów plików węzła klastra • /root/.ssh Jest to katalog, w którym ma miejsce definicja konfiguracji ssh [MAN1]. Jak opisano we wcześniejszych częściach pracy, należy zapewnić, by na każdym z węzłów można było otworzyć sesję z kontrolera klastra bez podawania hasła. W tym celu użyto metody uwierzytelnienia opartej o klucz publiczny. Dla ułatwienia jest to jedna para kluczy (publicznego i prywatnego) dla wszystkich węzłów klastra. Program yahade został zmodyfikowany, aby generował parę kluczy RSA za pomocą polecenia ssh-keygen, plik /root/.ssh/id_rsa skutkiem zawierający czego klucz powstaje prywatny oraz /root/.ssh/id_rsa.pub zawierający klucz publiczny. Klucz publiczny zostaje zapisany do katalogu, który będzie dostępny jako /root/.ssh/ na węźle klastra, czyli do pliku /slave2/root/.ssh/authorized_keys, natomiast klucz prywatny zostaje w /root/.ssh/. Dodatkowo wygenerowany zostaje plik /root/.ssh/known_hosts, gdzie dla każdego możliwego numeru IP 84 węzła klastra zapisana zostaje linia z kluczem publicznym serwera ssh węzła, pobranym z pliku /slave2/etc/ssh/ssh_host_rsa_key.pub. Dzięki temu nie będzie wymagane przy pierwszym połączeniu potwierdzenie autentyczności klucza, co by wymagało interakcji użytkownika. • /etc/hosts oraz /slave2/etc/hosts Jest to systemowa baza danych DNS. Przy połączeniach między węzłami klastra niektóre usługi próbują znaleźć nazwę sieciową przynależącą do IP, z którym nawiązywane jest połączenie. Jest to podyktowane czasem potrzebą bezpieczeństwa, a innym razem – ustalenia konfiguracji w zależności od nazwy sieciowej. W przypadku braku informacji o przynależności nazw sieciowych do adresów IP, każda próba ustalenia nazwy długo trwa. W tym celu yahade generuje listę mapowań między adresami IP a nazwami sieciowymi, która następnie zostaje zapisana do systemowej bazy danych DNS /etc/hosts oraz do jej odpowiednika dla węzła klastra, czyli do /slave2/etc/hosts. Przykład wygenerowanego pliku bazy danych DNS /etc/hosts przedstawia diagram nr 26. 127.0.0.1 192.168.1.10 192.168.1.11 192.168.1.12 192.168.1.13 ... localhost cdlinux cdlinux0 cdlinux1 cdlinux2 Diagram 26. Przykładowa zawartość pliku /etc/hosts • /etc/openmosix/openmosix.config Jest to konfiguracja skryptu inicjującego podsystem openMosix na kontrolerze klastra. Podobny plik istnieje na węźle klastra, jednak jego zawartość nie ulegnie zmianie w zależności od konfiguracji IP, gdyż przyjmuje się, że węzeł będzie podłączony do klastra zawsze na pierwszej z dostępnych kart sieciowych. Przykład tego pliku zamieszczono w poprzednim dotyczącym przygotowania narzędzi openMosix. Program yahade zmienia jedynie dyrektywę AUTODISCIF zgodnie z nazwą interfejsu sieciowego używanego do podłączenia do klastra. 85 Zamieszczono na diagramach nr 27, 28, 29 i 30 zmiany dokonane na kodzie programu yahade, który znajduje się w systemie operacyjnym w pliku /usr/bin/cdlcenter-yahade. Wytłuszczono linie, które zostały dodane lub zmienione. use Getopt::Std; use Socket; # Constants # use constant NOCD => 0; # 0 for cdlinux.pl use constant CDDUZY => 0; # 1 for cdlinux.pl duzy ... # ######################### sub cdl_net{ my %net_conf; my %buffer; my $buffer2; my $ipaddr, $netmask, $netaddr, $minrange, $maxrange, $maxip; my $conf_ip, $conf_mask, $conf_dns1, $conf_dns2, $conf_gw, $conf_eth; my $i, $j; &info_box("Proszę czekać...", "\n Wyszukiwanie karty sieciowej...") if(UI); open(DEVNET,"/proc/net/dev"); $interface="\n# Dodane przez cdlinux.pl\n"; ... $dns1="nameserver ".$net_conf{"dns1"}; $dns2="nameserver ".$net_conf{"dns2"}; $interface.="auto ".$net_conf{"eth"}."\niface ".$net_conf{"eth"}." inet static\n\taddress ".$net_conf{"ip"}."\n\tnetmask ".$net_conf{"mask"};"\n"; if ($net_conf{"gw"}!="") { $interface.="\tgateway ".$net_conf{"gw"}."\n"; } ; $interface.="\n"; if(!$TESTMODE){ ui_system($ifconfig); ui_system($route) if($net_conf{"gw"} !~ /^$/); open("RESOLV",">>/etc/resolv.conf"); print RESOLV ("$dns1\n") if($net_conf{"dns1"} !~/^$/); print RESOLV ("$dns2\n") if($net_conf{"dns2"} !~/^$/); close("RESOLV"); } $debug_info.="--\n<".$net_conf{"eth"}. ">\n$ifconfig\n$route\n/etc/resolv.conf:\n\t$dns1\n\t$dns2\n\n"; $ipaddr = inet_aton($net_conf{"ip"}); $netmask = inet_aton($net_conf{"mask"}); $netaddr = $ipaddr & $netmask; $netaddr_s = inet_ntoa($netaddr); $maxip = $netaddr | (pack ('N', (2 ** 32) - 1) ^ $netmask); Diagram 27. Zmiany wprowadzone do programu yahade, część 1 86 $maxrange_d = unpack ('N', $maxip) - 1; $minrange_d = unpack ('N', $ipaddr) + 1; if ($minrange_d > $maxrange_d) { $minrange_d = unpack ('N', $netaddr) + 1; $maxrange_d = unpack ('N', $ipaddr) - 1; } if ($minrange_d <= $maxrange_d) { $minrange = inet_ntoa (pack ('N', $minrange_d)); $maxrange = inet_ntoa (pack ('N', $maxrange_d)); } $buffer{"dhcpd.conf"} .= sprintf ("subnet %s netmask %s {\n\toption subnet-mask %s;\n\toption routers %s;\n\trange dynamic-bootp %s %s;\n}\n\n", $netaddr_s, $net_conf{"mask"}, $net_conf{"mask"}, $net_conf{"ip"}, $minrange, $maxrange); $conf_ip = $net_conf{"ip"}; $conf_mask = $net_conf{"mask"}; $conf_dns1 = $net_conf{"dns1"}; $conf_dns2 = $net_conf{"dns2"}; $conf_gw = $net_conf{"gw"}; $conf_eth = $net_conf{"eth"}; }else{ ui_system("dhclient -1 ".$net_conf{"eth"}) if(!$TESTMODE); ... if($DEBUGMODE){ &ui_debug($debug_info) if(UI); } # Configuration of various services according to network # settings # DHCP $buffer2 = ""; open (DEFAULTDHCP, "/etc/default/dhcp"); while (<DEFAULTDHCP>) { s/^INTERFACES=.*$/INTERFACES=\"$conf_eth\"/; $buffer2 .= $_; } close (DEFAULTDHCP); open (DEFAULTDHCP, ">/etc/default/dhcp"); print DEFAULTDHCP $buffer2; close (DEFAULTDHCP); $buffer2 = sprintf ("allow bootp;\n\noption domain-name \"cdlinux.cluster\";\n"); if ($conf_dns1) { $buffer2 .= "option domain-name-servers " . $conf_dns1; if ($conf_dns2) { $buffer2 .= ", " . $conf_dns2; } $buffer2 .= sprintf(";\n"); } Diagram 28. Zmiany wprowadzone do programu yahade, część 2 87 $buffer2 .= sprintf("next-server %s;\nfilename \"/etc/tftpboot/pxelinux.0\";\n\n", $conf_ip); $buffer2 .= $buffer{"dhcpd.conf"}; $buffer{"dhcpd.conf"} = $buffer2; open (DHCPDCONF, ">/etc/dhcpd.conf"); print DHCPDCONF $buffer{"dhcpd.conf"}; close (DHCPDCONF); # NFS my $exports = "/slave2 /cdlinux /usr /cdlinux/lib /cdlinux/usr2 /cdlinux/var"; $buffer{"exports"} = ""; for (split (/\ /, $exports)) { $buffer{"exports"} .= $_ . " " . $netaddr_s . "/" . $conf_mask . "(ro,sync,nohide,no_subtree_check,no_root_squash)\n"; } open (EXPORTS, ">/etc/exports"); print EXPORTS $buffer{"exports"}; close (EXPORTS); # PXELINUX $buffer{"pxelinux"} = ""; open (PXELINUX, "/etc/tftpboot/pxelinux.cfg/default"); while (<PXELINUX>) { s/ nfsroot=[^:]*:/ nfsroot=$conf_ip:/; $buffer{"pxelinux"} .= $_; } close (PXELINUX); open (PXELINUX, ">/etc/tftpboot/pxelinux.cfg/default"); print PXELINUX $buffer{"pxelinux"}; close (PXELINUX); # SLAVE/FSTAB $buffer{"fstab"} = ""; open (FSTAB, "/slave2/etc/fstab"); while (<FSTAB>) { s/^[^#:]*:/$conf_ip:/; $buffer{"fstab"} .= $_; } close (FSTAB); open (FSTAB, ">/slave2/etc/fstab"); print FSTAB $buffer{"fstab"}; close (FSTAB); # SSH ui_system("rm -f /root/.ssh/id_rsa{,.pub}"); ui_system("/usr/bin/ssh-keygen -t rsa -b 1024 -f /root/.ssh/id_rsa -P ''"); ui_system("cp -f /root/.ssh/id_rsa.pub /slave2/root/.ssh/authorized_keys"); Diagram 29. Zmiany wprowadzone do programu yahade, część 3 88 ui_system("mv -f /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys"); open (RSAKEY, "/slave2/etc/ssh/ssh_host_rsa_key.pub"); while (<RSAKEY>) { s/^([^ ]+) ([^ ]+) ([^ ]+)$/$1 $2/; $buffer2 = $_; } close (RSAKEY); $buffer{"ssh"} = ""; $i = $maxrange_d - $minrange_d; for (0..$i) { $buffer{"ssh"} .= &inet_ntoa(pack('N', $_ + $minrange_d)) . " " . $buffer2 . "\n"; } $buffer{"ssh"} .= $conf_ip . " " . $buffer2 . "\n"; open (SSH, ">/root/.ssh/known_hosts"); print SSH $buffer{"ssh"}; close (SSH); # ETC/HOSTS $buffer{"hosts"} = "127.0.0.1\tlocalhost\n"; $buffer{"hosts"} .= $conf_ip . "\tcdlinux\n"; $i = $maxrange_d - $minrange_d; for (0..$i) { $buffer{"hosts"} .= &inet_ntoa(pack('N', $_ + $minrange_d)) . "\tcdlinux" . (($_ + $minrange_d) & 255) . "\n"; } open (HOSTS, ">/etc/hosts"); print HOSTS $buffer{"hosts"}; close (HOSTS); open (HOSTS, ">/slave2/etc/hosts"); print HOSTS $buffer{"hosts"}; close (HOSTS); # OPENMOSIX OMDISCD $buffer{"omdiscd"} = ""; open (OMDISCD, "/etc/openmosix/openmosix.config"); while (<OMDISCD>) { s/^AUTODISCIF=.*$/AUTODISCIF=$conf_eth/; $buffer{"omdiscd"} .= $_; } close (OMDISCD); open (OMDISCD, ">/etc/openmosix/openmosix.config"); print OMDISCD $buffer{"omdiscd"}; close (OMDISCD); } Diagram 30. Zmiany wprowadzone do programu yahade, część 4 89 4.7. Usunięcie niepotrzebnego oprogramowania Na początku budowy systemu zainstalowano pewne oprogramowanie, z którego część była wymagana do pracy samego systemu operacyjnego klastrowy cdlinux.pl, natomiast pozostałą część stanowiły programy narzędziowe, które należy przed zakończeniem budowy usunąć, gdyż będą tylko niepotrzebnie zajmować miejsce w gotowym systemie operacyjnym. Takimi narzędziami są: • make, patch – narzędzia służące do kompilacji i łatania źródeł • biblioteki programistyczne libssl-dev, libncurses5-dev, libc6-dev, linux-kernelheaders • g++, g++-3.3, libstdc++5-3.3-dev – część pakietu kompilatora gcc, która odpowiada za kompilację C++ oraz potrzebne biblioteki. 4.8. System plików eksportowany do węzła Węzeł klastra uruchamiany jest przez sieć komputerową, a jego głównym systemem plików jest udział montowany przez NFS z kontrolera klastra. Katalogiem, który jest w tym celu wyeksportowany przez NFS, jest katalog /slave2. Z drzewa katalogów kontrolera klastra skopiowano do katalogu /slave2 katalogi /bin, /lib, /sbin. Założono katalog /readonly, do którego skopiowano katalogi /dev, /etc, /root, /var. Ideą takiego podziału jest to, iż katalogi mieszczące się w /readonly nie będą używane w wyjściowej postaci, tylko zostaną skopiowane do ramdisku, by ich zawartość mogła być modyfikowana podczas pracy systemu. W tym celu stworzono katalog /ramdisk, w którym przy uruchamianiu systemu będzie zamontowany ramdisk. Oczywiście katalogi /dev, /etc, /root, /var muszą być dostępne z poziomu katalogu głównego, dlatego stworzono w katalogu głównym dowiązania symboliczne o takich samych nazwach, jak owe katalogi, wskazujące każdy na podkatalog o tej samej nazwie mieszczący się w /ramdisk, dokąd w przyszłości zostaną skopiowane wersje z katalogu /readonly. Żeby jednak przed zamontowaniem ramdisku również istniał dostęp chociaż do statycznych wersji owych katalogów, stworzono dowiązania symboliczne od odpowiednich katalogów z /ramdisk do katalogów w /readonly. Oprócz katalogów istniejących w /readonly, w ramdisku będą również katalogi /home, /mnt i /tmp, 90 dlatego dowiązania symboliczne o tych nazwach również wskazują na podkatalogi /ramdisk. Wyjściową postać omawianych wyżej katalogów przedstawia diagram nr 31. / |-/bin `-/dev -> ramdisk/dev `-/etc -> ramdisk/etc `-/home -> ramdisk/home `-/lib `-/mnt -> ramdisk/mnt `-/ramdisk | |-dev -> ../readonly/dev | `-etc -> ../readonly/etc | `-root -> ../readonly/root | `-var -> ../readonly/var `-/readonly | |-dev | | |... | `-etc | | |... | `-root | | |... | `-var | |... `-/root -> ramdisk/root `-/sbin `-/tmp -> ramdisk/tmp `-/usr `-/var -> ramdisk/var Diagram 31. Wyjściowa zawartość katalogu /slave2 Katalog /dev skopiowano z kontrolera klastra bez zmian. Katalog /root stworzono w oparciu o standardowe skrypty .bashrc i .profile oraz uzupełniono o pusty katalog .ssh, przygotowany pod rozbudowę konfiguracji przez program yahade. Katalog /var skopiowano z pominięciem niepotrzebnych katalogów oraz plików. Katalog /etc, zawierający najwięcej istotnych szczegółów, skopiowano z pewnymi modyfikacjami. Z katalogów mieszczących skrypty inicjacyjne, czyli z /etc/init.d, zostały usunięte zbędne skrypty, a co ważniejsze – z katalogów /etc/rc*.d/ zostały usunięte 91 dowiązania symboliczne do skryptów, żeby niektóre z nich, które są używane na kontrolerze klastra, nie uruchamiały się na węźle. Dotyczy to głównie programów uruchamiających serwery NFS, dhcp, atftpd, openMosixcollector, etc. Jak opisano w rozdziale poświęconym uruchamianiu węzła klastra, zostały dodane skrypty wspomagające uruchamianie pod kątem przygotowania systemu plików oraz zróżnicowania nazw hosta poszczególnych węzłów klastra. Pierwszy ze wspomnianych skryptów to /etc/init.d/preparefs. Tworzy on ramdisk i montuje go w katalogu /ramdisk. Domyślnie ramdisk jest wielkości 12MB, co sprawia, że węzeł klastra potrafi pracować przy stosunkowo niewielkiej ilości pamięci operacyjnej. Po zamontowaniu ramdisku stworzone zostają na nim poszczególne katalogi i skopiowane zostają do niego podkatalogi katalogu /readonly, jak wspomniano wyżej. Na diagramie nr 32 przedstawiono kod źródłowy skryptu. #!/bin/sh # # Prepare read-write directories # RAMSIZE=12288 echo -en $"Tworzenie ramdiskow" dd if=/dev/zero of=/dev/ram4 bs=1k count=$RAMSIZE echo -en $"." mke2fs -N 10000 -m0 /dev/ram4 $RAMSIZE -q echo -en $"." echo mount mkdir mkdir mkdir mkdir mkdir mkdir mkdir chmod chmod -n -t ext2 /dev/ram4 /ramdisk /ramdisk/etc /ramdisk/var /ramdisk/tmp /ramdisk/root /ramdisk/home /ramdisk/mnt /ramdisk/dev 1777 /ramdisk/tmp 700 /ramdisk/root cd /readonly/etc tar cf - . | tar cd ../var/ tar cf - . | tar cd ../root/ tar cf - . | tar cd ../dev/ tar cf - . | tar cd / xf - -C /ramdisk/etc/ xf - -C /ramdisk/var/ xf - -C /ramdisk/root/ xf - -C /ramdisk/dev/ Diagram 32. Skrypt przygotowujący system plików węzła - /etc/init.d/preparefs 92 Drugim ze wspomnianych skryptów jest /etc/init.d/preparehostname. Jego zadanie jest proste – zmienia on nazwę hosta danego węzła w zależności od numeru IP, który został mu przydzielony przez bootp. Gdyby tego nie uczyniono, wszystkie węzły klastra posiadały taką samą nazwę hosta, co by wprowadziło zamęt podczas komunikacji. Kod źródłowy programu zamieszczono na diagramie nr 33. #!/bin/sh IPSUF=`/sbin/ifconfig | grep -A 1 eth0 | grep inet | sed "s,^.*:[0-9]*\.[0-9]*\.[0-9]*\.\([0-9]*\) .*Bcast.*$,\1,"` echo "Writing 'cdlinux${IPSUF}' into /etc/hostname" echo "cdlinux${IPSUF}" > /ramdisk/etc/hostname Diagram 33. Skrypt przygotowujący nazwę hosta węzła - /etc/init.d/preparehostname Kolejna zmiana polega na wyczyszczeniu zawartości pliku /etc/exports. Nic nie powinno być wyeksportowane z węzła domyślnie, nawet gdyby omyłkowo został włączony serwer NFS. Należy postarać się usunąć jak najwięcej zbędnych danych z systemu plików, aby nagrany na CD-ROM system operacyjny klastrowy cdlinux.pl był jak najmniejszej objętości. 4.9. Stworzenie płyty z dystrybucją Po przygotowaniu działającego systemu operacyjnego na roboczym twardym dysku, można go przetransportować na płytę CD-ROM z niewielkimi zmianami. W systemie operacyjnym cdlinux.pl służy do tego program cdlcenter-isomaker. Jak większość narzędzi cdlinux.pl, składa się on z części funkcyjnej i interfejsu użytkownika, które znajdują się w plikach odpowiednio cdlcenter-isomaker.sh oraz cdlcenter-isomaker.ui. Aby przygotowana płyta odzwierciedlała zmiany wprowadzone w systemie klastrowy cldinux.pl, należało zmodyfikować też program cdlcenter-isomaker.sh. Wprowadzone przez autora pracy zmiany polegają przede wszystkim na poprawieniu algorytmu przetwarzania plików przez program. W oryginalnej wersji program na początku usuwa zawartość katalogów /var/cache/apt/archives/ oraz /var/lib/apt/lists/ w celu zaoszczędzenia miejsca. W omawianej wersji katalog /var jest kopiowany do /tmp, podobnie jak inne katalogi mające się znaleźć na 93 płycie, po czym dopiero z kopii usuwane są niepotrzebne katalogi, podczas gdy oryginały na twardym dysku pozostają bez zmian. Pozostałe modyfikacje polegają na zmianie pliku /etc/fstab dystrybucji na płycie, gdyż istnieje dodatkowy system do zamontowania – oMFS w katalogu /mfs – oraz na dodaniu nowego katalogu do archiwizacji – /slave2. Na koniec konfigurator yahade zostaje skonfigurowany w ten sposób, by uruchamiany był wcześniej, niż w cdlinux.pl, gdzie uruchamiany był prawie na ostatnim miejscu. W systemie klastrowy cdlinux.pl uruchomienie zostało przeniesione przed inne skrypty, zaraz po uruchomieniu daemona logowania syslogd, gdyż od konfiguracji wygenerowanej przez yahade zależy zachowanie pozostałych części systemu operacyjnego, np. serwera atftpd, dhcp, NFS, podsystemu openMosix. Na diagramie nr 34 i 35 przedstawiono fragmenty programu cdlcenter-isomaker.sh, które zmieniono względem wersji z systemu cdlinux.pl. Wytłuszczono linie, które zostały dodane lub zmienione. # dodanie linka do join dla kazdego runlevelu cd $TEMP ln -s ../init.d/join etc/rcS.d/S11join 2>> $LOG_FILE ln -s ../init.d/yahade etc/rc2.d/S17yahade 2>> $LOG_FILE # Konfiguracja reboot dla CD cat <<EOF > $TEMP/etc/init.d/reboot ... # Konfiguracja fstab cat <<EOF > $TEMP/etc/fstab # /etc/fstab: statyczna informacja o systemach plikow. # # <system plikow> <punkt montowania> <typ> <opcje> <dump> <pass> /dev/ram4 / ext2 errors=remount-ro 0 1 proc /proc proc defaults 0 0 /dev/fd0 /mnt/floppy auto user,noauto 0 0 /dev/cdrom /mnt/cdrom iso9660 ro,user,noauto 0 0 mfs /mfs mfs defaults 0 0 EOF # czyszczenie ustawien sieci cp $TEMP/etc/network/interfaces.orig $TEMP/etc/network/interfaces # czyszczenie modules echo "" > $TEMP/etc/modules 2>> $LOG_FILE Diagram 34. Poprawki skryptu cdlcenter-isomaker.sh, część 1 94 #kopia /var dla bezpieczenstwa cp -dpr /var $TEMP # czyszczenie logow # kasowanie archiwow apt echo -en "Kasuje archiwa, cache, logi, backupy i listy apt z opii /var w $TEMP... " | tee -a $LOG_FILE rm $TEMP/var/cache/apt/archives/* 2>> $LOG_FILE # kasowanie cache pakietow rm $TEMP/var/cache/apt/*.bin 2>> $LOG_FILE # kasowanie logow find $TEMP/var/log -type f -exec bash -c 'echo -n > {}' \; 2>> $LOG_FILE # kasowanie backupow rm $TEMP/var/backups/* 2>> $LOG_FILE # kasowanie list apt rm $TEMP/var/lib/apt/lists/* 2>> $LOG_FILE echo -e "Zrobione!" | tee -a $LOG_FILE ... echo -en "Tworze /sbin... " | tee -a $LOG_FILE tar cfz $DIR/sbin.tgz sbin 2>> $LOG_FILE echo -e "Zrobione!" | tee -a $LOG_FILE echo -en "Tworze /slave2... " | tee -a $LOG_FILE tar cfz $DIR/slave2.tgz slave2 2>> $LOG_FILE echo -e "Zrobione!" | tee -a $LOG_FILE echo -en "Tworze /var... " | tee -a $LOG_FILE tar cfz $DIR/var.tgz -C $TEMP/var . 2>> $LOG_FILE echo -e "Zrobione !" | tee -a $LOG_FILE # Tworzenie obrazu plyty echo -en "Tworzenie obrazu: \n $DEST ... " | tee -a $LOG_FILE mkisofs -zR -o $DEST -b isolinux/isolinux.bin -c isolinux/boot.cat -noemul-boot -boot-load-size 4 -boot-info-table $DIR 2>> $LOG_FILE echo -e "Zrobione!" | tee -a $LOG_FILE echo -e "Operacja zakonczona!" | tee -a $LOG_FILE Diagram 35. Poprawki skryptu cdlcenter-isomaker.sh, część 2 4.10. Przygotowanie węzła do uruchomienia przez sieć Komputer, który ma być węzłem klastra zbudowanego w oparciu o klastrowy cdlinux.pl, musi mieć możliwość uruchomienia systemu operacyjnego przez sieć. Najbardziej korzystnie jest, gdy komputer wyposażony jest w kartę sieciową z pamięcią PROM (Programmable Read-Only Memory), w której jest, bądź do której można nagrać program ładujący zgodny z PXE. Wtedy system BIOS komputera należy skonfigurować tak, by próbował uruchomić system operacyjny przez sieć i proces powinien przebiegać zgodnie z opisem w rozdziale dotyczącym uruchamiania węzła klastra. 95 Niestety, większość współczesnych komputerów PC nie wspiera przedstawionego wyżej mechanizmu. W takiej sytuacji należy się posłużyć oprogramowaniem emulującym środowisko PXE. Programem przetestowanym przy współpracy z systemem klastrowy cdlinux.pl jest NetBoot [NETBOOT]. Głównym jego celem jest stworzenie obrazu do wgrania do pamięci PROM karty sieciowej, jednak przy jego pomocy możliwe jest stworzenie obrazu dyskietki, z której po uruchomieniu otrzymuje się środowisko PXE. W drugim przypadku wymagane są sterowniki do konkretnej karty sieciowej. Rozwiązanie takie wydaje się być uciążliwe, gdyż wymaga stworzenia tylu dyskietek, ile jest różnych kart sieciowych w komputerach, które mają stać się węzłami klastra. Z drugiej strony, przeważnie w większej ilości komputerów zgromadzonych razem są te same podzespoły, zatem najczęściej wystarczy jedna dyskietka dla całego laboratorium komputerowego. Pakiet NetBoot zawiera kilka programów. Używanym przy tworzeniu dyskietki startowej jest program makerom. Możliwe jest podanie opcji do programu, jednak nie jest to wymagane. Po uruchomieniu, użytkownikowi zostanie zadany szereg pytań. Pytania i przykładowe odpowiedzi zamieszczono na diagramie nr 36. Przy większości pytań zamkniętych zalecane są domyślne odpowiedzi. Przy wyborze karty sieciowej, należy wskazać posiadaną oraz ewentualnie podać dodatkowe parametry, np. IRQ, adres wejścia/wyjścia, adres pamięci współdzielonej (informacje ustawiane na karcie ISA). W przypadku kart PCI informacji takich nie trzeba podawać sterownikowi. NetBoot obsługuje większą ilość typów kart, niż wyświetlona na liście. Aby je obsłużyć, należy zdobyć sterownik pakietowy (ang. packet driver) albo sterownik NDIS2 od danego typu karty i umieścić go w katalogu <netboot>/lib/netboot/netdrvr/pktdrvr/, gdzie <netboot> jest rozumiane jako katalog bazowy instalacji pakietu NetBoot. Ostatnie pytanie ma na celu ustalenie typu formatu pliku, który ma zostać wygenerowany przez program. Może to być surowy kod, ew. formaty przydatne przy wgrywaniu do pamięci PROM (dla układów firmy Intel, Motorola lub Tektronix), czy do pamięci FlashCard przez sieć. Obraz dyskietki generowany jest przy każdym z rodzajów formatu wyjściowego. W przypadku dokonaniu wyboru tak, jak na przykładzie na diagramie nr 36, generowane są pliki image.rom oraz image.flo. 96 # makerom Bootrom configuration program, Version 0.9.8 (netboot) Copyright (C) 1995-2003 G. Kuhlmann Build bootrom for a processor older than 386 (y/n) [no] ? Include support for old-style menus (not recommended) (y/n) [no] ? Do you want the BIOS to look for boot disks (y/n) [no] ? Do you want the bootrom to ask before booting from network (y/n) [no] ? List of known network cards: (0) unknown card with user supplied driver (1) 3Com 3C501 Etherlink ISA (2) 3Com 3C503 Etherlink II ISA (3) 3Com 3C505 Etherlink Plus ISA (4) 3Com 3C507 Etherlink 16 ISA (5) 3Com 3C509 Etherlink III ISA (6) 3Com 3C509B Etherlink III ISA/PnP (7) 3Com 3C509B-Combo Etherlink III ISA/PnP (8) 3Com 3C509B-TP Etherlink III ISA/PnP (9) 3Com 3C509B-TPC Etherlink III ISA/PnP (10) 3Com 3C509B-TPO Etherlink III ISA/PnP (11) 3Com 3C523 Etherlink/MC MCA (12) 3Com 3C579 Etherlink III EISA (13) 3Com 3C579-TP Etherlink III EISA (14) AMD AM1500T ISA (15) AMD AM2100 ISA (16) ATI AT-2000 PnP (17) ATI AT-2560 PCI/100 (18) ATI AT-2560 PCI/100 TX (19) Accton EN1203 EtherDuo PCI (20) Accton EN1207 EtherCombo PCI (DEC chipset) Press <ENTER> to continue listing [... lista kart sieciowych do wyboru ...] Select a network card (-1 to review the list) [-1]: 3 You selected: 3Com 3C505 Etherlink Plus ISA Enter network driver options: Hardware IRQ number (decimal): 7 I/O address (hex): 330 Shared memory address (hex): b000 Do you want to use the packet driver debugger (y/n) [no] ? Do you want to specify an additional program (y/n) [no] ? Available output file types for rom image: (1) Raw binary (2) Intel hex (3) Motorola hex (4) Tektronix hex (5) Image for programming a FlashCard across the network Select the format you wish to use [1]: 1 Diagram 36. Program makerom służący do przygotowania obrazu dyskietki z emulatorem PXE 97 Pierwszy z nich jest obrazem w wybranym formacie (w tym przypadku – surowy kod), natomiast drugi plik zawiera obraz dyskietki startowej. Należy go załadować na dyskietkę poleceniem: # dd if=image.flo of=/dev/fd0 bs=512 po czym z dyskietki będzie można załadować system operacyjny. Aby tego dokonać, należy skonfigurować system BIOS przyszłego węzła klastra tak, by szukał systemu operacyjnego na dyskietce. 4.11 Gotowy produkt Zbudowano system operacyjny na dysku twardym, który po uruchomieniu staje się kontrolerem klastra. Pozostałe komputery w sieci LAN uruchamiają się korzystając z kontrolera klastra bez użycia własnych dysków twardych. Po odpowiednim skonfigurowaniu i zmodyfikowaniu programów stworzono obraz płyty CD-ROM, zawierający wersję wykonanego systemu operacyjnego przystosowaną do uruchamiania z CD-ROMu, bez potrzeby istnienia twardego dysku. Dużą trudność sprawiło dostosowanie implementacji systemu plików cramfs do pracy z NFS. Problem pojawił się niespodziewanie, gdyż z powodu uciążliwego procesu testowania gotowego systemu operacyjnego na płycie CD-ROM (po każdej modyfikacji należałoby przygotowywać obraz płyty i go nagrywać na nośnik CD-ROM), był on rozwijany w oparciu o wersję zainstalowaną na dysku twardym. Dopiero po przygotowaniu danych w systemie plików cramfs i nagraniu całości na płytę CD-ROM okazało się, iż system ten nie współpracuje z sieciowym systemem plików NFS. Obraz płyty CD-ROM ma objętość około 250MB, Teoretycznie powinien się zmieścić na płycie CD-ROM o średnicy 8cm, jednak autor pracy nie znalazł tego typu płyt w sprzedarzy, mimo iż kiedyś były często spotykane. Obraz mieści się na standardwoej płycie o średnicy 12cm i pojemności 650MB lub na płycie o średnicy 8cm i pojemności 210MB po usunięciu części oprogramowania. System operacyjny do uruchomienia potrzebuje 96MB pamięci RAM, jeżeli jego praca jest wspomagana przez obecność płyty cd-ROM w napędzie. Jeżeli system operacyjny ma być 98 wczytany całkowicie do pamięci RAM przy uruchomieniu, potrzebna pojemność pamięci wynosi 320MB. Potrzebna do pracy ilość pamięci RAM jest zależna od rozmiaru problemu, który ma być w systemie przetwarzany. Dla przykładu, renderowanie skomplikowanej grafiki przez program POVRAY wymaga dużej ilości pamięci. Jeżeli w systemie komputerowym znajduje się dysk twardy z partychą nadającą się na tzw. partycję wymiany (typ linux swap), jest ona wcielana do pamięci wirtualnej systemu operacyjnego, przez co zmniejszone zostają wymagania rozmiaru pamięci RAM. W następnym rozdziale przetestowano działanie systemu operacyjnego na pojedynczych różnych maszynach, jak również na klastrach zbudowanych z różnej ilości identycznych węzłów. 99 5. Testy wykonanego systemu Po wykonaniu systemu operacyjnego będącego przedmiotem niniejszego opracowania, poddano go serii testów. Sprawdzono go pod kątem wydajności, zarówno w postaci jednego komputera, jak i klastra złożonego z węzłów uruchomionych po sieci z pojedynczego nośnika CD-ROM. Podjęto próbę porównania klastra zbudowanego w oparciu o omawiany system do klastrów objętych rankingiem Top500 [TOP500], w szczególności do klastra będącego własnością Trójmiejskiej Akademickiej Sieci Komputerowej [TASK]. Wyniki poszczególnych testów omówiono w dalszej części rozdziału. 5.1. Test przy pomocy POVRAY w oparciu o PVM Użyto oprogramowania POVRAY, czyli Persistance of Vision Raytracer [POVRAY], które służy do renderowania grafiki w oparciu o śledzenie drogi promieni świetlnych. Wybrano tę metodę testowania z kilku względów. Po pierwsze, renderowanie grafiki przy pomocy programu POVRAY jest obciążające dla procesora. Obciążenie przy tym jest różne dla różnej złożoności obliczeniowej problemu będącego źródłem renderowania. Skutkiem tego, po podziale wyjściowego obrazu na równe części, pewne będzie łatwiej przetworzyć, podczas gdy inne trudniej. Po drugie, istnieją łaty na program POVRAY rozszerzające jego funkcjonalność o wsparcie dla systemu PVM [PVMWWW]. System PVM jest środowiskiem rozproszonego przetwarzania, dzięki któremu można poprzez odpowiednie zaprojektowanie oprogramowania użyć wielu komputerów jako jednej maszyny równoległej. System PVM polega na działaniu na każdym węźle klastra daemona pvmd, który odpowiada za komunikację między węzłami. W klastrze zbudowanym w oparciu o klastrowy cdlinux.pl istnieje z punktu widzenia PVM tylko jeden węzeł – jest to ten węzeł, na którym zostaje uruchomiony proces. Jeżeli na tym węźle uruchomione zostanie zadanie PVMPOVRAY przeznaczone na N procesorów, powstanie N procesów potomnych. Zadaniem systemu openMosix, w oparciu o który zbudowany jest system operacyjny klastrowy cdlinux.pl, jest przeniesienie tych N procesów na dostępne węzły klastra w ten sposób, by zrównoważyć obciążenie na całym klastrze. 100 5.1.1. Test na trzech węzłach o różnej wydajności Pierwszy test miał na celu zbadanie zachowania się mechanizmu rozkładania obciążenia w przypadku, gdy dostępne węzły klastra różnią się pod względem wydajności. Użyto w tym celu trzech komputerów połączonych w sieć Ethernet przez przełącznik 100mbps. Parametry komputerów przedstawiają się następująco: • komputer A, Intel Celeron M 330 1400MHz, 256MB RAM • komputer B, Intel Celeron 1700MHz, 256MB RAM • komputer C, Pentium III 500MHz, 128MB RAM Kontrolerem klastra został komputer A. Zadanie polegało na wyrenderowaniu grafiki w rozdzielczości 320 na 240 pikseli w oparciu o plik źródłowy programu POVRAY. Przy liczbie procesów przetwarzania większej, niż jeden, dzielono zadanie na pewną ilość fragmentów. Dołożono starań, aby wszystkie fragmenty były tego samego rozmiaru – aby szerokość i wysokość obrazu dzieliła się bez reszty przez odpowiednio szerokość i wysokość pojedynczego fragmentu (wielkości wyrażone w ilości pikseli). Wstępnie uruchomiono przetwarzanie zadania tylko na jednym z węzłów – komputerze A, przy czym wykonano test dla jednego oraz trzech procesów przetwarzania. Wyniki zbiera tabela nr 3. Tabela 3. Wyniki przetwarzania zadania na jednym procesorze ilość procesorów ilość procesów ilość fragmentów czas [s] 1 1 1 152 1 3 3 159 Jak widać, narzut spowodowany przez komunikację nawet w obrębie jednego węzła jest zauważalny. W następnej kolejności na klastrze złożonym z 3 węzłów uruchomiono przetwarzanie zadania przy użyciu 3, 6 oraz 8 procesów. Przy każdej fazie testu wykonano pomiary dla podziału zadania na różne liczby fragmentów – wielokrotności procesów przetwarzających. 101 W pierwszej fazie użytko 3 procesów przetwarzających, czyli dokładnie tyle, ile było węzłów klastra. Jednak jako że komputer C znacznie negatywnie odbiegał wydajnością od pozostałych dwóch, żaden z trzech procesów przetwarzania nie został automatycznie zmigrowany na niego. Czasy potrzebne do ukończenia przetwarzania zadania zostały przedstawione w tabeli nr 4. Tabela 4. Wyniki przetwarzania zadania na trzech procesorach przy trzech procesach ilość procesorów ilość procesów ilość fragmentów czas [s] 3 3 3 188 3 3 15 116 3 3 300 100 3 3 768 103 Najlepszy wynik uzyskano przy ilości fragmentów równej 300, czyli 100 razy ilość procesów. Wydawałoby się, że im więcej fragmentów, tym lepiej, jednak już przy ilości fragmentów równej 768 zauważyć można spadek szybkości. Intrygujący jest wynik dla 3 fragmentów. Jest to duży czas (188s) w porównaniu do takiej samej ilości procesów uruchomionych na jednym węźle (159s). Następna faza polegała na uruchomieniu sześciu procesów przetwarzania. W tym przypadku zawsze jeden z procesów był migrowany na słaby komputer C, natomiast komputery A oraz B były obarczone liczbą odpowiednio dwóch oraz trzech procesów. Wyniki pomiarów przedstawia tabela nr 5. Tabela 5. Wyniki przetwarzania zadania na trzech procesorach przy sześciu procesach ilość procesorów ilość procesów ilość fragmentów czas [s] 3 6 6 189 3 6 30 107 3 6 240 93 3 6 600 96 Tym razem najlepszy wynik uzyskano dla 240 fragmentów, czyli nie ilości 100 razy większej, niż liczba procesów, lecz podobnej do wygrywającej ilości z poprzedniej fazy. Uzyskany czas jest trochę niższy, co można tłumaczyć włączeniem się do przetwarzania 102 słabego komputera C. W tym przypadku również czas przetwarzania dla ilości fragmentów równej ilości fragmentów był długi w porównaniu do pojedynczego węzła. Ostatnia faza polegała na uruchomieniu ośmiu procesów przetwarzania. Tym razem również tylko jeden z procesów został przeniesiony na komputer C, natomiast komputery A oraz B zostały obciążone odpowiednio trzema oraz czterema procesami. Wyniki pomiarów przedstawia tabela nr 6. Tabela 6. Wyniki przetwarzania zadania na trzech procesorach przy ośmiu procesach ilość procesorów ilość procesów ilość fragmentów czas [s] 3 8 8 198 3 8 40 114 3 8 320 101 3 8 768 100 3 8 800 101 3 8 1536 104 3 8 3072 109 Również i w tym przypadku osiągnięto krótsze czasy przetwarzania dla większych ilości fragmentów, jednak tylko do pewnego pułapu (do ilości około 800 fragmentów), powyżej którego czas przetwarzania zaczął rosnąć, a wynik – tym samym – pogarszać. Zaobserwowano jeszcze dłuższy czas (198s) przetwarzania zadania przy podziale zadania na tyle fragmentów, ile procesów, niż w poprzednich fazach. Najlepsze wyniki poszczególnych faz testu są bardzo zbliżone do siebie – 100s, 93s i 100s odpowiednio dla 3, 6 i 8 procesów przetwarzania. W przypadku trzech procesów występowało silnie nierówne obciążenie – jeden z procesorów był obciążony dwoma procesami, drugi tylko jednym, podczas gdy trzeci nie był w ogóle obciążony. Natomiast w przypadku ośmiu procesów procesory A i B były obciążone odpowiednio trzema i czterema procesami. Zwiększenie liczby procesów na pojedynczym procesorze prowadzi również do pogorszenia wyników, co dobrze widać po wynikach fazy wstępnej testu na jednym procesorze. Zaobserwowano silną tendencję do większej wydajności wraz z rosnącą liczbą fragmentów, na jakie podzielone jest zadanie przetwarzania. Przy ilości fragmentów równej 103 ilości procesów zaobserwowano wydajność dużo gorszą, niż dla przetwarzania zadania na pojedynczym komputerze. Można to wytłumaczyć tym, iż złożoność obliczeniowa przetwarzania obrazu nie jest jednakowa w każdym punkcie. Istnieją obszary bardzo łatwe do przetworzenia w stosunku do innych, przy których procesor zmuszony jest do cięższej pracy. W przypadku podzielenia zadania od razu na tyle części, ile jest procesów, większe jest prawdopodobieństwo, że pewne procesy skończą pracę dużo szybciej, niż pozostałe, które natrafią na cięższe obliczeniowo fragmenty. Najlepsze efekty uzyskano przy liczbie fragmentów będącej 50- do 100-krotną wielokrotnością ilości procesów przetwarzania. Przy wyższych ilościach fragmentów, wydajność powoli spadała. Spadek ten jest prawdopodobnie spowodowany zbyt dużym narzutem obliczeniowym przeznaczonym na podział i przesyłanie fragmentów do węzłów w stosunku do ilości danych do przetworzenia w pojedynczym fragmencie. Również często występuje sytuacja, że aby przetworzyć obszary na krawędziach fragmentu, należy skorzystać z danych z sąsiednich fragmentów. Algorytm podziału zadania na fragmenty odpowiada za to, żeby wydajnie podzielić zadanie, na przykład przesyłać do węzłów fragmenty lekko zachodzące na siebie, aby wyeliminować późniejszą komunikację związaną z przetwarzaniem krawędzi. Jakkolwiek będzie on funkcjonował, obszary krawędziowe będą pewnym narzutem komunikacyjnym, więc jeżeli stosunek pola krawędzi fragmentu (rozumianej tu jako pas o szerokości większej, niż 0) do jego pola powierzchni będzie zbyt duży, narzut ten będzie większy. Aby zmierzyć jakość zrównoleglenia przetwarzania, należy obliczyć parametr speed-up (S), czyli przyspieszenie obliczeń. Parametr ten jest definiowany jako stosunek czasu wykonywania aplikacji sekwencyjnie do wykonywania aplikacji równolegle. Jeżeli przyjąć, że komputer C nie istniał w klastrze z racji swojej niewielkiej mocy obliczeniowej w stosunku do A i B, wzrost wydajności całego klastra w stosunku do pojedynczego węzła wynosił: S= czas sekwencyjny czas wykonania na węźle = ≈1.5 czas równoległy czas wykonania na klastrze Diagram 37. Wzór na obliczenie przyspieszenie przetwarzania równoległego 104 Przyspieszenie równe 1.5 oznacza, że zadanie na klastrze będzie wykonane 1.5 raza szybciej, niż byłoby wykonane na pojedynczym węźle. Jeżeli przyjmie się, że klaster złożony jest z dwóch węzłów, wyznaczone przyspieszenie jest dobrym wynikiem. Klaster, jednak, złożony był z trzech węzłów, w tym z jednego znacznie odbiegającego negatywnie od dwóch pozostałych, i przy takich założeniach wyznaczone przyspieszenie nie jest dobrym wynikiem. 5.1.2. Test na węzłach o takiej samej wydajności Badanie to przeprowadzono na klastrze zbudowanym z węzłów o takiej samej wydajności. Były to komputery o następujących cechach: • procesor Intel Pentium 4, prędkość zegara 1700MHz • pamięć operacyjna RAM o pojemności 256MB • pamięć wirtualna w postaci partycji wymiany o pojemności 1GB Połączone one były w sieć komputerową Ethernet, w której występowały zarówno połączenia 10mbps jak i 100mbps. Karty sieciowe komputerów nie pozwalały na uruchamianie systemu przez sieć zgodnie z mechanizmem PXE, zatem użyto emulatora PXE ładowanego z dyskietki. Wszystkie komputery posiadały napędy CD-ROM oraz FDD. 5.1.2.1. Pomiar prędkości uruchamiania Test ten miał na celu sprawdzenie, czy przy uruchomieniu większej ilości węzłów jednocześnie zauważalne będzie spowolnienie. Należy pamiętać, iż węzły uruchamiają się w oparciu o pojedynczy węzeł – kontroler klastra, zatem możliwe by było, że przy większej ilości jednoczesnych uruchomień, wydajność kontrolera będzie wąskim gardłem. Zmierzono czas uruchamiania się pojedynczego węzła. Następnie zmierzono czas uruchamiania się 2, 3 oraz 4 węzłów. Wyniki zamieszczono w tabeli nr 7. Tabela 7. Porównanie czasów uruchamiania się węzłów klastra przy różnej jednoczesnej ilości ilość węzłów czas uruchamiania się węzłów [s] 1 35s 2 35s, 35s 3 35s, 35s, 48s 4 36s, 36s, 36s, 36s 105 Przy tak niewielkiej liczbie węzłów zależność czasu uruchamiania od ilości węzłów można pominąć. W przypadku trzech węzłów zaobserwowano dłuższe uruchamianie się jednego z węzłów. Mogło to być spowodowane utraconym pakietem inicjującym połączenie BOOTP, TFTP, czy NFS węzła z kontrolerem klastra. Przy dobrej jakości sieci utracone pakiety nie powinny występować przy tak niewielkim obciążeniu. W badanym środowisku występowało kilka węzłów z podobnymi problemami sieciowymi. 106 5.1.2.2. Renderowanie mało skomplikowanej grafiki Test skalowalności klastra przeprowadzono podobnie, jak w przypadku klastra opartego o węzły o różnej wydajności. Zadaniem było wyrenderowanie grafiki programem POVRAY w oparciu o PVM. Wyniki pomiarów przedstawia tabela nr 8. Table 8. Wyniki przetwarzania mało skomplikowanego zadania na klastrze złożonym z jednakowych węzłów ilość procesorów ilość fragmentów 1 2 3 4 5 6 8 107 czas [s] 1 227 2 131 10 124 20 117 200 121 3 150 15 72 30 75 300 75 4 128 20 62 40 68 400 68 5 79 25 62 50 58 400 59 800 61 6 96 30 57 60 54 600 54 8 73 40 54 80 51 800 53 1600 52 Dla każdej sprawdzonej ilości procesorów przeprowadzono test dla kilku ilości fragmentów, na które podzielone jest zadanie. Najlepsze czasy osiągnięto dla różnych ilości fragmentów przy różnej ilości procesorów. Nie znaleziono innej prawidłowości oprócz potwierdzenia tezy wysuniętej przy poprzednim teście – najgorszy wynik osiąga się dla ilości fragmentów równej ilości procesorów, a przy zwiększaniu ilości fragmentów osiąga się coraz lepsze wyniki, jednak do pewnego momentu tylko, od którego wynik się stopniowo pogarsza. W przypadku omawianego testu, speed-up jest to stosunek czasu przetwarzania zadania na jednym węźle do czasu przetwarzania zadania na wielu węzłach. Aby zbadać skalowalność badanego problemu na klastrze obliczono wartości speed-up w zależności od ilości węzłów dla dwóch przypadków – dla najgorszego wyniku (dla liczby fragmentów zadania równej liczbie procesorów) oraz dla najlepszego wyniku przetwarzania. Wyniki przedstawia tabela nr 9 i wykres na ilustracji nr 11: Tabela 9. Najlepsze wyniki przetwarzania mało skomplikowanego zadania ilość procesorów czas wykonania [s] ilość fragmentów = ilość procesorów speed-up najlepszy wynik ilość fragmentów = ilość procesorów najlepszy wynik 2 131 117 1,73 1,94 3 150 72 1,51 3,15 4 128 62 1,77 3,66 5 79 58 2,87 3,91 6 96 54 2,36 4,2 8 73 51 3,11 4,45 108 Ilustracja 10. Wykres przyspieszenia klastra w funkcji ilości węzłów dla mało skomplikowanego problemu 4,45 4,5 4,2 4,25 3,91 4 3,66 3,75 speed-up 3,5 3,15 3,25 3,11 3 2,87 najgorszy wynik najlepszy wynik 2,75 2,5 2,36 2,25 1,94 2 1,77 1,73 1,75 1,51 1,5 2 3 4 5 6 7 8 ilość węzłów Prawo Amdahla głosi, iż jeżeli część procesu zajmująca aktualnie x*100% czasu zostanie przyspieszona N-krotnie, to cały proces zostanie przyspieszony jedynie 1 1 − x x N razy. Jeżeli przyjmie się, iż w przeprowadzonym teście również udaje się przyspieszyć tylko pewną część procesu przetwarzania zadania, to jej rozmiar w stosunku do całości można wyliczyć z następującego wzoru: x= N S −1 S N −1 gdzie: S – speed-up (przyspieszenie obliczeń) Przeprowadzone obliczenia przyspieszanej części zadania dla najlepszych wyników w zależności od liczby fragmentów przedstawiono w tabeli nr 10. 109 Tabela 10. Rozmiar przyspieszonej części zadania w zależności od ilości procesorów ilość procesorów speed-up przyspieszona część 2 1,94 0,97 3 3,15 1,02 4 3,66 0,97 5 3,91 0,93 6 4,2 0,91 8 4,45 0,89 Zauważa się tendencję zniżkową rozmiaru przyspieszonej przy zrównoleglaniu części zadania. Wynika to z tego powodu, iż na jakość zrównoleglenia procesu przetwarzania zadania ma wpływ nie tylko część zdania, która nie może być zrównoleglona, ale też i opóźnienia wynikające z komunikacji między węzłami. Pewną anomalią jest wynik dla trzech procesorów, co może być spowodowane losowym błędem podczas pomiarów. Posiłkując się wiedzą, iż przyspieszenie procesu przy zrównoleglaniu przy obecności opóźnień komunikacyjnych można w przybliżeniu wyrazić wzorami: S= 1 lub AB / N S= 1 AB/log N dobrano współczynniki i okazało się, że wykres przyspieszenia badanego zadania jest podobny do wykresu funkcji: S N= 1 0,10 0,10 /log N Wypracowanie powyższego wzoru potwierdza tezę, iż w teście występuje zrównoleglenie, na które duży negatywny wpływ mają opóźnienia komunikacyjne. Ponadto, speed-up jest logarytmicznie proporcjonalny do ilości węzłów, co oznacza, iż powoli rośnie wraz z rosnącą ilością węzłów. 5.1.2.3. Renderowanie bardziej skomplikowanej grafiki Kolejny test przeprowadzono tymi samymi metodami, co poprzedni, jednak materiałem do obróbki było źródło programu POVRAY, które wymagało dużo więcej mocy obliczeniowej procesora do przetworzenia, a co za tym idzie – zajmowało więcej czasu. Z 110 jednej strony jest to zaleta, gdyż przy większych wartościach zmniejsza się rozmiar względnego błędu pomiarów. Z drugiej strony, same badania długo trwają i z tego powodu skupiono się na jednym sposobie podziału zadania na fragmenty. W każdym z przypadków zadanie (obraz) zostało podzielone na 100 fragmentów o rozmiarze 32 na 24 piksele. Wyniki przedstawia tabela nr 11 oraz wykres na ilustracji nr 11. Tabela 11. Wyniki przetwarzania bardziej skomplikowanego zadania na klastrze złożonym z jednakowych węzłów ilość procesorów ilość fragmentów czas [s] speed-up 1 100 2100 1,00 2 100 1105 1,90 3 100 782 2,69 4 100 627 3,35 5 100 546 3,85 6 100 516 4,07 7 100 484 4,34 8 100 496 4,23 4,34 4,4 4,23 4,2 4,07 4 3,85 3,8 3,6 3,35 speed-up 3,4 3,2 3 2,8 2,69 2,6 2,4 2,2 2 1,9 1,8 2 3 4 5 6 7 ilość węzłów Ilustracja 11. Wykres przyspieszenia klastra w funkcji ilości węzłów dla skomplikowanego problemu 111 8 Trend przyspieszenia jest podobny do testu w poprzednim rozdziale. Ponownie podjęto próbę dopasowania współczynników do wzoru na przyspieszenie przy dużych opóźnieniach komunikacyjnych, co zaowocowało w konstrukcji następującego wzoru na przyspieszenie w zależności od ilości procesorów: S N= 1 0,11 0,11/log N Zaobserwowano ciekawe zjawisko. Jeżeli wymiary fragmentów podziału zadania były takie, że zadanie nie mogło być podzielone na całkowitą liczbę fragmentów (np. wysokość obrazu – zadania wynosi 320, a fragment ma wysokość 50), wtedy całkowity czas przetwarzania zadania okazywał się być większy, niż gdy zadanie było podzielone na fragmenty tego samego rozmiaru. Być może związane jest to z tym, że takie „niepełne” fragmenty wymagają do przetworzenia większej ilości komunikacji z sąsiednimi fragmentami w stosunku do własnej objętości (pola powierzchni). 5.2. Testy w oparciu o MPI MPI jest podobnym do PVM systemem rozproszonego przetwarzania opartym o przekazywanie wiadomości. Dla testów zainstalowano na klastrowym cdlinux.pl bibliotekę MPICH [MPICHWWW], która jest jedną z dostępnych darmowych implementacji MPI. 5.2.1. Test przy pomocy POVRAY w oparciu o MPI Istnieje łata na program POVRAY, która rozbudowuje funkcjonalność programu o wsparcie dla przetwarzania równoległego w oparciu o MPI. Korzystając z załatanego dzięki niej programu POVRAY, zaplanowano testy podobne do tych przeprowadzonych z programem PVM-POVRAY. Podobnie jak w przypadku PVM, MPI-POVRAY uruchomił N procesów na węźle kontrolera klastra dla zadanej ilości N węzłów będących w klastrze. Okazało się, jednak, iż openMosix nie pozwolił na migrację owych procesów na nieobciążone węzły klastra. Wynikło to prawdopodobnie z innej metody komunikacji stosowanej w MPICH, która sprawiła, iż nieopłacalną dla openMosixa wydała się migracja procesów. Wszystkie procesy wykonywały się na kontrolerze klastra, skutkiem czego przetwarzanie pliku będącego źródłem dla programu POVRAY odbywało się dużo wolniej, niż bez próby zrównoleglenia. 112 5.2.2. Porównanie klastrowego cdlinux.pl do klastrów Top500 Lista Top500 jest dostępna w Internecie pod adresem [TOP500] i zestawia 500 najbardziej wydajnych obliczeniowo superkomputerów. Pierwsza wersja rankingu powstała w roku 1993 i od tego czasu lista ta jest uaktualniana co pół roku. Do pomiaru wydajności komputerów używany jest test o nazwie Linpack, a dokładnie jego zrównoleglona wersja o nazwie hpl. Program hpl pracuje w oparciu o MPI, więc wydawało się, iż możliwe będzie wyznaczenie wydajności klastrowego cdlinux.pl przy użyciu tej metody. Jednak z powodu opisanego w poprzednim rozdziale niemożliwe stało się użycie tego testu. Przy próbie uruchomienia programu, kontroler klastra został obciążony w 100%, co spowodowało, że nawet zerwana została komunikacja między kontrolerem a węzłami. Potomnych procesów, które powinny pracować na osobnych węzłach klastra, nie udało się zmigrować na te węzły. Wydajność klastrowego cdlinux.pl pozostała nieoceniona liczbowo. 113 6. Podsumowanie Sporządzony system operacyjny jest w stanie kontrolować pojedynczą stację roboczą co najmniej tak samo, jak inne dystrybucje Linuxa. Oprócz bogatej biblioteki narzędzi typowych dla systemu UNIX posiada system X-Window, który oferuje graficzny interfejs użytkownika, co jest znacznym ułatwieniem pracy. Spełnia zadania przeciętnej dystrybucji Linuxa, a dodatkowo jest uruchamiany z nośnika CD-ROM bez potrzeby instalacji na twardym dysku. Ponad powyższymi cechami, klastrowy cdlinux.pl jest w stanie w prosty sposób wesprzeć budowę klastra obliczeniowego. Wystarczy uruchomić system z nośnika CD-ROM na jednym komputerze, a pozostałe komputery w sieci lokalnej uruchomią się automatycznie. Dzięki tak zbudowanemu klastrowi możliwe staje się zrównoleglenie zadań poprzez dystrybuowanie procesów składających się na zadania pomiędzy węzły klastra. Ważnym jest fakt, iż programy nie muszą być projektowane specjalnie pod architekturę klastra. Jeżeli chodzi o konkretne architektury równoległe, programy projektowane dla architektury PVM pracują poprawnie na klastrowym cdlinux.pl. Przetestowano tą cechę na przykładzie programu POVRAY z opcją pracy przy użyciu PVM z pozytywnymi wynikami. Przykładowe zadanie zostało zrównoleglone, przy czym parametr speed-up był blisko liniowego przy liczbie węzłów do około 5. Przy wyższych ilościach węzłów jakość zrównoleglenia spadała, co można tłumaczyć zwiększoną ilością wymaganej komunikacji między węzłami. Taki model zachowania zależy od przetwarzanego zadania – istnieją zdania, dla których speed-up będzie rósł szybciej oraz takie, dla których wolniej. Nie udało się dokonać testów w oparciu o mechanizm MPI, co pociągnęło za sobą w konsekwencji niemożność porównania klastrowego cdlinux.pl do klastra należącego do TASK (który wspiera MPI) oraz do klastrów z listy Top500. Prawdopodobnie rozwiązanie leży w modyfikacji działania biblioteki MPICH lub w użyciu innej biblioteki. Wykonany system operacyjny jest działającą implementacją projektu zawartego w niniejszym opracowaniu. Jest w pełni funkcjonalny jako samodzielny system operacyjny dla stacji roboczej, a ponadto umożliwia łatwe zbudowanie klastra komputerowego. Poprzez możliwość instalacji na twardym dysku i późniejsze zbudowanie płyty CD-ROM, każdy 114 użytkownik może system zmodyfikować i tym samym dostosować do własnych potrzeb. Dzięki temu wykonany system może służyć jako „szkielet”, na podstawie którego możliwe i łatwe jest zbudowanie bardziej rozbudowanego projektu. Przykładem może byc próba zbudowania sieci klastrów obejmujących jedną pracownię komputerową każdy, które razem spięte zostaną jednym kontrolerem i podłączone do większego klastra obliczeniowego, aby pobierać od niego zadania do wykonania. Ostatnim testem systemu operacyjnego jest umieszczenie go w Internecie na stronie [CDLINUXPL] w postaci obrazu płyty CD-ROM w formacie El-Torito, skąd można go swobodnie pobrać. 115 7. Bibliografia PKTLNX: Paweł Więcek, Pocket Linux, http://www.pocket-lnx.org CDLINUXPL: Michał Wróbel, Oficjalna strona dystrybucji cdlinux.pl, http://www.cdlinux.pl/ WRÓB: Michał Wróbel, Modyfikacja systemu Linux dla stacji bezdyskowych, 2001 OMHOWTO: Kris Buytaert, The openMosix HOWTO, 2003 NUMA: Matthew Dobson, Linux Support for NUMA Hardware, http://lse.sourceforge.net/numa/ CHANDRA: Rohit Chandra, Kourosh Gharachorloo, Vijayaraghavan Soundararajan, Anoop Gupta, Performance evaluation of hybrid hardware and software distributed shared memory protocols, 1994 DSMWWW: JAVID HUSEYNOV, Distributed Shared Memory Home Pages, http://www.ics.uci.edu/~javid/dsm.html PVMWWW: Al Geist, PVM Project, PVM, Parallel Virtual Machine, http://www.csm.ornl.gov/pvm/ MPICHWWW: MPICH Project, MPICH-A Portable Implementation of MPI, http://wwwunix.mcs.anl.gov/mpi/mpich/ LAMWWW: LAM/MPI Project, LAM/MPI Parallel Computing, http://www.lam-mpi.org/ PFISTER: Gregory Pfister, In Search of Clusters, 1997 NFSHOWTO: Tavis Barr, Nicolai Langfeldt, Seth Vidal, Tom McNeal, Linux NFS-HOWTO, 2004 OMVWWW: Matthias Rechenburg, openMosixview - a cluster management GUI, http://www.openmosixview.com/ MAN1: The Linux Documentation Project, System General Commands Manual, ELTORITO: Curtis E. Stevens, Stan Merkin, El Torito, Bootable CD-ROM Format Specification, 1995 SYSLINUXWWW: H. Peter Anvin, SYSLINUX, http://syslinux.zytor.com INITRD: Werner Almesberger, Hans Lermen, Using the initial RAM disk (initrd), 1996, 2000 PXESPEC: Intel Corporation, Preboot Execution Environment (PXE) Specification, 1999 NETBOOT: Gero Kuhlmann, NetBoot, The free toolkit for building Thin Clients, http://netboot.sourceforge.net/ 116 RFC2131: R. Droms, Dynamic Host Configuration Protocol, 1997 RFC1350: K. Sollins, The TFTP Protocol (Revision 2), 1992 NFSROOT: Gero Kuhlmann, Martin Mares, Mounting the root filesystem via NFS (nfsroot), 1996, 1997 NFSD: Neil Brown, The Linux Kernel NFSD Implementation, 1999 TUOM: Tab, Tab's Unofficial openMosix, http://openmosix.snarc.org LINUXFS: Moshe Bar, LINUX, systemy plików, 2002 LVFSL: Neil Brown, The Linux Virtual File-system Layer, 1999 OMWWW: Bruce Knox, The openMosix Project, http://openmosix.sourceforge.net TOP500: TOP500.org, Top 500 supercomputer sites, http://www.top500.org/ TASK: TASK, Trójmiejska Akademicks Sieć Komputerowa, http://www.task.gda.pl/ POVRAY: Persistence of Vision Raytracer Pty. Ltd., The Persistence of Vision Raytracer, http://www.povray.org/ 117 8. Załączniki Spis ilustracji Ilustracja 1. Główne okno programu OpenMosixview 28 Ilustracja 2. Okno umożliwiające zdalne zarządzanie węzłem klastra 28 Ilustracja 3. Główne okno programu OpenMosixprocs 30 Ilustracja 4. Okno programu OpenMosixprocs umożliwiające wykonanie operacji na danym procesie 31 Ilustracja 5. Główne okno programu OpenMosixAnalyzer 32 Ilustracja 6. Główne okno programu openMosixHistory 33 Ilustracja 7. Okno programu openMosixMigmon. Wszystkie procesy są na węźle domowym 34 Ilustracja 8. Okno programu openMosixMigmon. Procesy podzielone zostały na kilka grup (oznaczonych różnymi kolorami). Część z procesów została zmigrowana na drugi węzeł klastra. 35 Ilustracja 9. Ekran powitalny podczas uruchamiania klastrowego cdlinux.pl 41 Ilustracja 10. Wykres przyspieszenia klastra w funkcji ilości węzłów dla mało skomplikowanego problemu 109 Ilustracja 11. Wykres przyspieszenia klastra w funkcji ilości węzłów dla skomplikowanego problemu 111 118 Spis tabel Tabela 1. Zestawienie opcji kompilacji ważnych dla jądra rozbudowanego o openMosix 73 Tabela 2. Zmodyfikowane opcje kompilacji jądra 75 Tabela 3. Wyniki przetwarzania zadania na jednym procesorze 101 Tabela 4. Wyniki przetwarzania zadania na trzech procesorach przy trzech procesach 102 Tabela 5. Wyniki przetwarzania zadania na trzech procesorach przy sześciu procesach 102 Tabela 6. Wyniki przetwarzania zadania na trzech procesorach przy ośmiu procesach 103 Tabela 7. Porównanie czasów uruchamiania się węzłów klastra przy różnej jednoczesnej ilości 105 Table 8. Wyniki przetwarzania mało skomplikowanego zadania na klastrze złożonym z jednakowych węzłów 107 Tabela 9. Najlepsze wyniki przetwarzania mało skomplikowanego zadania 108 Tabela 10. Rozmiar przyspieszonej części zadania w zależności od ilości procesorów 110 Tabela 11. Wyniki przetwarzania bardziej skomplikowanego zadania na klastrze złożonym z jednakowych węzłów 111 119 Spis diagramów Diagram 1. Połączenia między węzłami klastra w obrębie oMFS 19 Diagram 2. Trzy równoważne zawartości pliku konfiguracyjnego /etc/openmosix.map 22 Diagram 3. Użycie słowa kluczowego ALIAS w pliku konfiguracyjnym /etc/openmosix.map 22 Diagram 4. Wynik działania programu showmap 24 Diagram 5. Wynik działania showmap dla numerów ID węzłów następujących po sobie 24 Diagram 6. Struktura płyty CD-ROM zwykłej oraz w formacie El-Torito [ELTORITO] 39 Diagram 7. Sposób montowania katalogów przy pracy z CD-ROM 44 Diagram 8. Sposób montowania katalogów przy pracy bez CD-ROM 45 Diagram 9. Schemat negocjacji PXE: komunikacja klienta z serwerem [PXESPEC] 49 Diagram 10. Uruchamianie się Linuxa poprzez emulację PXE programem NetBoot 57 Diagram 11. Uruchamianie się Linuxa w oparciu o kartę sieciową wspierającą PXE 58 Diagram 12. Wynik programu rpcinfo przed włączeniem usług NFS 61 Diagram 13. Wynik programu rpcinfo po włączeniu usług NFS 62 Diagram 14. Poprawki źródła jądra Linuxa rozbudowujące system plików cramfs o wsparcie dla NFS 72 Diagram 15. Ciag dalszy poprawek źródła jądra Linuxa rozbudowujących system plików cramfs o wsparcie dla NFS 73 Diagram 16. Procedura instalacji skompilowanego jądra Linuxa 75 Diagram 17. Zawartość pliku isolinux.cfg 76 Diagram 18. Zawartość pliku intro.msg 76 Diagram 19. Treść skryptu /linuxrc 79 Diagram 20. Skrypt /etc/init.d/join, który przygotowuje system plików 80 Diagram 21. Zawartość pliku konfiguracyjnego narzędzi openMosix - / etc/openmosix/openmosix.cfg 81 Diagram 22. Przykładowy nagłówek wygenerowanego przez yahade pliku dhcpd.conf 83 Diagram 23. Przykładowa sekcja subnet wygenerowanego przez yahade pliku dhcpd.conf 83 120 Diagram 24. Przykładowa zawartość pliku konfiguracyjnego /etc/tftpboot/pxelinux.cfg/default 83 Diagram 25. Zawartość pliku /slave2/etc/fstab będącego konfiguracją systemów plików węzła klastra 84 Diagram 26. Przykładowa zawartość pliku /etc/hosts 85 Diagram 27. Zmiany wprowadzone do programu yahade, część 1 86 Diagram 28. Zmiany wprowadzone do programu yahade, część 2 87 Diagram 29. Zmiany wprowadzone do programu yahade, część 3 88 Diagram 30. Zmiany wprowadzone do programu yahade, część 4 89 Diagram 31. Wyjściowa zawartość katalogu /slave2 91 Diagram 32. Skrypt przygotowujący system plików węzła - /etc/init.d/preparefs 92 Diagram 33. Skrypt przygotowujący nazwę hosta węzła - /etc/init.d/preparehostname 93 Diagram 34. Poprawki skryptu cdlcenter-isomaker.sh, część 1 94 Diagram 35. Poprawki skryptu cdlcenter-isomaker.sh, część 2 95 Diagram 36. Program makerom służący do przygotowania obrazu dyskietki z emulatorem PXE 97 Diagram 37. Wzór na obliczenie przyspieszenie przetwarzania równoległego 121 104