UXP zima 215-216, Grzegorz Blinowski UXP1A Unix Programowanie i Architektura zima 215-216 Grzegorz Blinowski Instytut Informatyki Politechniki Warszawskiej
UXP zima 215-216, Grzegorz Blinowski Regulamin, itp. Zasady ogólne: Tryb zaliczenia oceny są wystawione najpóźniej ostatniego dnia zajęć (przed rozpoczęciem sesji letniej), 5 p. Projekt, 5 p. kolokwia, 5 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 215-216, 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.1 -?) Oceny, wpisy, poprawa 28.1 (ostatnie zajęcia) Projekt: start ok. połowy listopada, zaliczenie do 21.1 Wymagania Systemy operacyjne Dobra znajomość języka C Materiały dostępne na stronie http://www.ii.pw.edu.pl/~gjb Kontakt: g.blinowski@ii.pw.edu.pl, tel PW: 222347184; konsultacje wt. 1-12
UXP zima 215-216, Grzegorz Blinowski Literatura W. Richard Stevens, Advanced Programming in the UNIX Environment Uresh Vahalia, Jadro systemu UNIX, WNT; 21 Berny Goodhear, James Cox, Sekrety magicznego ogrodu UNIX System V Wersja 4 od środka (podręcznik), WNT 21 Marc Rochkind, Programowanie w systemie Unix dla zawansowanych, WNT (wyd. 2; 25) David R. Butenhof, Programming with Posix Threads, Addison-Wesley, 1997 Daniel P. Bovet, Marco Cesati, LINUX kernel, Wydawnictwo RM (O Reilly) 21 M. Bach, Budowa systemu operacyjnego Unix, WNT 1996
UXP zima 215-216, 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 215-216, 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 215-216, 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 (,571 MHz) Peryferia: klawiatura/drukarka, taśma papierowa, taśma magentyczna Koszt: ok 72 K USD
UXP zima 215-216, 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 (198) Linia "komercyjna": Unix System III, Unix System V AT&T; SVR4 (1989)
UXP zima 215-216, Grzegorz Blinowski (Wikimedia Commons)
UXP zima 215-216, 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 215-216, Grzegorz Blinowski Standardy i organizacje Lata 8-te: wiele wersji na licencji AT&T (od 1983 podział Bell System) Konsorcjum X/Open 1984 199: OSF/1 BSD/Mach; Unix International (AT&T) 1993: COSE, X/Open Obecnie znak handlowy UNIX należy do The Open Group
UXP zima 215-216, Grzegorz Blinowski Standardy SVID System V Interface Definition (AT&T) SUS - Single Unix Specification 1988... POSIX (IEEE) 199+: Spec 117 1997: SUS v2 (Open Group) 21: POSIX:21 SUS v3 (3+ stron) 24: POSIX:24 28: POSIX:28
UXP zima 215-216, 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 P13.1 API (interfejs miedzy systemem operacyjnym a programami) IEEE P13.2 Interpreter poleceń i programy użytkowe IEEE P13.3 Testy zgodności IEEE P13.4a Wątki
UXP zima 215-216, Grzegorz Blinowski (Wikimedia Commons)
UXP zima 215-216, 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 215-216, Grzegorz Blinowski System procesów
UXP zima 215-216, 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 215-216, 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 215-216, Grzegorz Blinowski Diagram stanów procesu (stary)
UXP zima 215-216, 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 215-216, 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 215-216, 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 215-216, 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 215-216, Grzegorz Blinowski Deskryptor procesu w Linux Struktura task: struct task_struct <linux/sched.h> ok 2 KB przydzielany dynamicznie w kernelu <=2.4 dostępny na końcu segmentu stosu jądra (x86) obecnie na stosie jadra zlokalizowany thread_struct powiazany z task_struct
UXP zima 215-216, Grzegorz Blinowski Hierarchia procesów, PID, PPID Drzewiasta hierarchia procesów Dziedziczenie procesów osieroconych przez proces init (ppid==1) Powstawanie procesów zombie deskryptor procesu, którego statusu nie odebrał (jeszcze) rodzic specjalne procesy systemowe: : swapper. scheduler 1: init 2,3,4: pagedaemon, pageout, vmdaemon, fsflush, update Praktyczne znaczenie PID: identyfikacja, ustalenie hierarchii, zapisanie do pliku w celu wysłania sygnału
UXP zima 215-216, Grzegorz Blinowski Polecenie ps ogg% ps -axl UID PID PPID CPU PRI NI VSZ RSS WCHAN STAT TT -18 sched 1 1 456 DLs?? :1.17 Is?? :.58 /sbin/init -- 2 1-18 12 psleep DL?? :.7 (pagedaemon) 3 28 12 psleep DL?? :. (vmdaemon) 4 28 12 update DL?? 62:25.89 27 1 4 18 2 8 pause Is?? :.1 adjkerntz -i 73 1 2 196 448 select Ss?? 2:2.57 syslogd -s 1 1 2 196 472 select Is?? :2.62 inetd 12 1 1 18 332 448 pause Is?? 7:44.83 cron 11 1 on port 25 (sendmail) 2 62 78 select Ss?? :42.97 sendmail: accepting connections 16 wait TIME COMMAND (swapper) (update)
UXP zima 215-216, Grzegorz Blinowski Polecenie ps ogg% ps -axl UID PID PPID CPU PRI NI VSZ RSS WCHAN 167 1 2 2 12152 167 12154 167 1216 STAT 468 64 accept Is 28-2 28 167 1 28 12162 167 1 28 12164 167 2 18841 167 22953 TT TIME COMMAND?? 6:27.12 /usr/local/bin/sshd Z?? :. (sshd) - Z?? :. (sshd) - Z?? :. (sshd) - Z?? :. (sshd) 28 - Z?? :. (sshd) 1 2 836 14 select S?? :2.3 /usr/local/bin/sshd 167 28 Z?? :. 1 18843 18841 18 452 324 pause Ss p :.23 -csh (csh) 1 1917 18843 1 28 636 272 - R+ p :. ps -axl - (sshd) 14142 1 3 176 524 ttyin Is+ v :.9 /usr/libexec/getty Pc ttyv 2315 1 3 176 596 ttyin Is+ v1 :.2 /usr/libexec/getty Pc ttyv1 1 19292 1 3 452 324 ttyin Is+ v2 :.26 -csh (csh) 172 1 3 176 516 ttyin Is+ v3 :.2 /usr/libexec/getty Pc ttyv3 173 1 3 176 516 ttyin Is+ v4 :.2 /usr/libexec/getty Pc ttyv4
UXP zima 215-216, Grzegorz Blinowski API #include <unistd.h> pid_t getpid(void); pid_t getppid(void);
UXP zima 215-216, Grzegorz Blinowski Mapa pamięci procesu
UXP zima 215-216, Grzegorz Blinowski Mapa pamięci procesu 2^32 lub 2^44 (16 TB w adresowaniu 64-o bitowym) Stosy: User stack Kernel stack (pusty, jeśli w trybie user) Syscall: wywołanie funkcji bibliotecznej w trybie user, samo wejście do trybu jądra: uprzywilejowana instrukcja powodująca wyjątek Stos jądra używany normalnie do przechowywania rekordów aktywacji, zmiennych lokalnych itd. Podczas wykonywania kolejnych funkcji w trybie jądra Context switch: na stosie jądra odłożone rejestry itp, co pozwala na powrót przy ponownej aktywacji procesu
UXP zima 215-216, Grzegorz Blinowski Użytkownicy i grupy UID: liczba (uid_t) UID - nazwa - mapowanie przez /etc/passwd lub NIS/NIS+ API: #include <sys/types.h> #include <pwd.h> struct passwd *getpwnam(const char *login); struct passwd *getpwuid(uid_t uid); struct passwd *getpwent(void); /* seq read */ int setpwent(void); /* rewind */ void endpwent(void); /* close */
UXP zima 215-216, Grzegorz Blinowski Użytkownicy i grupy root:x::::/root:/bin/bash root:$1$xxxj:13726:::::: bin:x:1:1:bin:/bin: bin:*:9797:::::: daemon:x:2:2:daemon:/sbin: daemon:*:9797:::::: adm:x:3:4:adm:/var/log: adm:*:9797:::::: lp:x:4:7:lp:/var/spool/lpd: lp:*:9797:::::: mail:x:8:12:mail:/: mail:*:9797:::::: news:x:9:13:news:/usr/lib/news: news:*:9797:::::: mysql:x:27:27:mysql:/var/lib/mysql:/bin/bash mysql:*:9797:::::: pop:x:9:9:pop:/: pop:*:9797:::::: nobody:x:99:99:nobody:/: nobody:*:9797:::::: backup:x:3116:1:,,,:/home/backup:/bin/bash backup:$1$xxx/:13231::9999 ulam:x:3113:98:,,,:/home/ulam:/bin/bash ulam:$1xxx:13231::99999:7 tadek:x:312:1:,,,:/home/tadek:/bin/bash tadek:$xxxy1:14532::99999:
UXP zima 215-216, Grzegorz Blinowski Użytkownicy i grupy (API) struct passwd { char *pw_name; /* user name */ char *pw_passwd; /* encrypted password */ int pw_uid; /* user uid */ int pw_gid; /* user gid */ time_t pw_change; /* password change time */ char *pw_class; /* user access class */ char *pw_gecos; /* Honeywell login info */ char *pw_dir; /* home directory */ char *pw_shell; /* default shell */ time_t pw_expire; /* account expiration */ };
UXP zima 215-216, Grzegorz Blinowski Grupy użytkowników Grupa: GID, nazwa, lista użytkowników, hasło Styl BSD użytkownik może należeć do wielu grup na raz wg. tych przynależności ustalane są prawa dostepu do plików i innych zasobów lista akt. grup inicjowana przez roota w momencie logowania się użytkownika do systemu Styl SV proces należy do jednej grupy polecenie/funkcja newgrup() zmiana grupy
UXP zima 215-216, Grzegorz Blinowski /etc/group /etc/group: daemon:*:1:daemon kmem:*:2:root sys:*:3:root tty:*:4:root operator:*:5:root mail:*:6: bin:*:7: news:*:8: man:*:9: games:*:13: staff:*:2:root,gjb guest:*:31:root,guest uucp:*:66:uucp
UXP zima 215-216, Grzegorz Blinowski API grup #include <sys/types.h> #include <grp.h> struct group * getgrnam(const char *name); struct group * getgrgid(gid_t gid); struct group * getgrent(void); int setgrent(void); void endgrent(void);
UXP zima 215-216, Grzegorz Blinowski Real, effective, saved UID/GID Real user / group ID: identyfikacja, rozliczenia (RUID, RGID) Effective user / group ID: uprawnienia (EUID, EGID) Potrzeba zmianu UID dla root (przy logowaniu użytkownika) Potrzeba zmiany praw na innego użytkownika (typowo innego niż root i powrotu do oryginalnych praw) - trzeba zachować szczelny mechanizm uprawnień Wprowadzono Saved user / group ID
UXP zima 215-216, Grzegorz Blinowski Z(a)miana RUID, EUID (RGID, EGID) API setuid( uid_t uid ); setgid ( gid_t gid ); Jeśli root to ustawia RUID, EUID, SVUID (tylko root ustawia RUID) Jeśli nie root oraz uid==ruid uid==svuid ustaw: euid na uid Jesli nie spełnione powyższe to błąd EUID może być ustawione przez exec() SVUID początkowo takie jak EUID
UXP zima 215-216, Grzegorz Blinowski fork(), wait(), exec()
UXP zima 215-216, Grzegorz Blinowski Tworzenie procesów Życie procesu może być rozpatrywane z punktu widzenia jądra systemu oraz z punktu widzenia programisty: uruchomienie programu poprzez wywołanie exec...(), inicjalizację w crt i zakończenie procesu Przekazywanie argumentów przez funkcje exec (różne odmiany funkcji exec() ): main(int argc, char *argv[], char *envp[]) argv[] - nazwa programu rozmiar argv - 512 124 B typowo (stosowanie programu xargs) envp środowisko extern char **environ, getenv( char *par)
UXP zima 215-216, Grzegorz Blinowski Funkcja systemowa fork() fork() - Zwraca: dla potomka, > czyli PID potomka dla proc. rodzica, < w wypadku błędu (za dużo procesów) if ( (childpid = fork()) == ) { /* 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 215-216, 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 215-216, Grzegorz Blinowski wait() <sys/wait.h> <sys/time.h> <sys/resource.h> 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 215-216, Grzegorz Blinowski Status zwracany przez wait() Status związany z przyczyna zakończenia procesu oraz argumentem dla exit() (return) Arg dla exit() x x c:x8 nr-sygn nr-sygn 8 bit x7f 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 215-216, Grzegorz Blinowski Odmiany wait() int wait3(union wait *status, int options, struct rusage *rusage) status jak dla wait() options WNOHANG zwraca: 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 > - czekamy na konkretnego potomka o danym pid pid < -1 czekamy na potomka z danego pgrp = abs(pid) options: WCONTINUED, WNOHANG, WNOWAIT, WUNTRACED
UXP zima 215-216, 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 215-216, Grzegorz Blinowski Rodzina funkcji exec() #include <unistd.h> extern char **environ; int execl(const char *path, const char *arg,... /*, (char *) */); int execle(const char *path, const char *arg,... /*, (char *), char *const envp[] */); int execlp(const char *file, const char *arg,... /*, (char *) */); 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 arg!
UXP zima 215-216, 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.13.92 622 22 QTDIR=/usr/lib/qt SSH_TTY=/dev/pts/ 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 215-216, Grzegorz Blinowski Środowisko (environment) #include <unistd.h> 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