Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Wydział Informatyki PS Akademickie Centrum Informatyki PS.

Podobne prezentacje


Prezentacja na temat: "Wydział Informatyki PS Akademickie Centrum Informatyki PS."— Zapis prezentacji:

1 Wydział Informatyki PS Akademickie Centrum Informatyki PS

2 Wydział Informatyki Sieci komputerowe i Telekomunikacyjne Budowa systemu operacyjnego UNIX Krzysztof Bogusławski tel. 4 333 950 kbogu@man.szczecin.pl

3 Główne MENU z aktywnymi przyciskami do poszczególnych rozdziałów. 2. Podręczna pamięć buforowa 2. Podręczna pamięć buforowa 3. Wewnętrzna reprezentacja plików 3. Wewnętrzna reprezentacja plików 4. Funkcje systemowe systemu plików 4. Funkcje systemowe systemu plików 5. Struktura procesów 5. Struktura procesów 6. Zarządzanie procesami 6. Zarządzanie procesami MENU 1. Wstęp 1. Wstęp

4 Rozdział pierwszy – „Wstęp” 1. Wstęp 1. Wstęp 3. Wewnętrzna reprezentacja plików 3. Wewnętrzna reprezentacja plików 4. Funkcje systemowe systemu plików 4. Funkcje systemowe systemu plików 5. Struktura procesów 5. Struktura procesów 6. Zarządzanie procesami 6. Zarządzanie procesami MENU 2. Podręczna pamięć buforowa 2. Podręczna pamięć buforowa

5 Architektura systemów unixowych 1. Wstęp 1. Wstęp MENU Sprzęt Jądro nroff sh who a.out date wc grep ed vi ld as comp cpp cc Inne programy użytkowe

6 Przykładowe drzewo systemu plików fsl bin etc usr unix dev / mjbmauryshdatewhopasswdsrcbintty00tty01 cmd date.cwho.c 1. Wstęp 1. Wstęp MENU

7 Przykładowe drzewo systemu plików #include char bufor [2048]; int wersja = 1; main (argc, argv) int argc; char *argv[]; { int dpstary, dpnowy; if (argc != 3) { printf („Program kopiujący potrzebuje 2 argumentów\n”); exit (1); } dpstary = open (argv[1], O_RDONLY); /* otwórz plik źródłowy do czytania */ if (dpstary == -1) { printf („nie można otworzyć pliku %s\n”, argv[1]); exit (1); } dpnowy = creat (argv[2], 0666); /* otwórz plik docelowy z prawem rw dla każdego */ if (dpnowy == -1) { printf („nie można utworzyć pliku %s\n”, argv[2]); exit (0); } copy (dpstary, dpnowy); exit (0); } copy (stary, nowy) int stary, nowy; { int licznik; while ((licznik = read (stary, bufor, sizeof (bufor))) > 0) write (nowy, bufor, licznik); } 1. Wstęp 1. Wstęp MENU

8 Program tworzący nowy proces do skopiowania pliku main (argc, argv) int argc; char *argv[]; { /* zakładamy, że są dostępne 2 argumenty: plik źródłowy i plik docelowy */ if (fork() == 0) execl („copy”, „copy”, argv[1], argv[2], 0); wait ((int*) 0); printf („Zakończono kopiowanie\n”); } 1. Wstęp 1. Wstęp MENU

9 Wiele procesów i tryby wykonywania JJ UU Tryb jądra Tryb użytkownika Procesy ABCD 1. Wstęp 1. Wstęp MENU

10 Typowe poziomy przerwań Błąd maszyny Zegar Dysk Urządzenia sieciowe Terminale Przerwania programowe Błąd maszyny Zegar Dysk Urządzenia sieciowe Terminale Przerwania programowe Wyższy priorytet Niższy priorytet 1. Wstęp 1. Wstęp MENU

11 Rys. Diagram blokowy jądra systemu Programy użytkowników Biblioteki Interfejs funkcji systemowych Podsystem plików Podręczna pamięć buforowa Znakowe Programy obsługi urządzeń Blokowe Sterowanie sprzętem Sprzęt Komunikacja międzyprocesowa Przydział CPU Zarządzanie pamięcią Podsystem sterujący procesami Poziom jądra Poziom sprzętu Poziom użytkownika Poziom jądra trap 1. Wstęp 1. Wstęp MENU

12 Rys. Deskryptory plików, tablica plików i tablica i-węzłów Tablica deskryptorów plików użytkownika Tablica plikówTablica i-węzłów 1. Wstęp 1. Wstęp MENU

13 Rys. Układ systemu plików Blok systemowy Blok identyfikacyjny Lista i-węzłów Bloki danych 1. Wstęp 1. Wstęp MENU

14 Rys. Stos użytkownika i jądra dla programu copy Stos użytkownika Zmienne lokalneNie pokazano Adres zrębu 2 Adres powrotu po wywołaniu write Argumenty write nowy bufor licznik Zmienne lokalne licznik Adres zrębu 1 Adres powrotu po wywołaniu copy Argumenty copy start nowy Zmienne lokalne dpstary dpnowy Adres zrębu 0 Adres powrotu po wywołaniu main Argumenty main argc argv Stos jądra Zmienne lokalne Adres zrębu 1 Adres powrotu po wywołaniu func2 Argumenty funkcji jądra func2 Zmienne lokalne Adres zrębu 0 Adres powrotu po wywołaniu func1 Argumenty funkcji jądra func1 Zrąb 3 Wywołanie write() Zrąb 3 Zrąb 2 Wywołanie copy() func2() Zrąb 1 Wywołanie main() func1() Zrąb 0 Początek Zrąb 0 Interfejs funkcji systemowych Kierunek wzrostu stosu 1. Wstęp 1. Wstęp MENU

15 Rys. Struktury danych związane z procesem U-obszar Tablica procesów Pamięć główna Tablica segmentów procesu Tablica segmentów 1. Wstęp 1. Wstęp MENU

16 Rys. Stany procesu i przejścia między stanami 4 1 2 3 Wykonywany w trybie użytkownika Wykonywany w trybie jądra Wywołanie funkcji systemowej lub przerwanie powrót przerwanie Powrót z przerwania Wybranie procesu do wykonania Gotowy do wykonania budzenie zasypianie Uśpiony dopuszczalne przełączenie kontekstu 1. Wstęp 1. Wstęp MENU

17 Przykład: Tworzenie listy z podwójnymi dowiązaniami struct kolejka { } *wsk, *wsk1; wsk1->pwsk = wsk->pwsk; wsk1->lwsk = wsk; wsk->pwsk = wsk1; /* rozważ możliwość zmiany kontekstu tutaj */ wsk1->pwsk->lwsk = wsk1; 1. Wstęp 1. Wstęp MENU

18 Rys. Lista z dowiązaniami niepoprawna ze względu na przełączenie kontekstu wsk wsk 1 wsk wsk 1wsk Umieszczenie wsk1 na liście z podwójnymi dowiązaniami 1. Wstęp 1. Wstęp MENU

19 Rys. Kilka procesów śpiących w oczekiwaniu na dostęp do bufora Czas Proces A Proces B Bufor zablokowany Śpi Bufor zablokowany Śpi Bufor zablokowany Śpi Proces C Zdjęcie blokady z buforaObudź wszystkie śpiące procesy Gotowy do wykonania Wykonuje się Bufor odblokowany Załóż blokadę Zasypia z jakiegoś powodu Wykonuje się Bufor zablokowany Śpi Wykonuje się Bufor zablokowany Śpi Budzi się Zdejmuje blokadę Budzi wszystkie śpiące procesy Wreszcie przełączenie kontekstu Gotowy do wykonania Wykonuje się 1. Wstęp 1. Wstęp MENU

20 Rozdział drugi – „Podręczna pamięć buforowa” 2. Podręczna pamięć buforowa 2. Podręczna pamięć buforowa 3. Wewnętrzna reprezentacja plików 3. Wewnętrzna reprezentacja plików 4. Funkcje systemowe systemu plików 4. Funkcje systemowe systemu plików 5. Struktura procesów 5. Struktura procesów 6. Zarządzanie procesami 6. Zarządzanie procesami MENU 1. Wstęp 1. Wstęp

21 Rys. Nagłówek bufora 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU Numer urządzenia Numer bloku Stan bufora Wskaźnik do obszaru danych Wskaźnik do następnego Bufora w kolejce mieszającej Wskaźnik do następnego Bufora na liście wolnych Wskaźnik do poprzedniego Bufora na liście wolnych Wskaźnik do poprzedniego Bufora w kolejce mieszającej

22 Rys. Lista wolnych buforów Głowa listy wolnych Bufor 1Bufor 2Bufor n Wskaźnik do przodu Wskaźnik do tyłu 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

23 Rys. Bufory w kolejkach mieszających 284 175 9850 335 64 97 10 99 Nr bloku 1 mod 4 Nr bloku 2 mod 4 Nr bloku 3 mod 4 Nagłówki kolejek mieszających Nr bloku 0 mod 4 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

24 Algorytm przydziału bufora Algorytm getblk /*dostarcz blok*/ wejście:numer systemu plików numer bloku wyjście: bufor z założoną blokadą, który można użyć na blok { while (nie znaleziono bufora) { if( blok w kolejce mieszającej) if (bufor niedostępny)/*scenariusz 5*/ { sleep(zdarzenie: zwalnia się bufor); continue;/*powrót do pętli while*/ } oznacz bufor jako niedostępny;/*scenariusz 1*/ usuń bufor z listy wolnych; return(bufor); } else/*nie ma bloku w kolejce mieszającej*/ { if (nie ma buforów na liście wolnych)/*scenariusz 4*/ { sleep(zdarzenie: zwalnia się dowolny bufor); continue;/*powrót do pętli while*/ } usuń bufor z listy wolnych; if (bufor oznaczony do zapisu opóźnionego) /*scenariusz 3*/ { zapisz asynchronicznie bufor na dysk; continue;/*powrót do pętli while*/ } /*scenariusz 2 - znaleziono wolny bufor*/ usuń bufor ze starej kolejki mieszającej; wstaw bufor do nowej kolejki mieszającej; return(bufor); } 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

25 Rys. Poszukiwanie bloku 4 w pierwszej kolejce mieszającej 284 175 9850 335 64 97 10 99 Nr bloku 1 mod 4 Nr bloku 2 mod 4 Nr bloku 3 mod 4 Nagłówek Listy wolnych Nagłówki kolejek mieszających Nr bloku 0 mod 4 444 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

26 4 Rys. Usunięcie bloku 4 z listy wolnych 28 175 9850 335 64 97 10 99 Nr bloku 1 mod 4 Nr bloku 2 mod 4 Nr bloku 3 mod 4 Nagłówek Listy wolnych Nagłówki kolejek mieszających Nr bloku 0 mod 4 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

27 Algorytm zwalniania bufora algorytm brelse/*zwolnij bufor*/ wejście:bufor z założoną blokadą wyjście:brak { obódż wszystkie procesy czekające na dowolny wolny bufor; obódż wszystkie procesy czekające na dostęp do tego bufora; podnieś poziom pracy procesora w celu zablokowania przerwań; if (zawartość bufora jest aktualna i bufor nie jest przeterminowany) dołącz bufor do końca listy wolnych; else dołącz bufor na początek listy wolnych; obniż poziom pracy procesora w celu odblokowania przerwań; zdejmij blokadę z bufora; } 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

28 Rys. Poszukiwanie bloku 18 – nie ma w pamięci buforowej Nr bloku 1 mod 4 Nr bloku 2 mod 4 Nr bloku 3 mod 4 Nagłówek Listy wolnych Nagłówki kolejek mieszających Nr bloku 0 mod 4 284 175 9850 335 64 97 10 99 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

29 Rys. Usunięcie pierwszego bloku z listy wolnych, przydzielenie bufora na potrzeby bloku 18 Nr bloku 1 mod 4 Nr bloku 2 mod 4 Nr bloku 3 mod 4 Nagłówek Listy wolnych Nagłówki kolejek mieszających Nr bloku 0 mod 4 284 175 9850 18 35 64 97 10 99 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

30 Rys. Poszukiwanie bloku 18, bloki zaznaczone do zapisu opóźnionego na liście wolnych Nr bloku 1 mod 4 Nr bloku 2 mod 4 Nr bloku 3 mod 4 Nagłówek Listy wolnych Nagłówki kolejek mieszających Nr bloku 0 mod 4 284 175 98 3 35 64 97 10 99 Opóźnij 50 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

31 Rys. Zapis bloków 3 i 5, przydzielenie bufora po bloku 4 na potrzeby bloku 18 Nr bloku 1 mod 4 Nr bloku 2 mod 4 Nr bloku 3 mod 4 Nagłówek Listy wolnych Nagłówki kolejek mieszających Nr bloku 0 mod 4 28 18 175 98 3 35 64 97 10 99 Zapis 50 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

32 Rys. Poszukiwanie bloku 18, pusta lista wolnych Nr bloku 1 mod 4 Nr bloku 2 mod 4 Nr bloku 3 mod 4 Nagłówek Listy wolnych Nagłówki kolejek mieszających Nr bloku 0 mod 4 284 175 98 3 35 64 97 10 99 50 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

33 Rys. Wyścig po wolny bufor Czas Proces A Proces B Nie można znaleźć bloku b w kolejce mieszającej Nie ma buforów na Liście wolnych Śpij Nie można znaleźć bloku b w kolejce mieszającej Nie ma buforów na Liście wolnych Śpij Ktoś zwalnia bufor: brelse Bierze bufor z listy wolnych Przydziela na blok b 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

34 Rys. Poszukiwanie bloku 99, blok niedostępny Nr bloku 1 mod 4 Nr bloku 2 mod 4 Nr bloku 3 mod 4 Nagłówek Listy wolnych Nagłówki kolejek mieszających Nr bloku 0 mod 4 284 175 98 3 35 64 97 10 99 Niedostępny 50 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

35 Rys. Wyścig po bufor z założoną blokadą Czas Proces A Proces B Przydziel bufor na blok b Załóż blokadę Zainicjuj we-wy Śpij do zakończenia we-wy Śpij w oczekiwaniu na dowolny dostępny bufor (scenariusz 4) Szukaj bloku b w kolejce mieszającej Bufor niedostępny, Śpij Zakończenie we-wy, obudź się Weź bufor przydzielony wcześniej na blok b Przydziel bufor na blok b Proces C Brelse: obudź innych Bufor nie zawiera bloku b 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

36 Algorytm czytania bloku z dysku algorytm bread /*czytaj blok*/ wejście:numer bloku w systemie plików wyjście:bufor zawierający dane { dostarcz bufor na blok (algorytm getblk); if (bufor zawiera aktualne dane) return (bufor); zainicjuj czytanie z dysku; sleep(zdarzenie: zakończono czytanie z dysku); return (bufor); } 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

37 Algorytm czytania bloku z wyprzedzeniem algorytm breada/*czytaj blok i czytaj z wyprzedzeniem*/ wejście:(1) numer bloku w systemie plików do natychmiastowego czytania (2) numer bloku w systemie plików do czytania asynchronicznego wyjście:bufor zawierający dane do natychmiastowego czytania { if (pierwszego bloku nie ma w pamięci buforowej) { dostarcz bufor na pierwszy blok (algorytm getblk); if (bufor nie zawiera aktualnych danych) zainicjuj czytanie z dysku; } if (drugiego bloku nie ma w pamięci buforowej) { dostarcz bufor na drugi blok (algorytm getblk); if (bufor zawiera aktualne dane) zwolnij bufor (algorytm brelse); else zainicjuj czytanie z dysku; } if (pierwszy blok był w pamięci buforowej) { czytaj pierwszy blok (algorytm bread); return (bufor); } sleep (zdarzenie: pierwszy bufor zawiera aktualne dane); return (bufor); } 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

38 Algorytm zapisu bloku dyskowego algorytm bwrite/*zapisz blok*/ wejście:bufor wyjście:brak { zainicjuj pisanie na dysk; if (we-wy synchroniczne) { sleep (zdarzenie: zakończenie we-wy); zwwolnij bufor (alg. brelse); } else if (bufor zaznaczony do zapisu opóźnionego) zaznacz, że bufor należy umieścić na początku listy wolnych; } 2. Podręczna pamięć buf. 2. Podręczna pamięć buf. MENU

39 Rozdział trzeci – „Wewnętrzna reprezentacja plików” 3. Wewnętrzna reprezentacja plików 3. Wewnętrzna reprezentacja plików 2. Podręczna pamięć buforowa 2. Podręczna pamięć buforowa 4. Funkcje systemowe systemu plików 4. Funkcje systemowe systemu plików 5. Struktura procesów 5. Struktura procesów 6. Zarządzanie procesami 6. Zarządzanie procesami MENU 1. Wstęp 1. Wstęp

40 Rys. Algorytmy systemu plików 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU iget iput bmap namei alloc freeialloc ifree Algorytmy przydziału bufora getblk brelse breada bwrite Niskopoziomowe algorytmy systemu plików

41 Rys. Przykładowy i-węzeł na dysku Właściciel jmd Grupa pracownicy Typ pliku zwykły Prawa dostępu rwxr-xr-x Dostęp 23.10.1984 1:45 PM Modyfikacja 22.10.1984 10:30 AM I-węzeł 23.10.1984 1:30 PM Rozmiar 6030 bajtów Adresy dyskowe Właściciel jmd Grupa pracownicy Typ pliku zwykły Prawa dostępu rwxr-xr-x Dostęp 23.10.1984 1:45 PM Modyfikacja 22.10.1984 10:30 AM I-węzeł 23.10.1984 1:30 PM Rozmiar 6030 bajtów Adresy dyskowe 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

42 Dane przechowywane przez kopię i-węzła w pamięci 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU Stan i-węzła w pamięci wskazujący czy: - i-węzeł ma założoną blokadę, - proces czeka na zdjęcie blokady z i-węzła, - reprezentacja i-węzła w pamięci różni się od kopii dyskowej z powodu zmiany danych w i-węźle - plik jest punktem montowania Logiczny numer urządzenia systemu plików zawierającego plik Numer i-węzła. Ponieważ i-węzły są zapamiętane na dysku w tablicy liniowej, jądro identyfikuje numer i-węzła na dysku z jego położeniem w tablicy. I-węzeł na dysku nie potrzebuje tego pola Wskaźniki do innych i-węzłów w pamięci. Jądro łączy i-węzły w kolejkach mieszających i na liście wolnych w ten sam sposób, w jaki łączy bufory w kolejkach mieszających buforów i na liście wolnych buforów Licznik odwołań, wskazujący liczbę aktywnych wcieleń pliku (po otwarciu)

43 Algorytm przydziału i-węzłów w pamięci algorytm iget wejście: numer i-węzła w systemie plików wyjście: i-węzła z założoną blokadą { while (nie gotowe) { if (i-węzeł w puli i-węzłów) { if (i-węzeł ma założoną blokadę) { sleep(zdarzenie: zdjęcie blokady z i-węzła); continue; /*powrót do pętli while*/ } /* specjalne przetwarzanie w razie punktów zamontowania */ if (i-węzeł na liście wolnych i-wezłów) usuń z listy wolnych; zwiększ o 1 licznik odwołań w i-węźle; return(i-węzł); } /* i-węzła nie ma w puli i-węzłów */ if (nie ma i-węzłówna liście wolnych) return(błąd); usuń nowy i-węzeł z listy wolnych; zmień numer i-węzła i systemu plików; usuń i-węzeł ze starej kolejki mieszającej i umieść w nowej; wczytaj i-węzeł z dysku (algorytm bread); wypełnij inicjalnie i-węzeł (np. licznik odwołań na 1); return (i-węzeł); } 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

44 Zwalnianie i-węzła algorytm iput /* zwolnij i-wezeł w pamięci */ wejście: wskaźnik do i-węzła w pamięci wyjście: brak { jeśli nie ma blokady na i-węźle, to ją załóż; zmniejsz o 1 licznik odwołań do i-węzła; if (licznik odwołań == 0) { if (licznik dowiązań i-węzła == 0) { zwolnij bloki dyskowe zajęte przez plik (algorytm free, p. 4.7); ustaw typ pliku na 0; zwolnij i-węzeł (algorytm ifree, p. 4.6); } if (był dostęp do pliku lub zmienił się i-węzeł lub zmienił się pli k) uaktualnij i-węzeł na dysku; wstaw i-węzeł do listy wolnych; } zdejmij blokadę z i-węzła; } 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

45 Rys. Przydział ciągłych obszarów na pliki i fragmentacja obszaru wolnego Wolne Plik CPlik BPlik A 40506070 Adresy bloków Plik CPlik BPlik A 40506070 Adresy bloków 81 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

46 Rys. Numery bloków bezpośrednich i pośrednich w i-węźle Bezpośredni 0 I-węzeł Bezpośredni 1 Bezpośredni 2 Bezpośredni 3 Bezpośredni 4 Bezpośredni 5 Bezpośredni 6 Bezpośredni 7 Bezpośredni 8 Bezpośredni 9 Potrójny pośredni Podwójny pośredni Pojedynczy pośredni Bloki danych 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

47 Rys. Pojemność pliku w bajtach – 1KB na blok 10 bloków bezpośrednich po 1KB = 10 KB 1 blok pośredni i 256 bloków bezpośrednich =256 KB 1 blok podwójnie pośredni i 256 bloków pośrednich = 64 MB 1 blok potrójnie pośredni i 256 bloków podwójnie pośrednich = 16 GB 10 bloków bezpośrednich po 1KB = 10 KB 1 blok pośredni i 256 bloków bezpośrednich =256 KB 1 blok podwójnie pośredni i 256 bloków pośrednich = 64 MB 1 blok potrójnie pośredni i 256 bloków podwójnie pośrednich = 16 GB 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

48 Algorytm przekształcania numeru bajtu w numer bloku w systemie plików algorytm bmap /* odwzorowanie adresu bajtu w wejście: i-węzeł pliku w numer bloku na dysku*/ numer bajtu wyjście: numer bloku w systemie plików połoźenie bajtu w bloku liczba bajtów w bloku do przesłania numer bloku czytanego z wyprzedzeniem { wylicz numer bloku logicznego w pliku z adresu bajtu; wylicz położenie pierwszego transmitowanego bajtu; /* wyjście 2 */ wylicz liczbę bajtów do skopiowania użytkownikowi; /* wyjście 3 */ sprawdź czy będzie czytanie z wyprzedzeniem, zaznacz i-węzeł; /* wyjście 4 */ określ poziom pośredniości; while (nie na odpowiednim poziomie pośredniości) { wylicz indeks w i-węźle lub bloku pośrednim z numeru bloku logicznego w pliku; pobierz numer bloku dyskowego z i-węzła lub bloku pośredniego; zwolnij bufor z poprzedniego czytania z dysku, jeśli jest (alg. brelse); if (nie ma więcej poziomów pośredniości) return (numer bloku); wczytaj pośredni blok dyskowy (algorytm bread); zmodyfikuj numer bloku logicznego w pliku zgodnie z poziomem pośredniości; } 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

49 Rys. Rozkład bloków przykładowego pliku i jego i-węzeł 4096 228 45423 0 0 11111 0 101 367 0 824 9156 428 3333 9156 Podwójnie pośredni 331 0 75 367 Blok danych 3333 Blok danych 331 Pojedynczo pośredni 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

50 Rys. Zawartość pliku katalogowego /etc Numer bajtu w katalogu Numer i-węzła (2 bajty) Nazwa pliku 0 16 32 48 64 80 96 112 128 144 160 176 192 208 224 240 256 83 2 1798 1276 85 1268 1799 88 2114 1717 1851 92 84 1432 0 95 188... init fsck clri motd mount mknod passwd umount checklist fsdb1b config getty crash mkfs inittab 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

51 Algorytm przekształcający nazwę ścieżkową w i-węzeł algorytm namei /*przek. nazwę ścież. w i-węzeł*/ wejście: nazwa_ścieżkowa; wyjście: i-węzeł z założoną blokadą; { if (nazwa ścieżkowa rozpoczynająca się od korzenia) i-wezeł roboczy = i-węzeł korzenia (alg iget); else i-węzeł roboczy = i-węzeł bież. katalogu (alg iget); while (są jeszcze składowe o nazwie ścieżkowej) { wczytaj kolejną składową nazwy_ść; sprawdź, czy i-węzeł odpowiada katalogowi i czy ma prawa dostępu if (węzeł roboczy jest korzeniem i składową jest... ) continue; /*powrót do pętli while*/ czytaj katalog (i-węzeł roboczy) korzystając z algorytmów bmp, bred, brelse; if (składowa pasuje do pozycji w katalogu (i-węzeł roboczy)) { pobierz numer i-węzła dla pasującej składowej; zwolnij i-węzeł roboczy (iput); i-węzeł roboczy = węzeł pasującej składowej (iget); } else /*składowej nie ma w katalogu*/ return ( bez i-węzła ); } return (i-węzeł roboczy); } 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

52 Blok identyfikacyjny Blok identyfikacyjny zawiera pola z następującą informacją: Rozmiar systemu plików Liczba wolnych bloków w systemie plików Lista wolnych bloków dostępnych w systemie plików Indeks następnego wolnego bloku na liście wolnych bloków Rozmiar listy i-węzłów Liczba wolnych i-węzłów w systemie plików Lista wolnych i-węzłów w systemie plików Indeks następnego wolnego i-węzła na liście wolnych i-węzłów pola blokad dla listy wolnych bloków i list wolnych i-węzłów znacznik wskazujący, czy blok identyfikacyjny był modyfikowany 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

53 Algorytm przydziału nowych i-węzłów algorytm 'ialloc' /*przydziel i-węzeł*/ wejście: system plików wyjście: i-węzeł z założoną blokadą { while (nie zrobiono) { if (jest blokada na bloku identyfikacyjnym) { sleep (zdarzenie: blok identyfikacyjny staje się dostępny ); continue; /*powrót do pętli while*/ } if (lista i-węzłów w bloku identyfikacyjnym jest pusta ) { załóż blokadę na blok identyfikacyjny; pobierz zapamiętany i-węzeł do poszukiwania wolnych i-węzłów; szukaj na dysku wolnych i-węzłów aż zapełni się blok identyfikacyjny, lub nie będzie wolnych i-węzłów;(bred,brelse) zdejmij blokadę z bloku identyfikacyjnego wakeup (zdarzenie: blok identyfikacyjny staje się dostępny); 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

54 Algorytm przydziału nowych i-węzłów c.d. if (na dysku nie znaleziono wolnych i-węzłów ) return (brak węzła); zachowaj zapamiętany i-węzeł do następnego szukania wolnych i-węzłów; } /*są i-węzły na liście i-węzłów w bloku identyfikacyjnym*/ pobierz numer i-węzła z listy wolnych i-węzłów w bloku identyfikacyjnym; pobierz i-węzeł; (iget) if (węzeł mimo wszystko nie jest wolny) { zapisz i-węzeł na dysk; zwolnij i-węzęł; (iput) continue; /*powrót do pętli while*/ } /*i-węzeł jest wolny*/ wypełnij inicjalnie i-węzeł; zapisz i-węzeł na dysk; zmniejsz o 1 licznik wolnych i-węzłów systemu plików; return (i-wezeł); } 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

55 Rys. Przypisanie wolnego i-węzła ze środka listy Lista wolnych i-węzłów W bloku identyfikacyjnym 1819Tablica 1 8348PusteWolne i-węzły Indeks 20 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

56 Rys. Przypisanie wolnego i-węzła – pusta lista w bloku identyfikacyjnym Lista wolnych i-węzłów W bloku identyfikacyjnym 0Tablica 1 470Puste Indeks Lista wolnych i-węzłów W bloku identyfikacyjnym Indeks 484950 Tablica 2 476Wolne i-węzły475471 0 535 (Zapamiętany i-węzeł) 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

57 Algorytm zwalniania i-węzła algorytm ifree /*zwolnij i-węzeł*/ wejście: numer i-węzła w systemie plików; wyjście: brak; { zwiększ o 1 licznik wolnych i-węzłów w systemie plików; if (blok identyfikacyjny ma założoną blokadę) return; if (lista wezłów pełna) { if (numer i-węzła mniejszy niż zapamiętany numer i-wezła) zapamiętany num i-węzła do poszukiwań = numer i-węzła z wejścia; } else zapamiętaj numer i-węzła na liście węzłów; return; } 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

58 Rys. Pierwotna lista wolnych i-węzłów w bloku identyfikacyjnym 485049 535476Wolne i-węzły Zapamiętany i-węzeł 471475 Indeks 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

59 Rys. Zwolnienie i-węzła 499 485049 499476Wolne i-węzły Zapamiętany i-węzeł 471475 Indeks 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

60 Rys. Wyścig procesów podczas przydziału i-węzłów Czas Proces A Proces B Przydziela i-wżeł I z bloku identyfikacyjnego Śpi podczas czytania i-węzła (a) Próbuje przydzielić i-węzeł z bloku identyfikacyjnego Blok identyfikacyjny pusty (b) Szukanie wolnych i-węzłów na dysku, wstawia i-węzeł I do bloku identyfikacyjnego (c) Przydziela i-węzeł I z bloku identyfikacyjnego I w użyciu! Przydziel inny i-węzeł (e) Proces C I-węzeł w pamięci Wykonuje zwykłe czynności Kończy poszukiwanie, przydziela inny i-węzeł (d) 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

61 Rys. Wyścig procesów podczas przydziału i-węzłów (kontynuacja) Czas I Puste Wolne i-węzły JIK JI L (a) (b) (c) (d) (e) 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

62 Lista w bloku identyfikacyjnym Rys. Lista numerów wolnych bloków dyskowych 109106100103 208202205112 109 211 307301304214 211 310 406400403313 310 409 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

63 Algorytm przydziału bloku dyskowego algorytm alloc /*przydział bloku z systemu plików*/ wejście : numer systemu plików wyjście : bufor na potrzeby nowego bloku { while (blok identyfikacyjny ma założoną blokadę) sleep (zdarzenie : zdjęcie blokady z bloku identyfikacyjnego) ; usuń blok z listy wolnych w bloku identyfikacyjnym; if (z listy usunięto ostatni blok) { załóż blokadę na blok identyfikacyjny; czytaj blok, którego numer pobrano z listy wolnych (al bread) ; kopiuj numery bloków do bloku identyfikacyjnego; zwolnij bufor bloku (al brelse); zdejmij blokadę z boku identyfikacyjnego; obudź procesy (zdarzenie : zdjęto blokadę z bloku identyfikacyjnego); } pobierz bufor na blok usunięty z listy w bloku identyfikacyjnym (al getblk); wyzeruj bufor; zmniejsz o 1 całkowity licznik wolnych bloków; zaznacz, że blok identyfikacyjny był modyfikowany; return (bufor); } 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

64 Rys. Konfiguracja początkowa Lista w bloku identyfikacyjnym 109 208202205112 109 211 949 Zwolnienie bloku 949 Przydział bloku 949 109 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

65 Rys. Po przydziale numeru bloku (109) wypełnia się ponownie listę wolnych bloków w bloku identyfikacyjnym Lista w bloku identyfikacyjnym 211 341335338243 211 334 112208202205 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

66 Przykład: Różnica między prawem do czytania i przeglądania katalogów Mkdir śmiecie For i in 1 2 3 4 5 Do Echo witaj > śmiecie/$i Done Ls –ld śmiecie Ls –l śmiecie Chmod –r śmiecie Ls –ld śmiecie Ls śmiecie Ls –l śmiecie Cd śmiecie Pwd Ls –l Echo * Cd.. Chmod +r śmiecie Chmod –x śmiecie Ls śmiecie Ls –l śmiecie Cd śmiecie Chmod +x śmiecie 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

67 Rozdział czwarty – „Funkcje systemowe systemu plików” 2. Podręczna pamięć buforowa 2. Podręczna pamięć buforowa 4. Funkcje systemowe systemu plików 4. Funkcje systemowe systemu plików 3. Wewnętrzna reprezentacja plików 3. Wewnętrzna reprezentacja plików 5. Struktura procesów 5. Struktura procesów 6. Zarządzanie procesami 6. Zarządzanie procesami MENU 1. Wstęp 1. Wstęp

68 Rys. Funkcje systemowe systemu plików i ich związek z algorytmami 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU iget iput bmap namei alloc freeialloc ifree Algorytmy przydziału bufora getblk brelse breada bwrite Niskopoziomowe algorytmy systemu plików Przekaz. deskr. pliku Użycie namei Przydział I-węzłów Atryb. pliku We-wy na pliku Strukt. systemu plików Obsługa drzewa Funkcje systemu plików open creat dup pipe close creat mknod link unlink chown chmod stat read write lseek mount umount chdir chown open stat creat link chdir unlink chroot mknod chown mount chmod umount

69 Algorytm otwierania pliku algorytm open wejście: nazwa pliku sposób otwierania prawa dostępu do pliku (podczas tworzenia pliku) wyjście: deskryptor pliku { przekształć nazwę pliku w i-węzeł (algorytm namei); if (plik nie istnieje lub brak uprawnień) return (błąd); przydziel pozycję w tablicy plików na i-węzeł, zainicjuj licznik i bieżącą pozycję w pliku; Przydziel pozycję w tablicy deskryptorów użytkownika, ustaw wskaźnik do pozycji w tablicy plików; if (sposób otwarcia wymaga obcięcia pliku) zwolnij wszystkie bloki pliku (algorytm free); zdejmij blokadę z i-węzła; /* założoną w namei */ return (deskryptor pliku) } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

70 Rys. Struktury danych po wywołaniu open 0 1 2 3 4 5 6 7 Tablica deskryptorów plików użytkownika LicznikCzytanie 0 Tablica plików LicznikCzyt-pis 0 LicznikPisanie 0 Licznik 0 Tablica i-węzłów Licznik 0 LicznikCzytanie 1 Licznik 1 LicznikCzyt-pis 1 Licznik 1 LicznikPisanie 1 Licznik 2 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU dp1 = open („/etc/passwd”,O_RDONLY);dp2 = open („lokalny”,O_RDWR);dp3 = open („/etc/passwd”,O_WRONLY);

71 Tablica plików Rys. Struktury danych po otwarciu plików przez dwa procesy 0 1 2 3 4 5 6 7 Tablica deskryptorów plików użytkownika 0 1 2 3 4 5 6 7 Licznik Pisanie 1 Licznik Czytanie 1 Licznik Czyt-pis 1 Licznik Czytanie 1 Licznik Czytanie 1 Tablica i-węzłów Licznik 3 (/etc/passwd) Licznik 1 (lokalny) Licznik 1 (prywatny) 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

72 Algorytm czytania pliku algorytm read wejście: deskryptor pliku użytkownika adres bufora w procesie użytkownika liczba bajtów do wczytania wyjście: liczba bajtów skopiowanych do obszaru użytkownika { pobierz wskaźnik pozycji w tablicy plików korzystając z deskryptora pliku użytkownika; sprawdź prawa dostępu do pliku; ustaw w u-obszarze parametry określające adres w obszarze użytkownika, licznik bajtów, kierunek transmisji (do użytkownika); pobierz wskaźnik i-węzła z tablicy plików; załóż blokadę na i-węzeł; ustaw w u-obszarze położenie bajtu w pliku pobierając je z tablicy plików; while (nie osiągnięto wskazania licznika) { przekształć położenie bajtu w pliku na blok dyskowy (algorytm bmap); oblicz przesunięcie w bloku, liczbę bajtów do czytania; if (liczba bajtów do czytania równa się 0) /* próba czytania końca pliku */ break; /* wyjście z pętli */ czytaj blok (algorytm breada, jeśli czytanie z wyprzedzeniem, w przeciwnym razie algorytm bread); 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

73 Algorytm czytania pliku c.d. kopiuj dane z bufora systemowego do bufora użytkownika; uaktualnij pola w u-obszarze zawierające położenie bajtu w pliku, licznik czytanych bajtów, adres w obszarze użytkownika; zwolnij bufor; /* blokadę założono w bread */ } zdejmij blokadę z i-węzła; uaktualnij adres w pliku w tablicy plików do następnego czytania; return (całkowita liczba wczytanych bajtów); } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

74 Rys. Parametry wejścia-wyjścia przechowywane w u-obszarze trybwskazuje czytanie lub pisanie licznikliczba bajtów do wczytania lub wypisania położeniepołożenie bajtu w pliku adresdocelowy adres na kopiowane dane w pamięci użytkownika lub jądra znacznikwskazuje, czy adres jest w pamięci użytkownika czy jądra trybwskazuje czytanie lub pisanie licznikliczba bajtów do wczytania lub wypisania położeniepołożenie bajtu w pliku adresdocelowy adres na kopiowane dane w pamięci użytkownika lub jądra znacznikwskazuje, czy adres jest w pamięci użytkownika czy jądra 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

75 Przykładowy program czytający plik #include main() { int dp; char małybuf[20], dużybuf[1024]; dp=open(„/etc/passwd”, O_RDONLY); read(dp,małybuf,20); read(dp,dużybuf,1024); read(dp,małybuf,20); } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

76 Przykład: Proces czytający i piszący #include /* proces A */ main() { int dp; char buf[512]; dp=open(„/etc/passwd”,O_RDONLY); read(dp,buf,sizeof(buf)); } /* proces B */ main() { int dp,i; char buf[512]; for (i=0;i<sizeof(buf);i++) buf[i]=‘a’; dp=open(„/etc/passwd”,O_RDONLY); write(dp,buf,sizeof(buf)); } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

77 Przykład: Czytanie pliku z użyciem dwóch deskryptorów #include main() { int dp1, dp2; char buf1[512], buf2[512]; dp1=open(„/etc/passwd”,O_RDONLY); dp2=open(„/etc/passwd”,O_RDONLY); read(dp1,buf1,sizeof(buf1)); read(dp2,buf2,sizeof(buf2)); } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

78 Przykład: Program korzystający z funkcji systemowej lseek #include main(int argc, char *argv[]) { int dp, poz; char c; if (argc!=2) exit(); dp=open(argv[1],O_RDONLY); if (dp==-1) exit(); while ((poz=read(dp,&c,1))==1) { printf(„znak %c\n”,c); poz=lseek(dp,1023L,1); printf(„nowa pozycja %d\n”,poz); } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

79 Tablica plików Rys. Tablice po zamknięciu pliku 0 1 2 3 4 5 Tablica deskryptorów plików użytkownika 0 1 2 3 4 5 NULL Licznik Pisanie 1 Licznik 0 Licznik Czyt-pis 1 Licznik Czytanie 1 Licznik 0 Tablica i-węzłów Licznik 2 (/etc/passwd) Licznik 1 (lokalny) Licznik 0 (prywatny) 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

80 Algorytm tworzenia pliku algorytm creat wejście : nazwa pliku prawa dostępu wyjście: deskryptor pliku { pobierz i-węzeł odpowiadający nazwie pliku (algorytm namei); if (plik już istnieje) { if (nie ma uprawnień) { zwolnij i-węzeł (algorytm iput); return (błąd); } else /* plik jeszcze nie istnieje */ { przydziel wolny i-węzeł z systemu plików (algorytm ialloc); utwórz nową pozycję w katalogu macierzystym, dołącz nową nazwę pliku i nowo przydzielony numer i-węzła; } przydziel pozycję w tablicy plików na i-węzeł, zainicjuj licznik; if (plik istniał w chwili wywołania creat) zwolnij wszystkie bloki pliku (algorytm free); zdejmij blokadę z i-węzła; return (deskryptor pliku użytkownika); } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

81 Algorytm tworzenia nowego węzła algorytm mknod wejście : węzeł (nazwa pliku) prawa dostępu główny i drugorzędny numer urządzenia (dla blokowych i znakowych plików specjalnych) wyjście: brak { if (nowy węzeł nie jest nazwanym łączem i użytkownik nie jest nadzorcą) return (błąd); pobierz i-węzeł macierzysty nowego węzła (algorytm namei); if (nowy węzeł już istnieje) { zwolnij i-węzeł macierzysty (algorytm iput); return (błąd); } przydziel na potrzeby nowego węzła wolny i-węzeł z systemu plików (algorytm ialloc); utwórz nową pozycję w katalogu macierzystym, dołącz nazwę nowego węzła i numer nowo przydzielonego i-węzła; zwolnij i-węzeł katalogu macierzystego (algorytm iput); if (nowy węzeł jest blokowym lub znakowym plikiem specjalnym) wpisz numer główny i drugorzędny do struktury i-węzła; zwolnij i-węzeł nowego węzła (algorytm iput); } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

82 Algorytm zmiany bieżącego katalogu algorytm chdir wejście : nowa nazwa katalogu wyjście: brak { pobierz i-węzeł związany z katalogiem o nowej nazwie (algorytm namei); if (i-węzeł nie odpowiada katalogowi lub proces nie ma uprawnień) { zwolnij i-węzeł (algorytm iput); return (błąd); } zdejmij blokadę z i-węzła; zwolnij i-węzeł poprzednio bieżącego katalogu (algorytm iput); umieść nowy i-węzeł w u-obszarze w pozycji bieżącego katalogu; } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

83 Rys. Drzewo procesów i współdzielenie łączy Proces A Proces B Proces C Proces DProces E Tworzy łącze Współdzielą łącze Nie mogą współdzielić łącza 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

84 Algorytm tworzenia (nienazwanych) łączy algorytm pipe wejście: brak wyjście: deskryptor do czytania deskryptor do pisania { przydziel nowy i-węzeł z urządzenia do przechowywania łączy (algorytm ialloc); przydziel pozycję w tablicy plików do czytania i inną do pisania; zainicjuj pozycję w tablicy plików, by wskazywały nowy i -węzeł; przydziel deskryptor pliku użytkownika do czytania i inny do pisania, zainicjuj je tak, by wskazywały odpowiednie pozycje w tablicy plików; ustaw licznik odwołań do i-węzła na 2; zainicjuj licznik czytelników i pisarzy i-węzła na 1; } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

85 Pozycje w i-węźle odpowiadające Blokom bezpośrednim Rys. Logiczny obraz czytania i pisania do łącza 0123456789 Wskaźnik czytaniaWskaźnik pisania 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

86 Przykład: Czytanie i pisanie do łącza char napis[] = „cześć”; main () { char buf[1024]; char *wskz1, *wskz2; int dp[2]; wskz1 = napis; wskz2 = buf; while (*wskz1) *wskz2++ = *wskz1++; pipe (dp); for ( ; ; ) { write ( dp[1], buf, 6 ); read ( dp[0], buf, 6 ); } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

87 Przykład: Czytanie i pisanie do nazwanego łącza #include char napis[] = „cześć”; main (argc, argv) int argc; char *argv[]; { int dp; char buf[256]; /* utwórz nazwane łącze z prawem czytania / pisania przez wszystkich użytkowników */ mknod („fifo”, 010777, 0); if (argc == 2) dp = open(„fifo”, O_WRONLY); else dp = open(„fifo”, O_RDONLY); for ( ; ; ) if (argc == 2) write(dp, napis, 6); else read (dp, buf, 6); } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

88 Rys. Struktury danych po wywołaniu dup 0 1 2 3 4 5 6 7 Tablica deskryptorów plików użytkownika LicznikCzytanie 0 Tablica plików LicznikCzyt-pis 0 LicznikPisanie 0 Licznik 0 Tablica i-węzłów Licznik 0 LicznikCzytanie 1 Licznik 1 LicznikCzyt-pis 1 Licznik 1 LicznikPisanie 1 Licznik 2 1. open („/etc/passwd”,O_RDONLY);2. open („lokalny”,O_RDWR);3. open („/etc/passwd”, O_WRONLY ); etc/passwd lokalny 4. dup ( 3 ); LicznikCzytanie 2 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

89 Przykład: program ilustrujący funkcję dup() #include main () { int i, j; char buf [512], buf2 [512]; i = open(„etc/passwd”, O_RDONLY); j = dup( i ); read (i, buf1, sizeof(buf1)); read (j, buf2, sizeof(buf2)); close (i); read (j, buf2, sizeof(buf2)); } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

90 Drzewo systemu plików przed i po montowaniu binetc usr ccdateshgettypasswd / bininclude src awkbanneryaccstdio.huts / Główny system plików /dev/dsk1 System plików 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

91 Tablica montowania 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU Każda pozycja tablicy montowania zawiera Numer urządzenia, który identyfikuje montowany system plików Wskaźnik do bufora zawierającego blok identyfikacyjny systemu plików Wskaźnik do i-węzła korzenia montowanego systemu plików Wskaźnik do i-węzła katalogu będącego punktem zamontowania

92 Algorytm montowania systemu plików algorytm mount wejście : nazwa blokowego pliku specjalnego nazwa katalogu punktu zamontowania opcje (tylko do czytania) wyjście: brak { if (nie nadzorca) return (błąd) ; pobierz i-węzeł blokowego pliku specjalnego (algorytm namei); sprawdź poprawność; pobierz i-węzeł katalogu punktu zamontowania (algorytm namei); if (nie jest katalogiem lub licznik odwołań > 1) { zwolnij i-węzły (algorytm iput); return (błąd); } znajdź pustą pozycję w tablicy montowania; wywołaj procedurę otwarcia podprogramu sterującego urządzenia blokowego; pobierz wolny bufor z podręcznej pamięci buforowej; wczytaj blok identyfikacyjny do wolnego bufora; zainicjuj pola w bloku identyfikacyjnym; pobierz i-węzeł korzenia montowanego urządzenia (algorytm iget), wpisz wskaźnik do tablicy montowania; zaznacz odpowiednio i-węzeł punktu zamontowania; zwolnij i-węzeł pliku specjalnego (algorytm iput) ; zdejmij blokadę z i-węzła katalogu punktu zamontowania; } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

93 Rys. Struktury danych po wywołaniu mount Tablica i-węzłów I-węzeł punktu zamontowania (oznaczony) Licznik odwołań 1 I-węzeł urządzenia Nie używany Licznik odwołań 0 I-węzeł korzenia montowanego Systemu plików Licznik odwołań 1 Blok identyfikacyjny I-węzeł punktu zamontowania I-węzeł korzenia Tablica montowania Bufor 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

94 iget – zmodyfikowany algorytm dostępu do i-węzła o określonym numerze. Algorytm:zmodyfikowany iget ze wzg. na mount wejście: numer i-węzła w systemie plików wyjście: i-węzeł z założoną blokadą { while (nie gotowe) { if (i-węzeł w puli i-węzłów) { if (i-węzeł ma załozoną blokadę) { sleep (zdarzenie : zdjęcie blokady z i-węzła) ; continue; /* powrót do pętli while */ } /* specjalne przetwarzanie punktów zamontowania */ if (i-węzeł jest punktem zamontowania) { znajdź odpowiadającą mu pozycję w tablicy montowania; pobierz numer nowego systemu plików z tablicy montowania; użyj do szukania numeru i-węzła korzenia; continue; /* powrót do pętli while */ } if (i-węzeł na liscie wolnych i-węzłów) usuń z listy wolnych; zwiększ o l licznik odwołan w i-węźle; return (i-węzeł); } /* i-węzła nie ma w puli i-węzłów */ usuń nowy i-węzeł z listy wolnych; zmień numer i-węzła i systemu plików; usuń i-węzeł ze starej kolejki mieszającej i umieść w nowej ; wczytaj i-węzeł z dysku (algorytm bread) ; wypełnij inicjalnie i-węzeł (np. licznik odwołań na 1); return (i-węzeł); } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

95 namei – zmodyfikowany algorytm analizy nazwy ścieżkowej. Algorytm:zmodyfikowany namei ze wzg. na mount wejście: nazwa ścieżkowa wyjście:i-węzeł z założoną blokadą { if ( nazwa ścieżkowa rozpoczyna się od korzenia ) i-węzeł roboczy = i-węzeł korzenia ( algorytm iget ); else i-węzeł roboczy = i-węzeł bieżącego katalogu ( alg. iget ); while ( są jeszcze składowe w nazwie ścieżkowej ) { wczytaj z wejścia kolejną składową nazwy ścieżkowej; sprawdź, czy i-węzeł roboczy odpowiada katalogowi i czy prawa dostępu są w porządku; if ( i-węzeł jest zmienionym korzeniem i składową jest ‘..’ ) continue;/* powrót do pętli while */ szukanie składowej: czytaj i-węzeł ( katalog );/* algorytm bmap, bread i brelse */ if (składowa pasuje do pozycji katalogu ) { pobierz numer i-węzła pasującej składowej; if ( znaleziona i-węzeł korzenia, i-węzeł roboczy jest korzeniem, składową..) {/* przekraczanie punktu zamontowania */ pobierz pozycję z tab. montowania odpowiadająca i-węzłowi roboczemu; zwolnij i-węzeł roboczy ( alg. iput ); zwolni i-węzeł roboczy = i-węzeł punktu zamontowania; załóż blokadę na i-węzeł roboczego; przejdź do szukania składowej ( dla ‘..’ ); } zwolnij i-węzeł roboczy ( alg. iput); i-węzeł roboczy = i-węzeł pasującej składowej ( alg. iget ); } else /* składowej nie ma katalogu */ return (bez i-węzła ); } return ( i-węzeł roboczy ); } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

96 umount – algorytm demontowania systemu plików Algorytm:umount wejście: specjalna nazwa demontowanego pliku systemu plików wyjście: brak { if (nie nadzorca) return ( błąd ); pobierz i-węzeł pliku specjalnego ( alg. namei ); wydziel numer główny i drugorzędny demontowanego urządzenia; pobierz pozycję z tablicy montowania, korzystając z tych numerów zwolnij i-węzeł pliku specjalnego ( alg. iput ); usuń z tablicy segmentów pozycje odpowiadające instrukcjom dzielonym na plikach należących do tego sys. plików; uaktualnij blok identyfikacyjny, i-węzły, opróżnij bufory plików; if ( pliki z tego systemu plików nadal w użyciu ) return ( błąd ); pobierz i-węzeł korzenia zamontowanego systemu plików (wskaźnik jest w tablicy montowania ); załóż blokadę na i-węzeł; zwolnij i-węzeł (alg. iput );/* iget było w mount */ wywołaj procedurę zamykania urządzenia specjalnego; unieważnij bufory w puli zajęte przez demontowany system plików pobierz i-węzeł punktu zamontowania (wskaźnik jest w tablicy montowania); załóż blokadę na i-węzeł; zwolnij znacznik określający go jako punkt zamontowania; zwolnij-węzeł (alg. iput ); /*iget w mount */ zwolnij bufor użyty na blok identyfikacyjny; zwolnij pozycję tablicy montowania; } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

97 Link - powiązanie plików w drzewie systemu plików. sys testfile.h / usr src uts include sysrealfile.h 1. link (”usr/src/uts/sys”, ”usr/include/sys”); 2. link (”usr/include/realfile.h”, ”usr/src/uts/sys/testfile.h”); 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

98 Link - dodaje dowiązanie do pliku. Algorytmlink /* utwórz dowiązanie do pliku */ wejście: nazwa istniejącego pliku nowa nazwa pliku wyjście:brak { pobierz i-węzeł istniejącego pliku (alg namei ); if ( za dużo dowiązań do pliku lub próba dowiązania katalogu bez uprawnień nadzorcy) { zwolnij i-węzeł (alg. iput ); return (błąd ); } zwiększ licznik dowiązań w i -węźle; uaktualnij dyskową kopię i-węzła; zdejmij blokadę z i-węzła pobierz i-węzeł katalogu macierzystego, który ma zawierać nowy plik (alg namei ); if ( nowa nazwa pliku nie istnieje lub istniejący i nowy plik należą do różnych systemów plików ) { odtwórz stan sprzed modyfikacji; return (błąd ); } utwórz nową pozycję w katalogu macierzystym :wstaw nową nazwę pliku, numer i-węzła istniejącego liku; zwolnij i-węzeł katalogu macierzystego (alg. iput ); zwolnij i-węzeł istniejącego pliku (alg. iput ); } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

99 Scenariusz zastoju podczas tworzenia dowiązań czas proces Aproces B Spróbuj pobrać i-węzeł e Spij – blokada na i-węźle e Pobierz i-węzeł a Zwolnij i-węzeł a Pobierz i-węzeł b Zwolnij b Pobierz i-węzeł c Zwolnij c Pobierz i-węzeł d Spróbuj pobrać i-węzeł e Śpij – blokada na i-węźle e Pobierz i-węzeł e Zwolnij e Pobierz i-węzeł f Pobierz i-węzeł a Zwolnij a Pobierz i-węzeł e Zwolnij e Spróbuj pobrać i-węzeł f Spij – proces b założył blokadę na i-węzeł Obudź się – zdjęcie blokady z i-węzła e Spróbuj pobrać i-węzeł d Spij – proces a założył blokadę na i-węzeł Zastój 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

100 Unlink - usuwa dowiązanie do pliku Algorytmunlink /* usuń dowiązanie do pliku */ wejście: nazwa pliku wyjście: brak { pobierz i-węzeł macierzysty odwiązanego pliku (alg. namei ); /* jeśli usuwane dowiązanie do bieżącego katalogu...*/ if ( ostatnią składową nazwy pliku jest.) zwiększ licznik odwołań w i-węźle; else pobierz i-węzeł odwiązywanego pliku ( alg. iget ); if ( plik jest katalogiem, lecz użytkownik nie jest nadzorcą ) { zwolnij i-węzły ( alg. iput) return (błąd ); } if ( plik z instrukcjami dzielonymi i licznik dowiązań równy 1 ) usuń z tablicy segmentów; zapisz katalog macierzysty: wyzeruj numer i-węzła odwiązywanego pliku; zwolnij i-węzeł katalogu macierzystego ( alg. iput ); zmniejsz licznik dowiązań do pliku; zwolnij i-węzeł pliku ( alg. iput ); /* iput sprawdza, czy licznik dowiązań jest 0; jeśli tak, to zwalnia bloki (alg. free) i zwalnia i-węzeł ( alg. ifree ); } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

101 Zwalnianie i-węzła algorytm iput /* zwolnij i-wezeł w pamięci */ wejście: wskaźnik do i-węzła w pamięci wyjście: brak { jeśli nie ma blokady na i-węźle, to ją załóż; zmniejsz o 1 licznik odwołań do i-węzła; if (licznik odwołań == 0) { if (licznik dowiązań i-węzła == 0) { zwolnij bloki dyskowe zajęte przez plik (algorytm free, p. 4.7); ustaw typ pliku na 0; zwolnij i-węzeł (algorytm ifree, p. 4.6); } if (był dostęp do pliku lub zmienił się i-węzeł lub zmienił się pli k) uaktualnij i-węzeł na dysku; wstaw i-węzeł do listy wolnych; } zdejmij blokadę z i-węzła; } 3. Wewnętrzna rep. plików 3. Wewnętrzna rep. plików MENU

102 Unlink - wyścig procesów podczas usuwania dowiązania. czas proces Aproces Bproces C Odwiąż plik c Znajduje i-węzeł dla c z blokadą Śpi Szukaj nazwy c w katalogu b Znajdź numer i-węzła c Znajduje i-węzeł c z blokadą Śpi Budzi się i c wolne, odwiązuje c stary i-węzeł wolny, jeśli licznik dowiązań równy zero Przydziel i-węzeł nowemu plikowi n Przypadkowo przydziela stary i-węzeł c W końcu zdejmuje blokadę z i-węzła n Budzi się i stary i-węzeł c wolny (nowy i-węzeł n) Weź i-węzeł n Szukaj nazwy d w n 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

103 ulink - przykładowy program usuwający dowiązania do otwartego pliku #include main (argc, argv) int argc; char * argv[]; { int dp; char buf[1024]; struct stat bufStanu; if (argc != 2) /* potrzebny parametr */ exit(); dp = open(argv[1], O_RDONLY); if (dp == -1) /* błąd w open */ exit(); if (unlink(argv[1]) == -1) /* usuń dowiązanie do otwartego pliku */ exit(); if (stat(argv[1], &bufStanu) == -1) /* użycie nazwy */ printf (”Błąd w stat dla %s zgodnie z oczekiwaniem\n”, argv[1]); else printf (”stat dla %s zakończone sukcesem!\n”, argv[1]); if (fstat(fd, &bufStanu) == -1) /* użycie deskryptora */ printf (”Błąd w fstat dla %s\n”, argv[1]); else printf (”Sukces w fstat dla %s zgodnie z oczekiwaniem\n”, argv[1]); while (read(dp, buf, sizeof(buf)) > 0) /* czytaj otwarty odwiązany plik */ printf(”%1024s”, buf); /* drukuj 1K bajtowe pole */ } 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

104 I-węzły dla systemów plików różnych typów open close read write ropen rclose rread rwrite Operacje systemu plików I-węzły rodzajowe I-węzły systemu plików Systemu V Zdalne i-węzły System V Zdalne 4. Funkcje sys. syst. plików 4. Funkcje sys. syst. plików MENU

105 Rozdział piąty – „Struktura procesów” 2. Podręczna pamięć buforowa 2. Podręczna pamięć buforowa 5. Struktura procesów 5. Struktura procesów 3. Wewnętrzna reprezentacja plików 3. Wewnętrzna reprezentacja plików 4. Funkcje systemowe systemu plików 4. Funkcje systemowe systemu plików 6. Zarządzanie procesami 6. Zarządzanie procesami MENU 1. Wstęp 1. Wstęp

106 Diagram przejść międzystanowych procesu. 1 72 9 43 56 8 Wykonywany w trybie użytkownika Uśpiony poza pamięcią Gotowy do wykonania poza pamięcią Sprawdź i obsłuż sygnały Sprawdź wystąpienie sygnałów fork Utworzony za mało pamięci (tylko system wymiany) sprowadzenie do pamięci usunięcie z pamięci budzi się usunięcie z pamięci budzi się Uśpiony w pamięci Zombie zasypia wyjście uszereguj ponownie proces dość pamięci Gotowy do wykonania w pamięci Wywłaszczony wywłaszczenie Wykonywany w trybie jądra powrót do użytkownika wywołanie funkcji systemowej, przerwanie przerwanie, powrót z przerwania 5. Struktura procesów 5. Struktura procesów MENU

107 Tablica procesów – pola zawarte w tablicy procesów. Pozycja w tablicy procesów zawiera: Pole stanu - identyfikuje stan procesu; Pole z informacją, które pozwala jądru zlokalizować proces i jego u- obszar w pamięci głównej lub pomocniczej; Kilka identyfikatorów użytkownika UID, określa różne przywileje procesu; Identyfikatory procesu (PID) specyfikują wzajemne relacje między procesami. Pola te są ustawiane, gdy proces wchodzi do stanu „utworzony” w wywołaniu funkcji fork(); Deskryptor zdarzenia, gdy proces jest w stanie uśpionym; Parametry szeregowania; Pole sygnałów - wylicza sygnały wysłane do procesu i jeszcze nie obsłużone; Różne liczniki - pokazują czas wykonania procesu; 5. Struktura procesów 5. Struktura procesów MENU

108 Tablica procesów – pola zawarte w tablicy procesów. U-obszar zawiera: Wskaźnik do tablicy procesów – identyfikuje pozycję odpowiadającą temu u-obszarowi; Rzeczywisty i obowiązujący identyfikator użytkownika; Pola liczników - rejestrują czas spędzony w trybie użytkownika i jądra; Tablica - wskazuje, jak proces chce reagować na sygnały; Pole terminala sterującego; Pole błędu – rejestruje błędy podczas wykonania funkcji systemowych; Pole wartości przekazywanej – wynik ostatniej funkcji systemowej; Parametry wejścia / wyjścia opisują ilość danych do transmisji, adres źródłowej / docelowej tablicy w pamięci użytkownika, itp. Bieżący katalog i bieżący korzeń opisują środowisko systemu plików procesu; Tablica deskryptorów plików użytkownika; Pola graniczne określają rozmiar procesu i pliku, jaki proces może zapisać; Pola uprawnień modyfikują ustawienie praw dostępu do plików tworzonych przez proces. 5. Struktura procesów 5. Struktura procesów MENU

109 Rysunek procesów i segmentów Tablice segmentów procesu (adresy wirtualne) Instrukcje Dane Stos 8 K 16 K 32 K Instrukcje Dane Stos 4 K 8 K 32 K Proces A: Proces B: a Segmenty b d c e 5. Struktura procesów 5. Struktura procesów MENU

110 Adresowanie pamięci fizycznej jako stron. Odwzorowanie logicznych numerów stron w fizyczne. Adres szesnastkowy58432 Dwójkowy0101 1000 0100 0011 0010 Numer strony, przesunięcie na stronie: 01 0110 0001 00 0011 0010 Szesnastkowo:161 32 Adresowanie pamięci fizycznej jako stron: Logiczny numer stronyFizyczny numer strony 0177 154 2209 317 Odwzorowanie logicznych numerów stron w fizyczne. 5. Struktura procesów 5. Struktura procesów MENU

111 Odzworowanie adresów wirtualnych w fizyczne 5. Struktura procesów 5. Struktura procesów MENU 8K 32K 64K 541 K 783 K 986 K 897 K 87 K 522 K 727 K 941 K 1096 K 2001 K Puste 137 K 852 K 764 K 433 K 333 K Instrukcje Dane Stos Tablica segmentów procesu Adresy wirtualne Tablice stron (adresy fizyczne)

112 Przejście od trybu użytkownika do trybu jądra 5. Struktura procesów 5. Struktura procesów MENU 0 1 M 2 M 4 M Adres tablicy stron Adres wirtualny Liczba stron w tablicy stron Rej. jądra trójka 1 Rej. jądra trójka 2 Rej. jądra trójka 3 Rej. użytk. trójka 1 Rej. użytk. trójka 2 Rej. użytk. trójka 3 856 K 917 K 564 K 44 K 747 K 950 K 333 K 556 K 997 K 458 K 632 K 0 K 4 K 3 K 17 K 128 K 97 K 135 K 256 K 292 K 304 K 279 K 139 K Tablice stron (segmentu) procesu Tablice stron jądra

113 Odwzorowanie pamięci u-obszaru w jądrze 5. Struktura procesów 5. Struktura procesów MENU 2 M Adres tablicy stron Adres wirtualny w procesie Liczba stron w tablicy stron Rej. trójka 1 Rej. trójka 2 (U-obszar) Rej. trójka 3 114 K 708 K 143 K 565 K 843 K 794 K 361 K 1879 K 290 K 450 K 770 K 184 K 176 K 209 K 477 K 847 K 4 Tablice stron dla u-obszarów

114 Składniki kontekstu procesu 5. Struktura procesów 5. Struktura procesów MENU Instrukcje procesu Dane Stos Dane dzielone Statyczna część kontekstu Kontekst poziomu użytkownika Pozycja w tablicy procesów U-obszar Tablica segmentów procesu Statyczna część kontekstu poziomu systemu (Poziom użytkownika) Stos jądra dla warstwy 1 Zachowany kontekst rejestru dla warstwy 0 Stos jądra dla warstwy 2 Zachowany kontekst rejestru dla warstwy 1 Stos jądra dla warstwy 3 Zachowany kontekst rejestru dla warstwy 2 Dynamiczna część kontekstu Kontekst jądra Warstwa 0 Warstwa 1 Warstwa 2 Warstwa 3 Wskaźnik logiczny bieżącej warstwy kontekstu

115 Przykładowy wektor przerwań. Numer przerwaniaFunkcja obsługi przerwania 0clockintr 1diskintr 2ttyintr 3devintr 4softintr 5otherintr 5. Struktura procesów 5. Struktura procesów MENU

116 inthand – algorytm obsługi przerwań Algorytminthand /* obsłuż przerwania */ wejście: brak wyjście:brak { zachowaj (włóż na stos) poprzednią warstwę kontekstu; określ źródło przerwania; znajdź wektor przerwania; wywołaj funkcję obsługi przerwania; odtwórz (zdejmij ze stosu) poprzednią warstwę kontekstu; } 5. Struktura procesów 5. Struktura procesów MENU

117 syscall - Przykład przerwań Warstwa 1 kontekstu jądra Wykonaj funkcję obsługi przerwania „wywołanie funkcji systemowej” Zachowaj kontekst rejestru Poziom użytkownika Warstwa 2 kontekstu jądra Wykonaj funkcję obsługi przerwania dyskowego Zachowaj kontekst rejestru funkcji obsługi przerwania wywołania funkcji systemowej Warstwa 3 kontekstu jądra Wykonaj funkcję obsługi przerwania zegarowego Zachowaj kontekst rejestru funkcji obsługi przerwania dyskowego Wykonywanie w trybie użytkownika Wywołaj funkcję systemową Przerwanie dyskowe Przerwanie zegarowe 5. Struktura procesów 5. Struktura procesów MENU

118 syscall – algorytm wywołania funkcji systemowej algorytm syscall wejście:numer funkcji systemowej wyjście:wynik wywołania { znajdź pozycję w tablicy funkcji systemowych odpowiadającą funkcji o podanym numerze; określ liczbę parametrów wywołania; skopiuj parametry z przestrzeni adresowej użytkownika do u-obszaru; zachowaj bieżący kontekst na wypadek awaryjnego powrotu; wywołaj kod funkcji w jądrze; if (bład podczas wykonania funkcji systemowej) { wstaw numer błędu do rejestru 0 w konteksćie rejestru zachowanym przez użytkownika; włącz bit przeniesienia w rejestrze PS w kontekście rejestru zachowanym przez użytkownika; } else wstaw przekazywanie wartości do rejestrów 0 i 1 w konteksćie rejestru zachowanym przez użytkownika; } 5. Struktura procesów 5. Struktura procesów MENU

119 Funkcja systemowa creat i kod wygenerowany dla Motoroli 68000 char nazwa[] = ”plik”; main() { int dp; dp = creat(nazwa, 0666) } Części kodu wygenerowanego w asemblerze: 58:mov&0x1b6,(%sp)# włóż 0666 na stos 5e:mov&0x204,-(%sp)# przesuń wsk. stosu i włóż zmienną „nazwa” na stos 64:jsr0x7a# wywołaj f-cję biblioteczną odpowiadającą creat # kod biblioteczny odpowiadający creat: 7a:movq&0x8,%d0# włóż wartość 8 do rejestru danych nr 0 7c:trap&0x0# instrukcja przerwania systemowego 7e:bcc &0x6 # skok do 86 gdy bit przesunięcia = 0 80:jmp 0x13c# skok bezwarunkowy do 13c # kod biblioteczny obsługi błędów w funkcji systemowej: 13c:mov%d0,&0x20e# prześlij dane z rejestru 0 do 20e 142:movq &-0x1,%d0# prześlij stałą -1 do rejestru nr 0 144:mova %d0,%a0 146:rts# powrót z procedury 5. Struktura procesów 5. Struktura procesów MENU

120 syscall – postać stosu podczas wykonywania funkcji systemowej creat...... tryb (ósemkowo 666) Adres zmiennej „nazwa” Adres powrotu z biblioteki 1b6 204 6a trap w 7c Wartość wskaźnika stosu w chwili napotkania trap Kierunek wzrostu stosu. Stos jądra Warstwa 1 kontekstu Sekwencja wywołania dla creat Zachowany kontekst rejestru dla poziomu 0 (użytkownik) Wskaźnik rozkazów 7e Wskaźnik stosu ps Rejestr 0 (wartość wej. 8) Inne rejestry ogólnego przezn. 5. Struktura procesów 5. Struktura procesów MENU

121 Zmiana kontekstu – etapy zmiany kontekstu. Etapy zmiany kontekstu. 1.Zadecyduj, czy dokonać zmiany kontekstu i czy jest ona teraz dopuszczalna. 2.Zachowaj kontekst „starego” procesu. 3.Znajdź „najlepszy” proces do wykonania, stosując algorytm szeregowania. 4.Odtwórz kontekst tego procesu. 5. Struktura procesów 5. Struktura procesów MENU

122 Zmiana kontekstu – pseudokod. if (save_context()) /* zachowaj kontekst wykonywanego procesu /* { /* wybierz inny proces do wykonywania */... resume_context(nowy_proces); /* nigdy tutaj nie dojdzie */ } /* odtąd wykonuje się proces po wznowieniu */ 5. Struktura procesów 5. Struktura procesów MENU

123 Przesyłanie danych z obszaru użytkownika do obszaru jądra na komputerze VAX fubyte: prober$3,$1,*4(ap)# czy bajt dostępny beq1eret# nie movzbl*4(ap),r0 ret eret: mnegl$1,r0# powrót z błędem (-1) ret 5. Struktura procesów 5. Struktura procesów MENU

124 Tablica segmentów - pozycja w tablicy segmentów. Tablica segmentów zawiera: Wskaźnik do i-węzła pliku – który plik wstawiono inicjalnie do segmentu; Typ segmentu (instrukcje, pamięć dzielona, prywatne dane, stos); Rozmiar segmentu; Położenie segmentu w pamięci fizycznej; Stan segmentu - może być kombinacją takich warunków: segment ma założoną blokadę; segment jest żądany; segment jest w trakcie ładowania do pamięci; segment jest aktualnie dostępny w pamięci; Licznik odwołań – odpowiada liczbie procesów, które odwołują się do segmentu; 5. Struktura procesów 5. Struktura procesów MENU

125 allocreg - przydziela strukturę danych opisujących segment Algorytmallocreg /*przydziel strukturę danych opisuj. segment*/ wejście:(1) wskaźnik do i-węzła (2) typ segmentu wyjście:segment z założoną blokadą { usuń segment z listy wolnych segmentów; przypisz typ segmentu; przypisz wskaźnik do i-węzła segmentu; if (wskaźnik do i-węzła nie jest pusty) zwiększ licznik odwołań do i-węzła; umieść segment na liście zajętych segmentów; return (segment z założoną blokadą); } 5. Struktura procesów 5. Struktura procesów MENU

126 attachreg - przyłącza segment do procesu. Algorytm attachreg /*przyłącz segment do procesu*/ wejście:(1) wskaźnik do dołączonego segmentu (z założoną blokadą) (2) proces, do którego dołącza się e segment (3) adres wirtualny w procesie, pod który dołącza się segment (4) typ segmentu wyjście:pozycja w tablicy segmentów procesu { przydziel procesowi pozycję w tablicy segmentów procesu; zainicjuj pozycję w tablicy segmentów procesu; ustaw wskaźnik do przyłączanego segmentu; ustaw pole typu; ustaw pole adresu wirtualnego; sprawdź poprawność adresu wirtualnego, rozmiar segmentu; zwiększ licznik odwołań segmentu; zwiększ rozmiar procesu zgodnie z przyłączanym segmentem; zainicjuj nową trójkę rejestrów sprzętowych dla procesu; return (pozycja w tablicy segmentów procesu); } 5. Struktura procesów 5. Struktura procesów MENU

127 attachreg – przykład przyłączania istniejącego segmentu instrukcji. Adres tablicy stron Adres wirtualny procesu Rozmiar i ochrona 09 Tablica segmentów procesu Pozycja dla instrukcji Puste 846K 752K 341K 484K 976K 5. Struktura procesów 5. Struktura procesów MENU

128 growreg - zmienia rozmiar segmentu. algorytm growerg /* zmień rozmiar segmentu */ wejście:(1) wskaźnik do pozycji w tablicy segmentów procesu (2) wielkość zmiany rozmiaru segmentu (dodatnia lub ujemna) wyjście:brak { if (rozmiar segmentu rośnie) { sprawdź poprawność nowego segmentu; przydziel tablice pomocnicze (tablice stron); if (nie jest to system ze stronicow. na żądanie) { przydziel pamięć fizyczną; zainicjuj zgodnie z potrzebą tablice pomocnicze; } else /* rozmiar segmentu maleje*/ { zwolnij pamięć fizyczną, tak jak należy; zwolnij tablice pomocnicze, tak jak należy; } wykonaj (dalszą) inicjację tablic pomocniczych, w miarę potrzeby; ustaw pole rozmiaru w tablicy procesu; } 5. Struktura procesów 5. Struktura procesów MENU

129 growreg - zwiększenie rozmiaru segmentu stosu o 1KB. Adres tablicy stron Adres wirtualny procesu Rozmiar i ochrona 128K6K Tablica segmentów procesu Pozycja dla stosu 446K 796K 341K 532K 846K 752K 7K 484K 1. Zmiana rozmiaru. 2. Nowa strona. 5. Struktura procesów 5. Struktura procesów MENU

130 loadreg - załaduj część pliku do segmentu. Algorytmloadreg /* załaduj część pliku do segmentu */ wejście:(1) wskaźnik do pozycji w tablicy segmentów procesu (2) adres wirtualny, pod który ładuje się segment (3) i-węzeł pliku z ładowanym segmentem (4) adres bajtowy w pliku początku segmentu (5) licznik bajtów do załadowania wyjście: brak { zwiększ rozmiar segmentu zgodnie z jego końcowym rozmiarem (algorytm growreg); zaznacz stan segmentu: ładowany do pamięci; zdejmij blokadę z segmentu; ustaw parametry w u-obszarze do czytania pliku: docelowy adres wirtualny, pod który czyta się dane; początkowy adres bajtowy do czytania pliku; licznik bajtów czytanych z pliku; wczytaj plik do segmentu (wew. wariant algorytm read); załóż blokadę na segment; zaznacz stan segmentu; całkowicie załadowany do pamięci; obudź wszystkie procesy czekające na załadowanie segmentu; } 5. Struktura procesów 5. Struktura procesów MENU

131 loadreg - ładowanie segmentu instrukcji. Adres tablicy stron Adres wirtualny procesu Rozmiar i ochrona Tablica segmentów procesu Instrukcje ---0 1. Początkowa zawartość pozycji.2. Pierwsze wywołanie growreg: puste 4 779 K 846 K 752 K 341 K 3. Po pierwszym growreg. Tablica z jedną pozycją na odstęp.4. Wywołanie drugiego growreg()5. Po drugim growreg. 5. Struktura procesów 5. Struktura procesów MENU

132 freereg - zwolnij przydzielony segment. algorytm freereg /*zwolnij przydzielony segment*/ wejście:wskaźnik do segmentu (z założoną blokadą) wyjście: brak { if (licznik odwołań do segmentu jest różny od zera) { /* jakiś proces nadal korzysta z segmentu */ zdejmij blokadę z segmentu; if ( z segmentem jest związany i-węzeł) zdejmij blokadę z i-węzła; return; } if ( z segmentem jest związany i-węzeł) zwolnij i-węzeł (algorytm iput); zwolnij pamięć fizyczną nadal związaną z segmentem; zwolnij tablice pomocnicze związane z segmentem; wyczyść pola segmentu; umieść segment na liście wolnych segmentów; zdejmij blokadę z segmentu; } 5. Struktura procesów 5. Struktura procesów MENU

133 detachreg - odłącz segment od procesu. Algorytmdetachreg /* odłącz segment od procesu */ wejście: wskażnik do segmentu (z założoną blokadą) wyjście: brak { if (licznik odwołań do segmentu jest rózny od zera) { /* jakiś proces nadal korzysta z segmentu */ zdejmij blkadę z segmentu; if (segment jest związany i-węzłem) zdejmij blokadę z i-węzła; return; } if (z segmentem jest związany i-węzeł) zwolnij i-węzeł (algorytm iput); zwolnij pamięć fizyczną nadal związaną z segmentem ; zwolnij tablice pomocnicze związane z segmentem ; wyczyść pola segmentu; umieść segment na liście wolnych segmentów; zdejmij blokadę z segmentu; } 5. Struktura procesów 5. Struktura procesów MENU

134 Powielanie segmentu 5. Struktura procesów 5. Struktura procesów MENU Dzielony Prywatny Segmenty Instrukcje Dane Stos Instrukcje Dane Stos Proces A Proces B Tablice segmentów procesu Kopia danych

135 dupreg - do powielania istniejących segmentów. Algorytmdupreg /* powiela istniejący segment */ wejście:wsaźnik do pozycji w tablicy segmentów wyjście:wskaźnik do segmentu, który wyglada tak samo jak segment wejściowy { if (jest to segment dzielony) /* proces wołajacy zwiększy licznik odwołań do segmentu w kolejnych wywołaniach attachreg */ return(wskażnik do segmentu wejściowego); przydziel nowy segment (alg. allocreg); ustaw pomocnicze struktury do zarządzania pamięcią, analog. do struktury istniejących dla segmentu wejściowego; przydziel pamięć fizyczną na zawartość segmentu; skopiuj zawartość segmentu wejściowego do nowo przydzielonego; return(wskaźnik do przydzielonego segmentu); } 5. Struktura procesów 5. Struktura procesów MENU

136 Typowe warstwy kontekstu procesu w stanie uśpienia Wykonywanie w trybie użytkownika Wywołaj funkcję systemową Warstwa kontekstu jądra 1 Wykonaj funkcję systemową Zachowaj kontekst rejestru Poziom użytkownika Warstwa kontekstu jądra 1 Wykonaj funkcję systemową Zachowaj kontekst rejestru Poziom użytkownika Warstwa kontekstu jądra 2 Wykonaj kod zmiany kontekstu Zachowaj kontekst rejestru funkcji systemowej Warstwa kontekstu jądra 2 Wykonaj kod zmiany kontekstu Zachowaj kontekst rejestru funkcji systemowej Wywołaj algorytm sleep 5. Struktura procesów 5. Struktura procesów MENU

137 Procesy śpiące w oczekiwaniu na zajście zdarzenia i zdarzenia odwzorowane w adresy Proces a Proces b Proces c Proces d Proces e Proces f Proces g Proces h Adres A Adres B Adres C Oczekiwanie na zakończenie we-wy Czekanie na bufor Oczekiwanie na i węzeł Czekanie na wyjście z terminala 5. Struktura procesów 5. Struktura procesów MENU

138 Algorytm sleep wejście:(1) adres związany z zdarzeniem sleep (2) priorytet wyjście:1 jeśli proces zostaje obudzony w wyniku sygnału przechwyconego przez ten proces, algorytm longjmp, jeśli proces zostaje obudzony w wyniku sygnału, który nie został przechwycony przez proces, 0 w przeciwnym razie { podnieś poziom pracy procesora tak, by zablokować wszystkie przerwania; zaznacz stan procesu jako uspiony; umieść proces w kolejce mieszającej spiących procesów, zależnie od adresu zdarzenia; zachowaj adres zdarzenia w pozycji tablicy procesów; ustaw priorytet wejściowy jako poziom priorytetu procesu; if (spanie procesu nie jest przerwane) { przełącz kontekst; /* po obudzeniu procesu wznawia wykonanie w tym miejscu */ odtwórz poziom priorytetu procesora obowiazujący w chwili, gdy proces zasypiał, by dopuścić przerwania; return (0); } /* tutaj wówczas gdy spanie procesu może być przerwane przez sygnał */ if (nie nadszedł żaden sygnał dla procesu) { przełącz kontekst; /* po obudzeniu proces wznawia wykonanie w tym miejscu */ if (nie nadszedł żaden sygnał dla procesu) { odtwórz poziom priorytetu procesora obowiązujący w chwili, gdy proces zasypiał; return (0); } usuń proces z kolejki mieszającej procesów uśpionych, jeśli nadal tam jest; odtwórz poziom priorytetu procesora obowiązujący w chwili, gdy proces zasypiał; if (priorytet, z jakim śpi proces, dopuszcza przechwytywanie sygnału) return (1); wykonaj algorytm longjmp; } 5. Struktura procesów 5. Struktura procesów MENU

139 Algorytm wakeup algorytm wakeup wejście: adres związany ze zdarzeniem wyjście: brak { podniś poziom pracy procesora, tak by zablokować wszystkie przerwania; odszukaj kolejkę procesów uśpionych związanych z podanym adresem; for (każdy śpiący proces związany z podanym adresem) { usuń proces z kolejki mieszającej; zaznacz proces jako „gotowy do wykonania”; umieść proces na utrzymanej przez proces szeregujący liście procesów gotowych do wykonania; wyzeruj pole w pozycji tablicy procesów związane z podanym adresem; if (proces nie jest załadowany do pamięci) obudź proces wymiany (proces 0); else if (obudzony proces ma większe prawo do wykonania się niż bieżący proces wykonywany) ustaw znacznik procesu szeregującego; } odtwórz poprzedni poziom pracy; } 5. Struktura procesów 5. Struktura procesów MENU

140 Rozdział szósty – „Zarządzanie procesami” 2. Podręczna pamięć buforowa 2. Podręczna pamięć buforowa 6. Zarządzanie procesami 6. Zarządzanie procesami 3. Wewnętrzna reprezentacja plików 3. Wewnętrzna reprezentacja plików 4. Funkcje systemowe systemu plików 4. Funkcje systemowe systemu plików 5. Struktura procesów 5. Struktura procesów MENU 1. Wstęp 1. Wstęp

141 Funkcje systemowe do zarządzania procesami i ich związek z innymi algorytmami 6. Zarządzanie procesami 6. Zarządzanie procesami MENU Funkcje systemowe do zarządzania pamięcią Funkcje systemowe do synchronizacji Różne forkexecbrk exit dupreg attachreg detachreg allocreg attachreg growreg loadreg mapreg growreg detachreg wait signal kill setpgrp setuid

142 Algorytm fork algorytm fork wejście: brak wyjście: w procesie macierzystym PID potomka w procesie potomnym 0 { sprawdź dostępność zasobów jądra; pobierz wolną pozycję z tablicy procesów, unikatowy PID; sprawdź, czy użytkownik nie wykonuje zbyt wielu procesów; zaznacz, że potomek jest w stanie tworzony; skopiuj dane z pozycji w tabl. procesów związanym z procesem macierzystym do pozycji związanej z procesem potomnym; zwiększ licznik w i-węźle bieżącego katalogu i zmienionym korzeniu drzewa katalogów (jeśli zmieniano korzeń); zwiększ w tablicy plików licznik otwartych plików; utwórz w pamięci kopię kontekstu procesu macierzystego (u-obszar, instrukcje, dane, stos); wstaw pozorną warstwę kontekstu poziomu systemu na kontekst poziomu systemu potomka; pozorny kontekst zawiera dane umożliwiające potomkowi rozpoznanie się i rozpoczęcie wykonania od bieżącego miejsca po uzyskaniu sterownia; if (wykonany proces jest procesem macierzystym) { zmień stan potomka na “gotowy do wykonania”; return (ID potomka); /* od systemu do użytkowqnika */ } else /* wykonany proces jest procesem potonnum */ { zainicjuj w u-obszarze pola zawierające czas; return(0); } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

143 Algorytm fork – funkcja fork tworzy nowy proces potomny Stos użytkownika procesu macierzystego Dane procesu macierzystego Tablica segmentów procesu U-obszar Otwarte pliki Bieżący katalog Zmieniony katalog główny Stos jądra Stos użytkownika procesu potomnego Dane procesu potomnego Tablica segmentów procesu U-obszar Otwarte pliki Bieżący katalog Zmieniony katalog główny Stos jądra Współdzielone instrukcje Współdzielone instrukcje Tablica plików Tablica i -węzłów Proces potomny Proces macierzysty 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

144 Program, w którym proces macierzysty i potomny współdzielą dostęp do pliku # include int dpczyt, dppisz; char c; main (argc, argv) int argc; char *argv[]; { if (argc != 3) exit (1); if (( dpczty = open(argv(1), O_RDONLY)) == -1) exit (1); if ((dppisz= create(argv[2], 0666)) == -1) exit (1); fork(); /*oba procesy wykonują ten sam kod*/ czytpisz(); exit(0); } czytpisz() { for (;;) { if (read (dpczyt, &c, 1 ) !=1) return; write (dppisz, &c, 1) } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

145 Komunikacja między procesami przez potoki (użycie pipe, dup i fork) #include char napis[] = "hej tam, wszyscy"; main() { int licznik, i; int do_ojca[2], do_syna[2]; /*na łącza do ojca i syna*/ char buf[256]; pipe(do_ojca); pipe(do_syna); if (fork()==0) { /*tutaj wykonuje się proces potomny*/ close(0); /*zamknij stare standardowe wejście*/ dup(do_syna[0]); /*powiel koniec łącza do czyt na stand wej*/ close (1); /*zamknij stare stand wej*/ dup(do_ojca[1]); /*powiel koniec łącza do pis jako stand wyj */ close (do_ojca[1]); close (do_syna[0]); close (do_ojca[0]); close (do_syna[1]); for ( ; ; ) { if (( licznik = read(0,buf,sizeof(buf)) == 0 ) exit(); write(1,buf,licznik); } } /*tutaj wykonuje się proces macierzysty*/ close(1); dup (do_syna[1]); close(0); dup (do_syna[0]); close (do_syna[1]); close (do_ojca[0]); close (do_syna[0]); close (do_ojca[1]); for ( i=0 ; i<15 ; i++ ) { write (1,napis,strlen(napis)); read ( 0, buf, sizeof(buf)); } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

146 Sprawdzanie i obsługa sygnałów w diagramie stanów procesu 1 72 9 43 56 8 Wykonywany w trybie użytkownika Uśpiony poza pamięcią Gotowy do wykonania poza pamięcią Sprawdź i obsłuż sygnały Sprawdź wystąpienie sygnałów fork Utworzony za mało pamięci (tylko system wymiany) sprowadzenie do pamięci usunięcie z pamięci budzi się usunięcie z pamięci budzi się Uśpiony w pamięci Zombie zasypia wyjście uszereguj ponownie proces dość pamięci Gotowy do wykonania w pamięci Wywłaszczony wywłaszczenie Wykonywany w trybie jądra powrót do użytkownika wywołanie funkcji systemowej, przerwanie przerwanie, powrót z przerwania 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

147 Algorytm issig – rozpoznawanie sygnałów algorytm issig wejście : brak; wyjście : true, gdy proces otrzymał sygnały których nie ignoruje; false gdy proces otrzymał sygnały które ignoruje; { while (pole otrzymanych sygnałów w tabl. procesów różne od 0 ) { znajdź nr sygnału wysyłanego do procesu; if (sygnał śmierci potomka) { if (ignorowanie sygałów śmierci potomka) zwolnij w tablicy procesów pozycje potomków w stanie zombie; else if (przechwytywanie sygnałów śmierci potomka) return (true); } else if(nie ignorowanie sygnału) return (true); włącz bit sygnału w polu otrzymanych sygnałów w tabl procesów; } return (false); } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

148 Algorytm psig – obsługa sygnałów algorytm psig wejście : brak; wyjście : brak: { pobierz numer sygnału ustawiony w pozycji tablicy procesów: wyczyść numer sygnału w pozycji tablicy procesów; if (użytkownik wykonał wcześniej signal() i zażądał ignorowania tego sygnału) return; /*zrobione*/ if (użytkownik podał funkcję obsługi tego sygnału) { pobierz z u-obszaru adres wirtualny w przestrzeni użytkownika funkcji obsługi sygnału; /*następna instrukcja ma niepożądane efekty uboczne*/ wyczyść pozycję w u-obszarze przechowującą adres funkcji obsługi sygnału ; zmodyfikuj kontekst poziomu użytkownika; sztucznie utwórz zrąb stosu użytkownika by zasymulować wywołanie funkcji obsługi sygnału; zmodyfikuj kontekst poziomu systemu; wpisz adres funkcji obsługi sygnału do pola licznika rozkazów zachowanego przez użytkownika kontekstu rejestru; return; } if (sygnał jest takiego typu, że system powinien utworzyć ósemkowo obraz pamięci procesu) { utwórz w bieżącym katalogu plik o nazwie "core"; wpisz zawartość kontekstu poziomu użytkownika na plik "core"; } wykonaj natychmiast algorytm exit; } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

149 Program przechwytujący sygnały – kod źródłowy i deasemblacja programu #include main() { extern przechwyc(); signal (SIGINT, przechwyc); kill (0, SIGINT); } przechwyc() { } ***** VAX DISASSEMBLER ***** _main() e4: e6:pushab0x18(pc) ec:push1$0x2 # następny wiersz zawiera wywołanie signal ee:calls$0x2,0x23(pc) f5:pushl$0x2 f7:clrl-(sp) #następny wiersz zawiera wywołanie funkcji kill f9:calls$0x2,0x8(pc) 100:ret 101:halt 102:halt 103:halt _przechwyc() 104: 106:ret 107:halt _kill() 108: #następny wiersz zawiera instrukcję #przerwania systemowego 10a:chmk$0x25 10c:bgeeequ0x6 10e:jmp0x14(pc) 114:clrl 116:ret 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

150 Stos użytkownika i obszar zachowany przez jądro przed i po otrzymaniu sygnału Nowy zrąb sekwencji wywołującej Adres powrotu (10c) Warstwa 1 kontekstu jądra Zachowany obszar rejestrów Adres powrotu w procesie (10c) Zachowany przez użytkownika kontekst rejestru Stos użytkownika przed otrzymaniem sygnału Po Warstwa 1 kontekstu jądra Zachowany obszar rejestrów Adres powrotu w procesie (10c) Zachowany przez użytkownika kontekst rejestru Stos użytkownika przed otrzymaniem sygnału Przed Wierzchołek stosu użytkownika 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

151 Program demonstrujący wyścig między procesami podczas przechwytywania sygnałów # include przechwyć_sygnał() { printf („PID %d przechwyciłem jeden\n”, getpid()); /* wypisz ID procesu */ signal (SIGINT, przechwyć sygnał); } main() { int pid_ojca; signal (SIGINT, przechwyć sygnał); if (fork() == 0) { /* daj tyle czasu, by oba procesy mogły się zadomowić */ sleep (5); /* funkcja biblioteczna opóźniająca o 5 sekund */ pid_ojca = getpid();/* pobierz ID ojca */ for (;;) if (kill (pid_ojca, SIGINT) == -1) exit(); } /* obniż priorytet, zwiększając szansę na zademonstrowanie wyścigu między procesami */ nice (10); for (;;) ; } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

152 Związek między wartościami pid a zbiorami procesów  Jeśli pid jest liczbą całkowitą dodatnią, to jądro wysyła sygnał do procesu o identyfikatorze pid  Jeśli pid jest równy 0, to jądro wysyła sygnał do wszystkich procesów należących do tej samej grupy co proces wysyłający  Jeśli pid jest równy –1, to jądro wysyła sygnał do wszystkich procesów, których rzeczywisty identyfikator użytkownika równa się obowiązującemu identyfikatorowi użytkownika procesu wysyłającego. Jeśli obowiązujący identyfikator użytkownika procesu wysyłającego jest identyfikatorem nadzorcy, to jądro wysyła sygnał do wszystkich procesów z wyjątkiem procesu 0 i 1.  Jeśli pid jest liczbą ujemną różną od –1, to jądro wysyła sygnał do wszystkich procesów w grupie procesów o numerze równym absolutnej wartości pid. 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

153 Przykładowe użycie funkcji setpgrp # include main() { register int i; setpgrp(); for (i=0 ; i<10 ; i++ ) { if ( fork() ==0 ) { /*proces potomny*/ if ( i & 1 ) setpgrp(); printf("pid= %d pgrp= %d\n, getpid(), getpgrp()); pause(); /*fun systemowa zawieszająca wykonanie*/ } kill(0, SIGNT); } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

154 Algorytm exit algorytm exit wejście: kod powrotu dla procesu macierzystego wyjście: brak { ignoruj wszystkie sygnały; if (1ider grupy procesów związanej z terminalem sterującym) { wyślij sygnał zawieszenia do wszystkich członków grupy procesów; zmien wszystkim członkom numer grupy na 0; } zamknij wszystkie otwarte p1iki (wewnetrzna wersja algorytmu close); zwolnij bieżący katalog (algorytm iput) ; zwolnij bieżący (zmieniony) korzen, jeśli istnieje (algorytm iput) ; zwolnij segmenty, pamięć związaną z procesem (algorytm freereg) ; zapisz rekord rozliczeniowy; zanotuj, że proces jest w stanie zombie; uczyń proces init (1) procesem macierzystym wszystkich procesów potomnych; jeśli któreś z dzieci były w stanie zombie, to wyślij do init sygnał smierci potomka; wyślij sygnał śmierci potomka procesowi macierzystemu; przełącz kontekst; } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

155 Przykład programu wywołującego exit main() { int potomek; if ((potomek = fork()) == 0) { printf („PID potomka %d\n”, getpid()); pause();/* zawieś wykonanie aż do otrzymania sygnału */ } /* proces macierzysty */ printf („PID potomka %d\n”, potomek); exit (potomek); } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

156 Algorytm wait algorytm wait wejście: adres zmiennej na zapamiętanie kodu wyjścia potomka wyjście: identyfikator potomka, kod wyjścia potomka { if (czekający proces nie ma potomków) return (błąd) ; for (; ; ) /* wykonuj pętlę aż do wykonania return */ { if (czekający proces ma potomka w stanie zombie) { wybierz dowolnego potomka w stanie zombie; dodaj procesowi macierzystemu zużyty czas CPU potomka; zwolnij pozycję w tablicy procesów zajmowaną przez potomka; return (ID potomka, kod wyjścia potomka) ; } if (proces nie ma potomków) return (błąd) ; śpij z priorytetem dopuszczającym przerwania (oczekując na zdarzenie zakończenia wykonania procesu potomnego); } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

157 Przykład użycia wait i ignorowania sygnału śmierci potomka #include main (argc, argv) int argc; char *argv[]; { int i, przekazywany_kod, przekazywana_wartość; if (argc > 1) signal (SIGCLD, SIG_IGN);/* ignoruj śmierć potomków */ for (i=0; i < 15; i++) if (fork() == 0) { /* tutaj proces potomny */ printf („potomek %x\n”, getpid()); exit (i); } przekazywana_wartość = wait (&przekazywany_kod); printf („wait: przekazywana wartość: %x, przekazywany kod: %x\n”, przekazywana_wartość, przekazywany_kod); } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

158 Algorytm exec algorytm exec wejście:(1) nazwa pliku (2)lista parametrów (3)lista zmiennych środowiskowych wyjście:brak { weź i-węzeł pliku (algorytm namei); sprawdź czy plik wykonywalny i czy użytkownik ma prawo do wykonania; czytaj nagłówki pliku, sprawdź czy jest to moduł ładowalny; skopiuj parametry exec ze starej przestrzeni adresowej do systemowej; for (każdy segment dołączony do procesu) odłącz wszytskie stare segmenty (algorytm detach); for (każdy segment wyspecyfikowany w module ładowalnym) { przydziel nowe segmenty (algorytm allocreg); przyłącz segmenty (algorytm attachreg); załaduj segment do pamięci, jeśli należy (algorytm loadreg); } skopiuj parametry exec do nowego segmentu stosu użytkownika; specjalne przetwarzanie dla programów setuid, śledzenie; zainicjuj obszar na zachowanie rejestrów użytkownika w celu powrotu do trybu użytkownika; zwolnij i-węzeł pliku (algorytm iput); } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

159 Obraz pliku wykonywalnego Liczba magiczna Liczba sekcji Inicjalne wartości rejestrów Typ sekcji  Rozmiar sekcji  Adres wirtualny Dane (np. instrukcje) Dane Inne informacje Nagłówek podstawowy Nagłówek sekcji 1 Nagłówek sekcji 2 Nagłówek sekcji n Sekcja 1 Sekcja 2 Sekcja n 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

160 Przykład użycia funkcji exec main() { int status; if (fork() == 0) execl („/bin/date”, „date”, 0); wait (&status); } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

161 Przykład programu zamazującego swoje instrukcje #include main() { int i, *ip; extern f(), przechwyć_sygnał; ip = (int*) f;/* ip otrzymuje adres funkcji f */ for (i=0; i < 20; i++) signal (i, przechwyć_sygnał); *ip = 1;/* próba zamazania f */ printf („Po zamianie wartości *ip\n”); f(); } f() { } przechwyć_sygnał (n) int n; { printf („Przechwycono sygnał %d\n”, n); exit (1); } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

162 Algorytm xalloc – przydział segmentów instrukcji algorytm xalloc wejście: i-węzeł pliku wykonywalnego wyjście: brak { if (plik wykonywalny nie ma osobnego segmentu instrukcji) return; if (segment instrukcji związany z instrukcjami i-wezła) { /* segment instrukcji już istnieje, dołącz do niego */ załóż blokade na segment; while (zawartość segmentu nie jest jeszcze gotowa) { /* modyfikacja licznika odwołań zapobiega całkowitemu usunięciu segmentu*/ zwiększ licznik odwołań do segmentu; zdejmij blokadę z segmentu; śpij (zdarzenie: zawartość segmentu jest gotowa) ; załóż blokadę na segment; zmniejsz licznik odwołań do segmentu; } dołącz segment do procesu (algorytm attachreg) ; zdejmij blokade z segmentu; return; } /* nie ma takiego segmentu instrukcji --- utwórz go */ przydziel segment instrukcji (algorytm alłocreg) ; /*segment zablokowany*/ if (w trybie dostepu do i-węzła jest ustawiony bit lepkości) włacz znacznik lepkości segmentu; dołącz segment do adresu wirtualnego wskazanego przez nagłówek pliku związanego z i-węzłem (algorytm attachreg) ; if (plik specjalnie formatowany dla systemów ze stronicowaniem ) else /* nie formatowany dla systemów ze stronicowaniem */ skopiuj instrukcje pliku do segmentu (algorytm loadreg) ; zmień ochronę segmentu w tablicy segmentów procesu na "tylko do czytania"; zdejmij blokadę z segmentu; } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

163 Związek tablicy i-węzłów oraz tablicy segmentów w przypadku dzielonych instrukcji Tablica i-węzłów Tablica segmentów Możliwy scenariusz gdyby licznik odwołań do /bin/date mógł być równy 0 Wskaźnik do i-węzła w pamięci I-węzeł w pamięci dla /bin/date Segment instrukcji dla /bin/who Segment instrukcji dla /bin/date 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

164 Zmiana obowiązującego identyfikatora użytkownika - setuid() #include main() { int rzecz_id, obow_id, dp_mjb, dp_marek; rzecz_id = getuid(); /* rzeczywisty ident. użytkownika */ obow_id = geteuid(); /* obowiązujący ident. użytkownika */ printf („Rzeczywisty id: %d, obowiązujący id: %d”, recz_id, obow_id); dp_mjb = open („mjb”, O_RDONLY); dp_marek = open („marek”, O_RDONLY); printf („Deskryptory: mjb- %d, marek- %d”, dp_mjb, dp_marek); setuid (rzecz_id); printf („Po setuid(%d): rzeczywisty id: %d, obowiązujący id: %d”, rzecz_id, getuid(), geteuid()); dp_mjb = open („mjb”, O_RDONLY); dp_marek = open („marek”, O_RDONLY); printf („Deskryptory: mjb- %d, marek- %d”, dp_mjb, dp_marek); setuid (rzecz_id); printf („Po setuid(%d): rzeczywisty id: %d, obowiązujący id: %d”, obow_id, getuid(), geteuid()); } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

165 Zmiana obowiązującego identyfikatora użytkownika - setuid() – wyniki po wykonaniu programu rzecz_id = 5088, obow_id = 8319 dp_mjb = –1, dp_marek = 3 po setuid(5088): rzecz_id = 5088, obow_id = 5088 dp_mjb = 4, dp_marek = -1 po setuid(8319): rzecz_id = 5088, obow_id = 8319 mjb rzecz_id = 8319, obow_id = 8319 dp_mjb = -1, dp_marek = 3 po setuid(8319): rzecz_id = 8319, obow_id = 8319 dp_mjb = -1, dp_marek = 4 po setuid(8319): rzecz_id = 8319, obow_id = 8319 marek 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

166 Algorytm brk algorytm brk wejście: nowa wartość break wyjście: stara wartość break { załóż błokadę segmentu danych procesu; if (zwiększenie wielkości segmentu) if (nowa wielkość segmentu niepoprawna) { zdejmij blokade segmentu danych; return (błąd) ; } zmień wielkość segmentu (algorytm growreg) ; wyzeruj nową przestrzeń adresową; zdejmij blokadę segmentu danych procesu; } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

167 Zastosowanie funkcji brk #include char *wsk; int nr; main() { char *sbrk(); extern przechwyć(); signal (SIGSEGV, przechwyć); wsk = sbrk (0); printf („Początkowa wartość break: %u\n”, wsk); for (;;) *wsk++ = 1; } przechwyć (sygn) { nr++; printf („Odebrano sygnał %d; wywołanie nr %d: adres %u\n”, sygn, nr, wsk); sbrk (256); signal (SIGSEGV, przechwyć); } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

168 Zastosowanie funkcji brk – przykładowe wyniki działania programu początkowa wartość break 140924 przechwycony sygnał 11; wywołanie nr 1: adres 141312 przechwycony sygnał 11; wywołanie nr 2: adres 141312 przechwycony sygnał 11; wywołanie nr 3: adres 143360... (te same adresy wpisywane do 10-tego wywołania) przechwycony sygnał 11; wywołanie nr 10: adres 143360 przechwycony sygnał 11; wywołanie nr 11: adres 145408... (te same adresy wpisywane do 18-tego wywołania) przechwycony sygnał 11; wywołanie nr 18: adres 145408 przechwycony sygnał 11; wywołanie nr 19: adres 145408 początkowa wartość break 140924 przechwycony sygnał 11; wywołanie nr 1: adres 141312 przechwycony sygnał 11; wywołanie nr 2: adres 141312 przechwycony sygnał 11; wywołanie nr 3: adres 143360... (te same adresy wpisywane do 10-tego wywołania) przechwycony sygnał 11; wywołanie nr 10: adres 143360 przechwycony sygnał 11; wywołanie nr 11: adres 145408... (te same adresy wpisywane do 18-tego wywołania) przechwycony sygnał 11; wywołanie nr 18: adres 145408 przechwycony sygnał 11; wywołanie nr 19: adres 145408 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

169 Pętla główna interpretatora poleceń (część I) /* wczytaj wiersze polecenia do napotkania końca pliku */ while (read (stdin, bufor, lbajtów)) { /* rozbiór gramatyczny wiersza polecenia */ if ( /* wiersz polecenia zawiera & */ ) wtle = 1; else wtle = 0; /* polecenie nie należące do języka poleceń interpretatora */ if (fork() == 0) { /* zmiana przypisania wejścia-wyjścia? */ if (/* zmiana przypisania pliku wyjściowego */ ) { dp = creat (nowy_plik, maska); close (stdout); dup (dp); close (dp); /* zmiana przypisania stdout dokonana */ } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

170 Pętla główna interpretatora poleceń (część II) if ( /* łącze komunikacyjne */ ) { pipe (pdeskr); if (fork() == 0) { /* pierwsza składowa wiersza polecenia */ close (stdout); dup (pdeskr[1]); close (pdeskr[1]); close (pdeskr[0]); /* stdout przypisany do łącza */ /* polecenie wykona proces potomny */ execlp (polecenie1, polecenie1, 0); } /* druga składowa wiersza polecenia */ close (stdin); dup (pdeskr[0]); close (pdeskr[1]); close (pdeskr[0]); /* standardowe wejście z łącza komunikacyjnego */ } execve (polecenie2, polecenie2, 0); } /* proces macierzysty kontynuuje tutaj pracę... * czeka na zakończenie potomka, jeśli to konieczne */ if (wtle == 0) ident = wait (&stan); } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

171 Przykład interpretacji poleceń: zależność między procesami w ls –l | wc Inter- pretator ls -l wc wait exit read write 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

172 Algorytm start – ładowanie systemu algorytm start wejście: brak wyjście: brak { zainicjuj wszystkie struktury danych jadra; pseudo-montowanie systemu płików; recznie utwórz środowisko dla procesu o; utwórz proces 1 (fork) : { /* przetwarzanie - proces 1 */ przydziel segment; dołącz segment do przestrzeni adresowej; zwiększ wielkość segmentu, tak aby pomieścić kod; skopiuj kod z przestrzeni jądra do przestrzeni użytkowej ; zmień tryb jądra na tryb użytkownika; /* init nigdy tu nie dochodzi - rezultat zmiany trybu; * init wykonuje /etc/init i staje się "normałnym" * programem użytkowym pod wzgledem wykonywania * funkcji systemowych */ } /* proces o kontynuuje w tym miejscu */ utwórz procesy jądra; /* proces o wywołuje proces wymiany, zarządzający przydziałem * pamięci głównej oraz pomocniczej dla procesów; * pętla nieskończona; * proces o zwykle śpi, jeśłi nie ma pracy do wykonania*/ wykonaj algorytm wymiany; } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

173 Algorytm init algorytm init wejście: brak wyjście: brak { dp = open("/etc/inittab", o_RDONLY); while (wczytaj_wiersz(dp, bufor)) { /* wczytaj każdy wiersz pliku */ if (stan aktuałny != stan z bufora) continue; /* powrót do petli while */ /* stany zgodne */ if (fork() == 0) { execl("proces okreśłony w buforze"); exit(); } /* init nie czeka, lecz powraca do petli while */ } while ((ident = wait((int *) o)) != -l) { /* sprawdź, czy nie nastapiła śmierć utworzonego procesu, * rozważ moż1iwość ponownego utwórz*/ * w przeciwnym razie, po prostu pra uj da1ej*/ } 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

174 Przykładowy plik inittab Format: identyfikator, stan, akcja, specyfikacja procesu. Pola oddzielone dwukropkami. Komentarz na końcu wiersza poprzedzony znakiem #. co::respawn:/etc/getty console console# konsola u operatora 46:2:respawn:/etc/getty –t 60 tty46 4800H# tutaj komentarz Format: identyfikator, stan, akcja, specyfikacja procesu. Pola oddzielone dwukropkami. Komentarz na końcu wiersza poprzedzony znakiem #. co::respawn:/etc/getty console console# konsola u operatora 46:2:respawn:/etc/getty –t 60 tty46 4800H# tutaj komentarz 6. Zarządzanie procesami 6. Zarządzanie procesami MENU

175 Koniec http://kbogu.man.szczecin.pl Inne prezentacje znajdują się na stronie:


Pobierz ppt "Wydział Informatyki PS Akademickie Centrum Informatyki PS."

Podobne prezentacje


Reklamy Google