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