Systemy operacyjne II – skrót (na 4)
1969 – Bell Labs firmy AT&T mikrokomputery PDP-7 i PDP-9
Twórcy UNIXa: Ken Thompson, Dennis Ritchie
Wersje z sukcesem komercyjnym:
AIX (IBM)
SunOS, Solaris (Sun)
Ultrix (Compaq)
HP-UX (hp)
Xenix (Microsoft)
POSIX – Portable Operating System Interface, obejmuje interfejs programistyczny (API), interfejs
użytkownika (polecenia systemowe), właściwości powłoki system
Single UNIX Specification – inicjatywa The Open Group, mocno zbieżna z POSIX
UNIX cechy:
Projektowany na potrzeby badao
Tanie licencje
Mocne podstawy techniczne
UNIX – cechy charakterystyczne:
Bardziej złożone funkcje uzyskuje się ze złożenia mniej złożonych
Każdy program jest filtrem
Przenośnośd ponad efektywnośd
Prosty format plików ASCII
Kod wielokrotnego użycia
Skrypty
Prosty interfejs użytkownika
Raportowanie jeśli coś nie tak i tylko wtedy
Hierarchiczny system plików
Wielozadaniowośd i wieloużytkownikowośd
Komunikacja międzyprocesowa
Protokół TCP/IP
System operacyjny jest po to by ukryd obsługę sprzętu przed użytkownikiem i programami
użytkownika
Struktura systemu UNIX:
Użytkownik
Shell i narzędzia (programy)
Jądro
Sprzęt
Jądro dostaje od użytkownika (programu) wywołanie systemowe i podaje przerwanie do sprzętu.
Jądro odpowiedzialne jest za zarządzanie zasobami, współdzielenie użytkowników i zadao oraz
komunikację, jest warstwą ochronną pomiędzy programamio i sprzętem, kontroluje działanie
programów, urządzeo peryferyjnych.
Podsystemy jądra:
System plików (hierarchia katalogów, wiele systemów plików, wejścia/wyjścia)
Zarządzanie procesami
Cygwin (GPL) – implementacja POSIX dla Win32
Istnieje API języka C do wszystkich wywołao systemowych
W jądrze znajduje się:
Tabela procesów – zwiera wpis każdego procesu w systemie
Tabela otwartych plików – zawiera min. 1 wpis dla każdego otwartego pliku w systemie
Zbiór użytkowników tworzy grupę, użytkownicy mogą byd członkami wielu grup.
Każdy użytkownik należy do pierwotnej grupy (domyślnej).
Grupy i użytkownicy znajdują się w katalogach /etc/passwd i /etc/group
Hasła użytkownika przechowywane są w /etc/passwd i /etc/shadow, szyfrowanie kodem 7 bitowego
kodu ASCII, jest ono kluczem algorytmu DES. E-blok DES jest modyfikowany za pomocą 12 bitowej
wartości (ziarna) ustalanego na podstawie czasu aktualnego (zazwyczaj), algorytm jest wykonywany
na 64 bitowym bloku zer. Wyjście podawane jest na wejście kolejnej iteracji (25 iteracji). 64 bitowy
wynik transformowany jest na 11 znaków z alfabetu 64 znakowego (litery,cyfry, ‘.’ I ‘/’).
Uwierzytelnianie – udowadnianie tożsamości
Autoryzacja – sprawdzenie czy można wykonad operację
Mikrojądro – strukturalizacja systemu, w którym jądro zawiera minimalną ilośd programów
wbudowanych, pozwala na komunikację i minimalne zarządzanie procesami/zasobami, duże
możliwości personalizacji, bezpieczeostwo
Makrojądro – strukturalizacja systemu, w którym funkcje systemu są umieszczane w jądrze, a nie w
obszarze użytkownika (makrojądrem jest Linux/Windows)
Typy praw:
Read
Write
Execute
Zbiory uprawnieo:
Właściciela
Grupy
Pozostałych
Dla katalogu prawa wyglądają tak, że:
Read – może listowad zawartośd
Write może dodawad/usuwad pliki
Execute – może otwierad pliki
Efektywny UID i GID – UID i GID przypisane programowi wykonywanemu przez jądro, możliwe jeśli
pliki mają ustawione flagi setuid i set gid
Ścieżka bezwzględna – od katalogu głównego /
Ścieżka względna od bieżącego katalogu roboczego
Urządzenia w UNIXie są traktowane jak pliki, w systemie widoczne jako pliki specjalne
Każdy proces zawiera własną tablicę deskryptorów plików, jest indeksowana od 0, wpisy wskazują na
wpisy w tabeli otwartych plików.
Trzy pierwsze wpisy w tablicy deskryptorów są zarezerwowane dla standardowego wejścia (0),
standardowego wyjścia (1), wyjścia błędów (2) i domyślnie dotyczą terminala (/dev/tty).
Katalog hierarchiczny odpowiada systemowi plików na pojedynczym dysku, z którego ładowany jest
system, pozostałe podsystemy są montowane, czyli dołączane do istniejącego drzewa.
Wpisy w katalogach są dowiązaniami do pliku na dysku, dwa różne wpisy mogą byd dowiązaniami do
tego samego pliku.
Dowiązania symboliczne – „pliki” zawierające nazwę innego pliku, nie zmieniają liczby dowiązao do
pliku (informacja o pliku), pozwalają na wiązanie między różnymi systemami plikowymi.
Dowiązania sztywne (regularne) – umieszczona w systemie plików referencja na konkretny i-węzeł
W UNIXie wszystkie procesy są potomkami procesu init, procesy zwykle kooczą się po wywołaniu
exit, tworzone są poprzez wywołanie fork() lub vfork().
Procesy mogą byd w stanie:
Uśpiony
Zatrzymany
Wykonywany
Oczekujący
Zombie
Kontekst procesu to:
Przestrzeo adresową (kod, dane, stos, pamięd współdzieloną)
Informacje kontrolne (u-obszar, tablica procesów)
Dane uwierzytelniające
Zmienne środowiskowe
U-obszar – częśd przestrzeni użytkownika powyżej stosu, zwykle odwzorowany w ustalony adres,
zawiera informacje niezbędne podczas wykonywania procesu, może byd wymienialny
Tablica procesów Proc - zawiera informacje konieczne gdy proces nie wykonuje się, nie może byd
wymieniany.
U-obszar obejmuje:
Kontekst procesu
Wskaźnik w tablicy Proc
Rzeczywisty i efektywny ID
Argumenty, zwracane wartości, błędy wywołania
Informacje o sygnałach
Deskryptory
Bieżący katalog i korzeo
Tablica Proc zawiera:
ID procesu i grupy
Wskaźnik na U-obszar
Stan procesu
Wskaźnik na kolejki
Priorytet
Informacje zarządzania pamięcią
Flagi
Root ma UID i GID =0
Mechanizm blokowania: gdy nie są dostępne zasoby proces jest usypiany ( sleep() ), umieszcza się w
kolejce zablokowanych, gdy zasób jest zwalniany wywołuje się wakeup() dla wszystkich procesów,
przechodzą one w stan gotowy i kolejkowane.
Priorytety jądra 0-49
Priorytety użytkownika: 50-127
kill() – wysyłanie sygnałów
proces to wykonywana jednostka, program w trakcie wykonywania, czyli dane i kod w pamięci.
Obraz to komputerowe środowisko wykonywania programu, czyli zbioru bajtów przechowywanych w
pliku wykonywalnym.
fork() – tworzy nowy proces, kopiuje pamięd wirtualną, katalog roboczy i deskryptory, zwraca
wartośd PID potomka, procesowi potomnemu 0
exec() – rodzina programów zastępująca wykonywany kod innym
Efektywnie fork kopiuje dane dopiero po odwołaniu się do nich (przyspieszenie wykonania).
Rodzic gromadzi informacje o potomku poprzez funkcję wait, proces po wywołaniu jest w stanie
zombie, aż do wywołania wait przez rodzica.
Proces i ID:
ID procesu
ID grupy procesów
ID procesu rodzica
Efektywny UID i GID
Rzeczywisty UID i GID
Umask
Środowisko procesu to zbiór par nazwa-wartośd będących napisami.
Sygnał – wiadomośd międzyprocesowa, może byd specjalnie obsługiwana, domyślnie obsługiwana lub
ignorowana
Typowe sygnały:
Sigkill
Sigterm
Sigchld
Sigstop
Sigcont
signal() – ustawienie obsługi specjalnej dla sygnału
Łącza – wyjście jednego procesu jest wejściem innego
vi -r - wyświetla liste odnalezionych plików wymiany
vi:
^ - początek wiersza
$ koniec wiersza
/napis – wystąpienie napisu z prawej
dd – usuwa wiersz
ndd lub dnd – usuwa n wierszy
yy lub Y – kopiuje bieżący wiersz do bufora
p – wstawia wiersz z bufora
:set nu – numerowanie wierszy
:syntax on – podświetlenie składni
gcc – kompilator C
g++ kompilator C++
działanie gcc:
Preprocesorowanie
Kompilacja
Asemblacja
Konsolidacja
Opcje gcc:
-c – zatrzymuje po kompilacji lub asemblacji bez linkowania
-o – określa nazw
-D – ustawia macro
-g – informacje dla debugera
-I – dodaje katalog do przeszukiwania dla .h
-L – dodaje katalog do przeszukiwania dla bibliotek
-l… – dołączanie biblioteki
-Wall – ostrzeżenia dla wszystkich sytuacji niepolecanych
Makefile:
plik wykonuje się po podaniu polecenia make, służy do kompilacji złożonych projektów
konstrukcja w postaci:
cel : zależności
<Tab>reguła
% zastępuje dowolny ciąg
wildcard – dowolna nazwa
Debugowanie GDB:
gcc –g plik.c –o output
gdb output / gdb output 12345 (pid procesu)/ gdb output core.2957 (zrzut pamięci)
W samym GDB:
run arglist
set args arglist
b [file:] line – ustawia breakpoint
b [file:] func – ustawia breakpoint na funkcję
clear – czyści breakpoint kolejny lub wyspecyfikowany
delete – czyści wszystkie break pointy
c – kontynuuj
s – pojedynczy krok
Zmienne środowiskowe:
#include …
extern char ** environ;
int main…
Biblioteki:
statyczna:
o gcc -c libname.c
o ar cr libname.a libname.o
o #include libname.h
o gcc program.c -o output –L. –lname
współdzielona:
o gcc -shared -fPIC – o libname.so obj.o
o gcc program.c -o output –L. –lname \ -Wl, -rpath,.
Współdzielona ładowana dynamicznie:
o gcc -shared -fPIC – o libname.so obj.o
o w programie używamy funkcji:
void *dlopen(plik,tryb)
dlclose(handle)
char *dlerror()
void *dlsym(handle,func_name)
LD_LIBRARY_PATH – zmienna pozwalająca na zmianę katalogów przeszukiwania dla bibliotek
Proces – egzemplarz wykonywanego programu
Porces!=wątek
Proces posiada własną przestrzeo adresową, wątki posiadają wspólna sekcję danych
Kontekst procesu:
Pid, gpid,uid,gid
Środowisko
Katalog roboczy
Kod programu
Rejestry
Stos
Sterta
Deskryptory
Akcje sygnałów
Biblioteki współdzielone
Narzędzia komunikacji międzyprocesowej (np. IPC)
Informacje kontrolne (u-obszar, tablica procesów proc)
Procesy tworzy się za pomocą fork() lub vfork()
Procesy zwykle kooczą się po wywołaniu exit()
Init – proces po którym wszystkie procesy „dziedziczą”
Algorytm planowania w Linuksie to algorytm planowania round-robin z wywłaszczeniami, w którym
każdy proces posiada przyczeilony i ustalony kwant czasu
Umask – działa na zasadzie, że od podanych praw odejmuje się jego wartośd
getpid() – pid naszego procesu
getppid() – pid procesu macierzystego
getuid/geteuid – uid/efektywny uid procesu
getgid/getegid – gid/efektywny gid procesu
Proces potomny dziedziczy po macierzystym:
uid, euid, gid, egid
deskryptory i pozycje
identyfikatory sesji, terminal sterujący, sygnalizatory ustanowienia id usera i grupy, bieżący
katalog roboczy, katalog główny, maskę tworzenia plików
maskę sygnałów oraz obsługę
sygnalizator zamykania (close-on-exec)
środowisko
segment pamięci wspólnej
ograniczenia zasobów systemowych
Potomek nie dziedziczy blokad plików, ma zerowane zbiory zaległych sygnałów oraz wartości czasów.
int atexit(void (*func)(void)) – rejestruje funkcje do wywołania po exit, wywołanie w odwrotnej
kolejności
pid_t wait(int *status) – czeka na któregoś z potomków
pid_t waitpid(pid_t pid, int *status, int options) – czeka na zakooczenie potomka pid, jeśli pid=-1 to
na dowolny, jeśli 0 to na każdy który ma gpid taki sam, >0 na konkretny <-1 na konkretny o pid=|pid|
Procesy zombie są adoptowane przez proces init.
kill(pid,signal) – wysyłanie sygnału
sighandler_t signal(signum,sighandler_t) – ustawia nowy sposób obsługi sygnału, zwraca poprzedni
Sygnały SIGKILL i SIGSTOP nie mogą byd ani przechwycone ani zignorowane.
Sigaction – zmiana obsługi sygnału, do tego struktura o tej samej nazwie
Sigprocmask – zmienia maskę blokowanych sygnałów (ustawiamy na te które mają byd blokowane
lub te które nie mają byd)
Sigemptyset – pusty zbiór sygnałów
Sigfillset – kompletny zbiór sygnalów
Sigaddset – dodaje do zbioru
Sigdellset – usuwa ze zbioru
Sigismember – sprawdza czy w zbiorze
Wątek – jednostka wykonawcza w obrębie jednego procesu, jest ciągiem instrukcji wykonywanych
na tych samych danych, wątki działają na wspólnych zasobach procesu, duplikują jedynie to co jest im
potrzebne, dysponują własnymi kopiami:
wskaźnika na stos
rejestrów
inf. dot. planowania
zestawów sygnałów
danych wątku
Z współdzielenia zasobów wynika:
wskaźniki o tej samej wartości wskazują na te same dane
zmiany dokonywane przez jeden wątek widziane przez inne
wymuszanie jawne stosowanie synchronizacji
Wątki poziomu użytkownika same zarządzają wykonaniem, wątek rezygnuje z czasu procesora
poprzez bezpośrednie wywołanie żądania wymiany albo odebranie sygnału zegara systemowego.
Wątki poziomu jądra implementowane przez dołączanie do procesu tabeli wątków, system zarządza
wątkami z wykorzystaniem kwantów czasu, brak kradzenia czasu przez zachłanny wątek i blokowania
operacji I/O
clone() – funkcja tworzy nowy proces, pozwoli procesom potomnym współdzielid kontekst wykonania
(obszar pamięci, tablica deskryptorów, sygnały).
pthread – wątek Linuksa dla C w postaci pthread.h i biblioteki pthread
Wątki są zdecydowanie bardziej wydajne niż procesy tworzone fork().
Wątki stosuje się jeśli zadania im stawiane mogą byd wykonywane niezależnie w dużym stopniu.
Wszystkie wątki mają dostęp do globalnej pamięci procesu, mogą mied własne prywatne dane.
pthread_mutex_ - Miteksy
pthread_attr_ - obiekty atrybutów wątków
pthread_create – tworzy wątek
pthread_exit – kooczy wątek
pthread_join – czeka na zakooczenie wątku podanego parametrem (wątek musi byd dołączalny),
tylko jeden wątek może czekad na dany inny wątek, jest punktem anulowania
pthread_self – zwraca id wątku
pthread_equal – sprawdza czy id1 i id2 odnoszą się do tego samego wątku (return >0)
pthread_detach – odłącz wątek od macierzystego
pthread_cancel – przerywa działanie wątku wskazanego ( anulowanie synchroniczne – do punktu
anulowania/asynchroniczne – w każdej chwili)
Muteksy – rodzaj semaforów binarnych, może byd zablokowany (wart. 1) lub odblokowany (wart. 0),
muteks może byd odblokowany tylko przez wątek który go zablokował, teoretycznie mogą byd
rekurencyjne.
pthread_mutex_init – inicjalizacja Miteksu
pthread_mutex_destroy – niszczy muteks
pthread_mutex_lock – funkcja zajmuje muteks (jeśli zajęty to czeka)
pthread_mutex_trylock – sprawdzenie stanu Miteksu
pthread_mutex_unlock – odblokowanie Miteksu
Każdy obiekt IPC ma określony identyfikator i klucz (32 bity nieujemna rzeczywista), identyfikator
przydzielany podczas otwierania, jak deskryptor, klucz jest „nazwą” zasobu, na podstawie którego
uzyskuje się identyfikator, dostęp jest kontrolowany jak dla plików.
Kolejki komunikatów – umożliwiają przesyłanie pakietów danych pomiędzy procesami (komunikaty
zawierają treśd z długością i typ), odbiorca może czekad na dowolny komunikat lub na komunikat
określonego typu, komunikaty są przechowywane aż do odebrania lub usunięcia kolejki.
msgget() – zwraca id kolejki lub tworzy nową
msgctl() – wykonuje operacje na kolejce: IPC_STAT (kopiowanie inf. Ze struktury), IPC_SET (zapis
wartości), IPC_RMID (usunięcie kolejki i struktur danych)
msgsnd() – wysyła komunikat
msgrcv() – funkcja czyta z kolejki, jeśli msgtyp jest 0 to czytany pierwszy dostępny, jeśli > 0 to
komunikat danego typu, jeśli <0 to pierwszy o najniższym numerze <= wartości bezwgl. z msgtyp
ftok() – zwraca unikalny klucz
semafory – struktury danych użytkowane wspólnie przez kilka procesów, stosowane najczęściej do
synchronizowania działania kilu procesów korzystających ze wspólnego zasobu, podstawowym
rodzajem semafora jest semafor binarny, przyjmujący dwa stany opuszczony (P) i podniesiony (V).
Są dwa podejścia do semaforów:
1
o Opuszczony ma wartośd 0
o Podniesiony ma wartośd >0
2
o Opuszczony ma wartośd >0
o Podniesiony ma wartośd =0
semget() – zwraca id zestawu semaforów lub tworzy taki zestaw
semctl() – wykonuje operacje sterujące na zestawie semaforów
sepom() – wykonanie operacji semaforowej (na jednym lub więcej semaforze), sem_op zawiera
wartośd która zostanie dodana do semafora, jeśli któraś z funkcji sops nie zostanie wykonana to
zablokowanie procesu i nie wykonanie wszystkich operacji.
Pamięd współdzielona – specjalnie utworzony segment wirtualnej przestrzeni adresowej, do którego
dostęp ma wiele procesów, pierwszy proces tworzy taki segment, następnie dowiązuje go powodując
odwzorowanie w obszar danych i może dalej zapisywad dane, inne procesy mogą już czytad/pisad.
shmget() – tworzy segment pamięci współdzielonej i umożliwia dostęp do segmentu
shmctl – odpowiednik msgctl
*shmat() – funkcja dołącza segment pamięci wspólnej do przestrzeni adresowej procesu, zwraca
adres odwzorowania
shmdt() – wyłącza segment z przestrzeni adresowej procesu
fread() – nakładka na funkcję systemową read()
open() – przekształca ścieżkę na deskryptor pliku
creat() – open() z flagami O_WRONLY|O_CREAT|O_TRUNC (O_TRUNC – obcięcie do zerowej
długości)
flagi:
O_RDONLY
O_WRONLY
O_RDWR
O_APPEND – do dopisywania
Parametry mode S_I*:
R – read
W – write
X – execute
USR – user
GRP – group
OTH – other
read() – czyta z deskryptora do bufora
write() – pisze z bufora do deskryptora
lseek() – przesuwa się po deskryptorze
Przy dużych plikach efektywny jest zapis/odczyt paczkami będącymi wielokrotnościami bloków
dyskowych w systemie plików.
unlink() – usuwa nazwę z systemu plików (zmniejsza licznik dowiązao sztywnych i-węzła), jeśli jest to
ostatni deskryptor, a coś czyta to zaznaczany do usunięcia
remove() – odwołuje się bezpośrednio do unlink dla plików i do rmdir dla katalogów
fcntl() – dokonuje jednej z wielu różnych operacji na deskryptorze, np. F_GETFD lub F_SETFD
(sprawdzenie/ustawienie bitu FD_CLOEXEC czyli co ma byd zrobione z plikiem po wykonaniu exec),
F_NOTIFY (powiadamianie o modyfikacji katalogu/plików), *LEASE (pobranie/ustawienie dzierżawy)
Jeśli w prawach pliku zamiast x jest s w części usera/grupy to proces przyjmuje identyfikator
właściciela programu, jeśli zamiast x jest t w części others to program nie jest zwalniany z pamięci
(przestarzałe, nazywane bitem lepkości)
access() – sprawdza czy proces może czytad/pisad/wykonywad i sprawdzad istnienie pliku,
sprawdzanie poprzez maski R_OK W_OK X_OK i F_OK, jeśli ok to zwracane 0
chmod() – zmiana praw dostępu
chown() – zmiana właściciela (jeśli któryś na -1 to nie będzie zmian), zmieniad może tylko SuperUser
dowiązanie sztywne – nowa nazwa dla istniejącego pliku, nie można powiedzied które jest oryginalne,
ma te same prawa i właścicielstwo, nie może odnosid się do katalogów i różnych systemów plików
dowiązanie symboliczne – plik zawierający łaocuch z nazwą pliku na który wskazuje, może byd
stosowany do katalogów, są interpretowane w trakcie działania, może zawierad fragmenty ścieżki
względnej, może wskazywad na istniejący lub nieistniejący plik, nie można nadpisad istniejącego
dowiązania, prawa są nieistotne
link() – tworzy dowiązanie twarde
symlink() – tworzy dowiązanie symboliczne
stat()/fstat() – zwraca informacje o podanym pliku, nie są konieczne prawa dostępu do pliku, w
przypadku stat konieczne są prawa przeszukiwania do katalogów po kolei.
Makra do plików:
S_ISREG
S_ISDIR
S_ISCHR – urządzenie znakowe
S_ISBLK – urządzenie blokowe
S_ISFIFO
S_ISLNK
S_ISSOCK
Katalog to plik zawierający listę i-węzłów i nazw plików
mkdir() – tworzy katalog
rmdir() – usuwa katalog (pusty!)
opendir() – otwiera katalog
closedir() – zamyka katalog
readdir() – czyta katalog
rewinddir() – powraca do początku katalogu
chdir() – zmienia katalog bieżący
getcwd() – kopiuje nazwę bieżącego katalogu do bufora
scandir() – skanuje katalog wywołując funkcję filter() dla każdego katalogu (zdefiniowaną przez
użytkownika), następnie dla wartości >0 z filter wywoływana jest funkcja porównująca compar()
(zdefiniowana przez użytkownika) i umieszczane w tablicy namelist
alphasort/versionsort – funkcje porównujące do compar()
ftw() – przechodzenie drzewa katalogu wywołując funkcję fn dla każdego wpisu
Potoki:
Nazwane (kolejki FIFO), dostępne dla różnych procesów
Nienazwane, dostępne dla bezpośrednio spokrewnionych procesów
pipe() – funkcja tworzy potok nienazwany, pod filedes[0] jest odczyt, pod filedes[1] jest zapis
z potoków czytamy/piszemy jak ze zwykłych plików
close() – można zamknąd odczyt/zapis z potoku
fcntl(filedes, F_SETFL, O_NONBLOCK) – zmiana zachowania w przypadku przepełnionego potoku i
pustego (normalnie blokowanie)
mkfifo() – tworzy potok nazwany
mmap() – odwzorowuje w pamięci plik, mapowanie pliku do pamięci
munmap() – kooczy odwzorowanie plików w pamięci
memcpy() – kopiuje między mapowanymi plikami w pamięci
Systemy plików w Linux (według kolejności powstania i używania):
Minix do 64MB, nazwy 14 znaków
Ext do 2GB, nazwy 255 znaków, listy do zarządzania wolnymi blokami, brak rozróżnienia na
czas dostępu, modyfikacji i tworzenia
Ext2 do 16384GB, rozmiar pliku do 2048 GB, automatyczne rozpoznawanie uszkodzeo
(lost+found)
Ext3 obsługa księgowania, brak odzyskiwania plików
Ext4 obsługa woluminu do 1024PB, mniejsza fragmentacja
EXT2
System składa się z wielu grup bloków dyskowych, jeden blok jest uważany za podstawową jednostkę
objętościową danych.
Wielkośd bloku jest stała w ramach całego systemu plików (1024:4096 bajtów).
Pierwszy blok każdej partycji jest zarezerwowany na sektor ładowania danej partycji i nei jest
zarządzany przez system plików tej partycji. Następne bloki są blokami obsługiwanymi przez system
plików partycji, w przypadku EXT2:
Superblok – zawiera kluczowe informacje o dysku i formacie danych (liczba i-węzłów i bloków na
dysku, liczba wolnych), we wszystkich grupach ma tą samą wartośd
Deskryptor grup – zawiera informacje o miejscach w których zaczynają się pozostałe części grup i
liczbie wolnych i-węzłów i bloków w grupach, taki sam we wszystkich grupach
Bitmapa bloków – obszar 1 bloku dyskowego, tablica bitowa zawierająca mapę zajętości bloków w
grupie
Bitmapa i-węzłów – 1 blok dyskowy, tablica bitowa zawierająca mapę zajętości i-węzłów w grupie
Tablica i-węzłów – obszar na dysku zawierający i-węzły danej grupy
Bloki danych – dane właściwe w blokach
Struktury mogą zajmowad więcej niż jeden blok.
Jądro systemu korzysta z superbloku i deskryptorów grupy znajdujących się w zerowej grupie bloków
e2fsck – program badający spójnośd systemu pliku, odwołuje się do grupy zerowej i kopiuje w
pozostałych blokach
liczba grup bloków zależy od rozmiaru partycji i wielkości bloku
liczba grup bloków w przybliżeniu = s/(8*b)
s – rozmiar partycji w blokach
b – rozmiar bloku w bajtach
Rozmiar partycji w EXT2 – 8GB, rozmiar bloku 4KB
4KB bitmapa bloku więc 4K*8=32K bloków danych
32K bloków *4KB blok = 128MB rozmiar grupy
8*1024 rozmiar partycji / 128 = 64 grupy bloków
Superblok zawiera masę informacji, jakieś flagi, czasy sprawdzania, montowania, liczbę montowao,
rozmiar systemu plików w blokach, liczbę i-węzłów, rozmiar bloku i wiele wiele więcej.
s_log_block_size – wyraża rozmiar bloku jako potęgę 2, przy czym jednostką jest 1024 bajty
s_state – 0 jeśli zamontowany albo niewłaściwie odmontowany, 1 odmontowany, 2 zawiera błędy
i-węzeł:
Typ pliku
Rozmiar pliku w bajtach
Identyfikator usera/grupy
Czasy
Ilośd dowiązao
Lista kontroli dostępu
Liczba bloków w pliku
Adres fragmentu
Tablica opisu bloków pliku zawiera adresy bloków reprezentujących plik (i_block)
Tablica i-węzłów – składa się z ciągu sąsiadujących bloków zawierających określoną liczbę i-węzłów
Każdy i-węzeł ma rozmiar 128 bajtów
Numer i-węzła jest jednoznacznie określony przez jego położenie na dysku, np. węzeł numer 13021
to 733eci wpis w tablicy trzeciej grupy bloków (reszta z dzielenia modulo przez rozmiar bloku numer
grupy to częśd całkowita z dzielenia)
Rozmiar pliku w bajtach może byd różny od rozmiaru obliczanego na podstawie zajętych bloków
(niepełne wypełnienie bloków)
W i-węzłach jest zmienna i_mode 2bajtowa, zawieraona 4 bity typu pliku, 3 bity modyfikatorów (s i t
w prawach) oraz 9 bitów praw dostępu
Dla dowiązao symbolicznych jeśli ścieżka jest krótsza niż 60 znaków to jest przechowywana w i_block
Pliki urządzeo, potoki i gniazda nie posiadają bloków danych, informacje w i-węzłach
Katalogi to pliki zawierające w blokach wiązania nazw i i-węzłów.
Dla zwiększenia wydajności większośd struktur kopiowana jest do pamięci, jeśli caching mode jest
fixed limit to ograniczona ilośd struktur może byd w pamięci, jeśli dynamic, to struktura jest
przechowywana tak długo jak jest używany obiekt.
mke2fs – program do formatowania
Formatowanie polega na:
1. Inicjalizacji superbloku i deskryptora grup
2. Dla każdej grupy bloków rezerwuje się bloki dla superbloku, deskryptora, tablicy i-węzłów i
bitmap
3. Inicjalizacja bitmap
4. Inicjalizacja tablic i-węzłów
5. Utworzenie katalogu / (głównego)
6. Utworzenie katalogu lost+found
7. Aktualizacja bitmap
Obliczanie numerów bloków:
Direct – to musi byd podane (jak nie to jednak jest ich 12 :D)
b – wielkośd bloku w bajtach
a – wielkośd adresu bloków w bajtach
1-indirect: direct ÷ b/a+direct-1
2-indirect: 1-indirect ÷ (b/a)
2
+b/a+direct-1
3-indirect: 2-indirect ÷ (b/a)
3
+(b/a)
2
+b/a+direct-1
Jeśli liczymy ile danych dla poszczególnych adresowao to liczymy to co po ÷ i dodajemy 1 (bo od zera
numerowane).
ext2_new_inode()-alokacja i-węzła
ext2_free_inode() – zwolnienie i-węzła
ext2_get_block() – alokacja bloku
ext2_free_blocks() – zwolnienie bloku
Jeśli tworzymy nowy i-węzeł dla katalogu to wybierane jest miejsce z największą liczbą wolnych
bloków, jeśli nie jest katalogiem to szukanie w grupie blisko danego katalogu, jeśli brak to
poszukiwanie z algorytmem quadratic hash, jeśli dalej nic to liniowo.
Mechanizm księgowania polega na tym, że dane są najpierw zapisywane w dzienniku/kronice przed
zapisem na dysk, dzięki temu zmniejsza się prawdopodobieostwo uszkodzenia systemu plików.
W EXT3 do wyboru tryb księgowania:
Journal – zapisywane metadane i zwykłe dane
Ordered – księgowane metadane (domyślny)
Writeback – księgowane metadane z możliwością modyfikacji danych do których się one
odnoszą
VFS – wirtualny system plików
System plików Linuksa wygląda jak hierarchiczne drzewo katalogów.
VFS jest warstwą abstrakcji dostarczającą jednolity interfejs dla wszystkich systemów plików
zamontowanych w systemie.
Klasy systemów obsługiwane przez VFS:
Dyskowe systemy plików (EXT,System V, BSD, VFAT,NTFS, ISO9660 i inne)
Sieciowe systemy plików (NFS, Coda, SMB, NCP)
Specjalne systemy plików, tj. systemy wirtualne np. system plików /proc do zawartości
struktur jądra
VFS oparty na obiektowości, dwie składowe:
Zbiór definicji
o Obiekt super bloku (zamontowany system plików)
o Obiekt i-węzła (info o pliku)
o Obiekt pliku (powiązanie plik – proces)
o Obiekt pozycji w katalogu (pozycja w katalogu – plik)
Warstwa oprogramowania do działao na obiektach
Obiekty tego samego pliku są wiązane listami głównie dwukierunkowymi.
Każdy obiekt ma powiązania z metodami w postaci wskaźników.
W superbloku VFS:
s_list – lista zamontowanych systemów plików
s_dev – urządzenie na którym jest ten system
s_dirty – lista zmodyfikowanych i-węzłów
…
W systemie istnieje tablica mieszająca i-węzłów, dostęp do początku listy przez zmienną
inode_hashtable (lista kolizji łączona za pomocą pola i_hash)
Każdy i-węzeł znajduje się na jednej z trzech list:
Używane
Nieużywane
Zmodyfikowane (brudne)
Obiekt plikowy VFS znajduje się na jednej z kilku list:
Obiektów nieużywanych
Obiektów w użyciu
Obiektów do otwarcia
Wpis katalogu VFS:
Zawiera informacje o odwzorowaniach nazw w i-węzły
Umożliwia dekodowanie opisu drzewa
Ostatnio udostępniony i zwolniony zapis w katalogu jest przechowywany w pamięci podręczenj
(dentry cache).
W strukturze dentry są pola:
d_inode – wsk na i-węzeł
d_parent – katalog rodzica
d_subdirs – lista podkatalogów
d_hash, d_lru, d_child – powiązanie z innymi listami
d_op – metody zapisu (wskaźnik)
d_count, d_flags – użycia
Do szybkiego dostępu do katalogów korzysta się z tablic mieszających na podstawie nazw katalogów,
lista kolizji w d_hash, lista wolnych wpisów w d_lru, lista aliasów w d_alias
W systemie są dwie listy LRU podręcznej pamięci buforowej zapisów w katalogach:
pierwszego poziomu – odczytywane z dysku dane katalogowe (np. ls)
drugiego poziomu – pozycje których używamy najczęściej (np. cat, wc)
Elementy najczęściej używane na koocach list.
Proces posiada dwa pliki powiązane:
pole struct fs_struct *fs – z dowiązaniem do bieżącego katalogu oraz korzenia systemu
pole files_struct *files – tablica deskryptorów, pole fd na pierwsze 32 otwarte pliki
W jądrze systemu znajduje się lista wbudowanych lub załadowanych modułów systemów plikowych.
Struktura obsługująca informacje o systemie plikó - file_system_type:
name – nazwa
read_super – funkcja czytająca superblok
owner – moduł implementacji określonego typu systemu plików
fs_flags – flagi, m.in. czy wymaga urządzenia rzeczywistego
fs_supers – lista superbloków
next – wskaźnik na następny zamontowany system
Na pierwszy element listy zarejestrowanych plików wskazuje file_systems
Rejestrowanie modułu – odbywa się podczas dynamicznego łączenia modułu za pomocą
init_module():
wskazanie/napisanie funkcje read_super
alokacja pamięci na obiekt określający typ systemu plików
wywołanie rejestracji register_filesystem
cleanup_module – usuwanie modułu
Wszystkie zamontowane systemy plików są zawarte w liście składającej się ze struktur vfsmount:
mnt_dev – numer urządzenia
mnt_devname – nazwa urządzenia
mnt_dirname – punkt montowania
mnt_flags – flagi urządzenia
mnt_sb – wskaźnik na superblok
mnt_dquot - opcje dysku
mnt_next – następny element
Dostęp za pomocą zmiennej vfsmntlist
Przykład montowania (modyfikacja również dentry):