UXP – zima 2015-2016, Grzegorz Blinowski

UXP1A Unix – Programowanie i Architektura zima 2015-2016

Grzegorz Blinowski Instytut Informatyki Politechniki Warszawskiej

UXP – zima 2015-2016, Grzegorz Blinowski

Regulamin, itp. •

Zasady ogólne: – Tryb zaliczenia – oceny są wystawione najpóźniej ostatniego dnia zajęć (przed rozpoczęciem sesji letniej), – 50 p. Projekt, 50 p. kolokwia, 50 p. do zaliczenia przedmiotu – Projekt i kolokwia niezbędne do zaliczenia - min. 25 p. za kolokwia, min. 25 p. za projekt – nie przewiduje się poprawkowego kolokwium – poprawka indywidualne rozmowy – Kolokwium – 1 godz. lekcyjna, bez notatek



Projekt: – Projekt rusza po c.a. 1 mies. wykładów – Zespoły 4-o osobowe, – propozycja własnych projektów - bez sztampowych rozwiązań – ujemne punkty za znaczne opóźnienie – Projekt wstępny - na papierze i projekt zasadniczy: demo + obszerna dokumentacja – Szczegółowe wymagania podane przy rozdawaniu zadań

UXP – zima 2015-2016, Grzegorz Blinowski

Regulamin itp. •

Inne – Wolne czwartki: 24/12, 31/12 – Kolokiwum I – po omówieniu mechanizmów IPC – Kolokiwum II – po omówieniu całości materiału (21.01 - ?) – Oceny, wpisy, poprawa 28.01 (ostatnie zajęcia) – Projekt: start ok. połowy listopada, zaliczenie do 21.01



Wymagania – Systemy operacyjne – Dobra znajomość języka C



Materiały – dostępne na stronie http://www.ii.pw.edu.pl/~gjb



Kontakt: [email protected], tel PW: 222347184; konsultacje wt. 10-12

UXP – zima 2015-2016, Grzegorz Blinowski

Literatura •

W. Richard Stevens, Advanced Programming in the UNIX Environment



Uresh Vahalia, Jadro systemu UNIX, WNT; 2001



Berny Goodhear, James Cox, Sekrety magicznego ogrodu UNIX System V Wersja 4 od środka (podręcznik), WNT 2001 Marc Rochkind, Programowanie w systemie Unix dla zawansowanych, WNT (wyd. 2; 2005) David R. Butenhof, Programming with Posix Threads, Addison-Wesley, 1997 Daniel P. Bovet, Marco Cesati, LINUX kernel, Wydawnictwo RM (O’Reilly) 2001 M. Bach, Budowa systemu operacyjnego Unix, WNT 1996

• • • •

UXP – zima 2015-2016, Grzegorz Blinowski

Plan wykładów • Historia, Standardy • Procesy • Sygnały • Pliki - podstawy • Komunikacja IPC (potoki, FIFO, SYSV IPC) • Kolokwium nr 1 • Pliki – cd, zajmowanie plików i rekordów • VFS; systemy plików: UFS, Procfs/specfs, NFS (i RPC) • VM • Wątki •XTI (?) • boot / init • Kolokwium nr 2

UXP – zima 2015-2016, Grzegorz Blinowski

Historia • 1965-1969: GE&MIT&Bell Labs - MULTICS • 1969: Ken Thompson, Dennis Ritchie (Bell Labs): gra "Space Travel", komputer GE-645 • 1969: PDP-7 (Bell): środowisko systemu plików, obsługa procesow, 2 użytkowników -> PDP-11 • UNICS -> UNIX Brian Kernighan; pierwszy użytkownik - wydz. patentowy Bell Labs. • 1971: UNIX First Edition • 1972: język B; 1973 - język C (Thomson & Ritchie) • 1974 - artykuł o Unix-ie w Comm. of the ACM

UXP – zima 2015-2016, Grzegorz Blinowski

PDP-7, PDP-11

• Architektura: 18 bit • RAM: 4 Kw - słów 18b (9KB) • RAM maks: 64 Kw (144 KB) • Cykl zegara 1.75 us (0,571 MHz) • Peryferia: klawiatura/drukarka, taśma papierowa, taśma magentyczna • Koszt: ok 72 K USD

UXP – zima 2015-2016, Grzegorz Blinowski

Historia c.a. • 1975 -> Edycja 6 - V6 - pierwsza edycja używana poza Bell Labs • 1976: Ritchie - stdio • 1975-76 pierwsza wersja przeniesiona na inną maszynę niż PDP • 1979 - edycja v7 (kompilator C, sh) • 1978 - BSD (bazuje na v6) - Bill Joy, komputery VAX11 (32 bit); pierwsza implementacja TCP/IP w BSD (1980) • Linia "komercyjna": Unix System III, Unix System V AT&T; SVR4 (1989)

UXP – zima 2015-2016, Grzegorz Blinowski

(Wikimedia Commons)

UXP – zima 2015-2016, Grzegorz Blinowski

Główne innowacje • BSD: – TCP/IP – Sockets API – Job control – Symlinks – System plików UFS – Multi-group (przynależność do wielu grup)

• System V – Biblioteki .so – TLI, STREAMS – IPC (pamięć dzielona, semafory, kolejki komunikatów) • SunOS – V-node – Funkcja mmap() – NFS, RPC, XDR

UXP – zima 2015-2016, Grzegorz Blinowski

Standardy i organizacje • Lata 80-te: wiele wersji na licencji AT&T (od 1983 – podział Bell System) • Konsorcjum X/Open – 1984 • 1990: OSF/1 – BSD/Mach; Unix International (AT&T) • 1993: COSE, X/Open • Obecnie znak handlowy “UNIX” należy do “The Open Group”

UXP – zima 2015-2016, Grzegorz Blinowski

Standardy • • • • • • • •

SVID – System V Interface Definition (AT&T) SUS - Single Unix Specification 1988 – ... POSIX (IEEE) 1990+: Spec 1170 1997: SUS v2 (Open Group) 2001: POSIX:2001 – SUS v3 (3000+ stron) 2004: POSIX:2004 2008: POSIX:2008

UXP – zima 2015-2016, Grzegorz Blinowski

Standardy • Unix System V release 4 (SVID)– AT&T, Unix International, Novel • X/Open XPG3 (m.in. IPC, X-windows, lokalizacja programów, programy użytkowe, język C) • POSIX (wybrane): – IEEE P1003.1 – API (interfejs miedzy systemem operacyjnym a programami) – IEEE P1003.2 – Interpreter poleceń i programy użytkowe – IEEE P1003.3 – Testy zgodności – IEEE P1003.4a – Wątki

UXP – zima 2015-2016, Grzegorz Blinowski

(Wikimedia Commons)

UXP – zima 2015-2016, Grzegorz Blinowski

Cechy • •

Przenośność - źródła C + kilka % kodu asamblera Wielozadaniowy i wielodostępny – Wiele procesów – każdy ma „złudzenie” posiadania maszyny na własność – Równoczesna praca wielu użytkowników



Pamięć wirtualna : – procesy mogą alokować więcej pamięci niż jest w systemie, – mapa pamięci procesu może być "stała" i obejmować całą przestrzeń adresową (4 GB w modelu 32b)

• • •

Wirtualny i rozproszony system plików Wirtualny - w jednym drzewie wiele typów systemów plików Rozproszony - obejmuje wiele maszyn w sieci

UXP – zima 2015-2016, Grzegorz Blinowski

System procesów

UXP – zima 2015-2016, Grzegorz Blinowski

Procesy- zagadnienia • Cykl życia: tworzenie, wykonanie, zakończenie • Tryb wykonania: user, kernel • Wejście do kernel: syscall, przerwanie, wyjątek • Szeregowanie: w jaki sposób proces jest wybierany z listy gotowych procesów, jak lista ta jest zarządzana i sortowana • Przełączanie / wywłaszczanie (contex switching) • Wykorzystanie pamięci (we współpracy z pod-systemem VM) • Wykorzystanie systemu plików (we współpracy z podsystemem VFS) • Obsługa wyjątków (sygnały) • Timing – statystyki, profilowanie, itp.

UXP – zima 2015-2016, Grzegorz Blinowski

Diagram stanów procesu SONPROC syscal intr., fault

exit() SZOMB

SONPROC kernel

preempt

SRUN

sleep schedule SSLEEP

wakeup

SRUN

ten sam stan

SIDL (idle)

fork()

UXP – zima 2015-2016, Grzegorz Blinowski

Diagram stanów procesu (stary)

UXP – zima 2015-2016, Grzegorz Blinowski

Diagram stanów procesu - Linux •

TASK_RUNNING – w trakcie wykonania lub gotowy



INTERRUPTIBLE lub UNINTERRUPTIBLE – odp. SSLEEP



TASK_STOPPED (nie pokazany – SIGTSTP i inne)

UXP – zima 2015-2016, Grzegorz Blinowski

Deskryptor procesu • Proces opisany poprzez swój deskryptor • Deskr. częściowo zależny od architektury sprzętu • “Klasyczny” podział deskryptora na 2 części: – proc - /usr/include/sys/proc.h – u - u-area (u-obszar) - /usr/include/sys/user.h • Powiązania deskryptorów z innymi strukturami: – Struct pid – hierarchia procesów (także „orphaned flag”, odp. hash table, itp) – VFS: ufschunk, file, vnode – VM: as (address space), seg (segments)

UXP – zima 2015-2016, Grzegorz Blinowski

struct proc •

rejestry procesora: rejestry uniwersalne – odkładane na stosie kernelowym procesu w momencie wejścia w tryb jądra(!); rej. kontekstu, wskażniki stosów user i kernel



stan procesu (SRUN, SIDL, SZOMB, SONPROC, …)



PID, PPID,



zdarzenie, na które oczekuje proces



pamięć, mapowanie pam. wirt



informacje organizacyjne związane z listą procesów i kolejkami schedulara: priorytet, wartość nice, statystyki schedulera



proces group



wskażnik na u-area



limity



inf. związane z obsługą sygnałów: maski



liczniki czasu



inf. związane z obługą select()

UXP – zima 2015-2016, Grzegorz Blinowski

struct u (user) • katalog aktualny • root fs • tablica otwartych plików • terminal sterujący • pole zwrotu f-kcji systemowej • liczniki czasu i inne dane statystyczne • inf. związane z debugowaniem i core dump-em

UXP – zima 2015-2016, Grzegorz Blinowski

Deskryptor procesu w Linux • Struktura task: – struct task_struct

– ok 2 KB • przydzielany dynamicznie • w kernelu 0 czyli PID potomka dla proc. rodzica, < 0 w wypadku błędu (za dużo procesów)

if ( (childpid = fork()) == 0 ) { /* proces potomny */ exec(....); } else { /* proces macierzysty */ }



Cele: – Tworzenie nowego procesu – Tworzenie demona: fork, exec, exit, fork, exec, exit – Tworzenie “farmy” procesów serwisowych – Tworzenie nadzorcy i procesu roboczego (demona) – Shell – wykonywanie poleceń, przetwarzanie w tle, przetwarzanie potokowe

UXP – zima 2015-2016, Grzegorz Blinowski

fork() Duplikacja procesu: • • •

Nowy Deskryptor, Nowe segmenty pamięci (stos, sterta, dane) – dla potomka takie same po wyjściu z fork() ale nie te sam! Pozostaje b.z.: text

Deskryptor: • Zostaje częściowo skopiowany, • Zmienia się: PID, PPID, • Dziedziczone: – RUID, EUID, – tablica otwartych plików, – akt. katalog, – umask, – ustawienia dotyczące sygnałów

UXP – zima 2015-2016, Grzegorz Blinowski

wait()

int wait( int *status); •

Oczekuje na zakończenie procesu potomnego (którego kolwiek), funkcja powolna (może być przerwana sygnałem)



zwraca –1 jeśli nie było potomka



zawiesza się gdy jest potomek, czeka na jego zakończenie



gdy potomek wykona jawny lub niejawny exit() wait() się odblokowuje



Zombie – nie było wait() u rodzica



exit() – generuje SIGCLD (domyślnie nie ma reakcji)



ustawienie konieczny

signal( SIGCLD, SIG_IGN)

powoduje, że wait() nie jest

UXP – zima 2015-2016, Grzegorz Blinowski

Status zwracany przez wait() • Status – związany z przyczyna zakończenia procesu oraz argumentem dla exit() (return) Arg dla exit()

0x00

0x00

c:0x80 | nr-sygn

nr-sygn 8 bit

0x7f 8 bit

Zakończenie przez exit()

Sygnał zakończyl potomka: Jeśli core to ustawiony Najstarszy bit mlodszego bajtu Proces zatrzymany – nie zakończony

UXP – zima 2015-2016, Grzegorz Blinowski

Odmiany wait() int wait3(union wait *status, int options, struct rusage *rusage)



status – jak dla wait()



options – WNOHANG



zwraca: 0 jeśli nie blok i nic się nie stało, -1 błąd, PID

pid_t waitpid(pid_t pid, int *stat_loc, int options);



pid == -1 - dowolny proces



pid > 0 - czekamy na konkretnego potomka o danym pid



pid < -1 czekamy na potomka z danego pgrp = abs(pid)



options: WCONTINUED, WNOHANG, WNOWAIT, WUNTRACED

UXP – zima 2015-2016, Grzegorz Blinowski

execve() •

Ładuje nowy program do istniejącego procesu



Wraca tylko w przypadku błędu



Deskryptor procesu po wywołaniu execve() – “nadpisanie” wybranych pól: dane, stos, sterta, text, rejestry, statystyki, liczniki czasu – Zachowanie b/z innych: PID, PPID, PGRP, grupy, tablica plików, aktualny katalog, terminal sterujący, rusage, root fs, umask, maska sygnałów (ale nie funkcje obsługi sygnałów! (dlaczego?))



Typowe sytuację błędne: – [EACCES] – nie ma prawa dostępu do pliku programu, lub brak +x, lub zły typ pliku – [ENOENT] – brak pliku – [ENOEXEC] – nieznany lub zły format pliku programu – [ENOTDIR] – katalog w ścieżce nie jest katalogiem – [ETXTBSY] – plik programu otwarty do zapisu

UXP – zima 2015-2016, Grzegorz Blinowski

Rodzina funkcji exec() #include extern char **environ; int execl(const char *path, const char *arg0, ... /*, (char *)0 */); int execle(const char *path, const char *arg0, ... /*, (char *)0, char *const envp[] */); int execlp(const char *file, const char *arg0, ... /*, (char *)0 */); int execv(const char *path, char *const argv[]); int execve(const char *path, char *const argv[], char *const envp[]); int execvp(const char *file, char *const argv[]); int execvP(const char *file, const char *search_path, char *const argv[]); •

Pierwotna funkcja to execve()



Uwzględnienie zmiennej środowiskowej PATH



Specjalne traktowanie plików z magiczną sekwencją #!shell



Może ustawić EUID, EGID (set user/group id)



Uwaga na relację path/file z arg0 !

UXP – zima 2015-2016, Grzegorz Blinowski

Środowisko (environment) gjb@skinner:~$ env MANPATH=/usr/local/man:/usr/man:/usr/lib/java/man TERM=xterm SHELL=/bin/bash SSH_CLIENT=172.22.103.92 60220 22 QTDIR=/usr/lib/qt SSH_TTY=/dev/pts/0 USER=gjb MAIL=/var/mail/gjb PATH=/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/lib/java/bin:/usr/li b/java/jre /bin:/usr/lib/qt/bin:. LC_COLLATE=C PWD=/home/gjb LANG=en_US HOME=/home/gjb gjb@skinner:~$

UXP – zima 2015-2016, Grzegorz Blinowski

Środowisko (environment) #include extern char **environ; char *getenv(const char *name); int putenv(char *string); int setenv(const char *name, const char *value, int overwrite);



Przechowywany jest wskaźnik (string nie jest kopiowany)



Konwencja “nazwa=wartość” nie jest narzucona



Ostatni element tablicy environ ma wartość NULL