Sistemi Operativi: Processi - Lezione 07

147
1 Concetto di processo Processo: istanza di un programma in esecuzione Codice del programma (sezione di testo) Stato di avanzamento Contatore di programma Pila (variabili locali, indirizzi di ritorno) Variabili locali (sezione dei dati)

Transcript of Sistemi Operativi: Processi - Lezione 07

Page 1: Sistemi Operativi: Processi - Lezione 07

1

Concetto di processo• Processo: istanza di un programma in

esecuzione– Codice del programma (sezione di testo)– Stato di avanzamento

♦Contatore di programma♦Pila (variabili locali, indirizzi di ritorno)

– Variabili locali (sezione dei dati)

Page 2: Sistemi Operativi: Processi - Lezione 07

2

Concetto di processo• Programma e processo sono due entità

distinte– Un programma è un'entità passiva

♦File su disco (codice o eseguibile) immutato♦Non va in esecuzione da solo

– Un processo è un'entità attiva♦Struttura dati contenente puntatori a

–Codice–Dati–Stato del processo

Page 3: Sistemi Operativi: Processi - Lezione 07

3

Esecuzione di un processo• Il gestore dei processi esegue, ad intervalli di

tempo più o meno regolari, una sequenza di istruzioni pertinenenti al programma (trace)

• Un SO moderno, multiprogrammato, time-sharing garantisce una esecuzione sequenziale e concorrente (interleaved) di più processi

• Compiti specifici del gestore dei processi:– Garantire l'esecuzione sicura di una traccia– Scegliere il prossimo processo di cui sarà

eseguita una traccia (scheduling)– Gestire la commutazione periodica tra un

processo ed un altro (context switch)

Page 4: Sistemi Operativi: Processi - Lezione 07

4

Esecuzione interleaved

Gestoreprocessi

Memoriaprincipale

Processo A

Processo B

Processo C

ProgramCounter

Page 5: Sistemi Operativi: Processi - Lezione 07

5

Esecuzione interleaved

Gestoreprocessi

Memoriaprincipale

Processo A

Processo B

Processo C

ProgramCounter

Indirizzi PC

a + 0a + 2a + 6a + 10

Scade l'intervallodi tempo assegnatoal processo A

Page 6: Sistemi Operativi: Processi - Lezione 07

6

Esecuzione interleaved

Gestoreprocessi

Memoriaprincipale

Processo A

Processo B

Processo C

ProgramCounter

Indirizzi PC

g + 100g + 102g + 106g + 110g + 114

Il gestore dei processisceglie come prossimoprocesso da eseguireil processo B, e neprepara l'esecuzione

Page 7: Sistemi Operativi: Processi - Lezione 07

7

Esecuzione interleaved

Gestoreprocessi

Memoriaprincipale

Processo A

Processo B

Processo C

ProgramCounter

Indirizzi PC

b + 32b + 36b + 40

Il processo B siinterrompe perchédeve effettuare unaoperazione di I/O

Page 8: Sistemi Operativi: Processi - Lezione 07

8

Esecuzione interleaved

Gestoreprocessi

Memoriaprincipale

Processo A

Processo B

Processo C

ProgramCounter

Indirizzi PC

g + 100g + 102g + 106g + 110g + 114

Il gestore dei processisceglie come prossimoprocesso da eseguireil processo C, e neprepara l'esecuzione

Page 9: Sistemi Operativi: Processi - Lezione 07

9

Esecuzione interleaved

Gestoreprocessi

Memoriaprincipale

Processo A

Processo B

Processo C

ProgramCounter

Indirizzi PC

c + 248c + 356c + 360c + 364

Il processo C terminala sua esecuzione

Page 10: Sistemi Operativi: Processi - Lezione 07

10

Esecuzione interleaved

Gestoreprocessi

Memoriaprincipale

Processo A

Processo B

Processo C

ProgramCounter

Indirizzi PC

g + 100g + 102g + 106g + 110g + 114

Il gestore dei processisceglie come prossimoprocesso da eseguireil processo A, e neprepara l'esecuzione

Page 11: Sistemi Operativi: Processi - Lezione 07

11

Esecuzione interleaved

Gestoreprocessi

Memoriaprincipale

Processo A

Processo B

Processo C

ProgramCounter

Indirizzi PC

a + 14a + 18a + 22a + 56

Il processo A siblocca perché richiedeuna operazione di I/O

Page 12: Sistemi Operativi: Processi - Lezione 07

12

Rappresentazione di un processo• L'esecuzione di tipo interleaved deve essere

modellata all'interno del gestore dei processi• Sembrerebbe naturale introdurre un modello

del tipo DFA (Deterministic Finite Automata, automa deterministico a stati finiti)

• Quanti stati utilizzo per il mio modello?• Proviamo con il caso più semplice:

– Due stati: running, not running– I processi non in esecuzione sono “accodati” di

fronte al processore, in attesa di ricevere tempo di calcolo

– Tramite oppoerunte transizioni, un processo è in grado di cambiare stato

Page 13: Sistemi Operativi: Processi - Lezione 07

13

Rappresentazione di un processoModello a due stati

not running runningcreazione terminazione

blocking

dispatching

Diagramma di accodamento

coda processi pronti CPUdispatchingcreazione terminazione

Page 14: Sistemi Operativi: Processi - Lezione 07

14

Incompletezza del modello a 2 stati• Il modello a due stati è incompleto• Tutti i processi che non eseguono sono

equiparati a processi in qualche modo “bloccati”

• In realtà, le cause del blocco possono essere estremamente diverse:– scadenza dell'intervallo di tempo di calcolo

assegnato– comando di una operazione di I/O– arrivo di una interruzione

• Per discriminare le diverse cause di blocco, è necessario considerare un modello con almeno tre stati

Page 15: Sistemi Operativi: Processi - Lezione 07

15

Modello a tre stati• L'automa che descrive il ciclo di vita di un

processo è composto da tre stati:– running: la CPU sta eseguendo una traccia del

processo– blocked: la CPU ha comandato una istruzione

che richiede il verificarsi di un evento (di solito, I/O) per conto del processo, che deve fermarsi ed attendere la risposta

– ready: la CPU non sta eseguendo una traccia del processo (quale che sia il motivo), tuttavia il processo è nelle condizioni di essere ripristinato

• Differenziazione esplicita degli stati di “bloccato” e “pronto”

Page 16: Sistemi Operativi: Processi - Lezione 07

16

Modello a tre statiModello a tre stati

ready runningcreazione terminazione

scadenzaintervallo

tempo

dispatching

blocked

attesaevento

completamentoevento

Transizioniready => running: assegnazione CPU al processo

running => ready: il processo ha utilizzato il max.tempo per esecuzione traccia

running => blocked: attesa completamento evento

blocked => ready: l'evento atteso si verifica

Page 17: Sistemi Operativi: Processi - Lezione 07

17

Stati aggiuntivi• Il modello a tre stati è in grado di catturare le

diverse dinamiche di interruzione dell'esecuzione di una traccia

• Vengono aggiunti alcuni stati aggiuntivi per la gestione pulita dei meccanismi di creazione e di terminazione del processo

• Due ulteriori stati:– new: il sistema alloca ed inizializza le strutture

dati per la gestione dell'esecuzione del processo

– exit: il sistema rilascia le strutture dati ed alcune risorse allocate dal processo

Page 18: Sistemi Operativi: Processi - Lezione 07

18

Stati aggiuntiviStato aggiuntivo new

new readycreazione terminazioneadmit

Strutture datiper il processoallocate edinizializzate

Stato aggiuntivo exit

running exitterminazione

Rilascio strutturedati allocate per ilprocesso

Page 19: Sistemi Operativi: Processi - Lezione 07

19

Modello a cinque stati• Ad ogni processo è associato uno stato• Durante l'esecuzione, un processo è soggetto

a cambiamenti di stato• Stati:

– new: il processo è stato appena creato– running: una unità di elaborazione esegue le

istruzioni del relativo programma– blocked: il processo è in attesa del verificarsi di

un qualche evento– ready: il processo attende di essere assegnato

ad una unità di elaborazione– exit: il processo ha terminato la sua esecuzione

Page 20: Sistemi Operativi: Processi - Lezione 07

20

Modello a cinque stati

new exit

ready running

blocked

ammesso

interruzione

dispatching

uscita

attesa I/Oattesa evento

completamento I/Overifica evento

Page 21: Sistemi Operativi: Processi - Lezione 07

21

Modello a cinque stati

Coda processi pronti

Diagramma di accodamento

CPU

I/O Coda I/O Richiesta I/O

quanto di tempoesaurito

generazioneprocesso figlio

attesainterruzione

processo figlioin esecuzione

occorrenzainterruzione

Page 22: Sistemi Operativi: Processi - Lezione 07

22

Cause di creazione di un processo• Attivazione di un batch job

– Comando inviato tramite shell

• Login interattivo– Accesso al sistema da parte di un utente

• Gestione di un servizio– Un processo soddisfa una richiesta di servizio– Il processo invocante non si interrompe– Processi server

• Spawning– Un processo soddisfa una richiesta di servizio– Il processo invocante si interrompe– Processi di login

Page 23: Sistemi Operativi: Processi - Lezione 07

23

Cause di terminazione di un processo• Completamento della traccia di istruzioni

– Può essere comunicato esplicitamente

• Indisponibilità di memoria– Il processo richiede troppa memoria

• Violazioni di limite– Accesso a locazioni di memoria proibite

• Errore di protezione– Accesso ad una risorsa protetta o inesistente

• Terminazione su richiesta– Operata dal sistema o da un altro processo

• Errore aritmetico– Divisione per zero, overflow

Page 24: Sistemi Operativi: Processi - Lezione 07

24

Il grado di multiprogrammazione• Il processore è, solitamente, molto più veloce dei

sistemi di I/O– La maggior parte dei processi residenti in memoria

è nello stato blocked, in attesa di completamento di una richiesta di I/O

– Rischio di sottoutilizzo del processore

• Come si può prevenire questo problema?– Si cerca di mantenere il maggior numero di processi

possibile negli stati running/ready

– Grado di multiprogrammazione: numero di processi eseguibili (running + ready)

– Obiettivo: mantenere il più alto possibile il grado di multiprogrammazione

Page 25: Sistemi Operativi: Processi - Lezione 07

25

Swapping

• Per superare il limite imposto dal vincolo di memoria fisica disponibile, si introduce il concetto di swapping nel modello

• Due stati aggiuntivi:– Blocked-Suspended: il processo è bloccato (in

attesa di un evento) e la memoria che occupa è stata liberata con un trasferimento dati su disco (swap out)

– Ready-Suspended: il processo non è bloccato (nessun evento, oppure attesa terminata) e torna ad occupare memoria centrale con un trasferimento dati da disco (swap in)

Page 26: Sistemi Operativi: Processi - Lezione 07

26

Modello a cinque stati con swapping

new exit

ready running

blocked

ammesso

interruzione

dispatching

uscita

attesa I/Oattesa evento

completamento I/Overifica evento

blockedsuspended

readysuspended

Rimozione dallamemoria (swap out)

verifica evento

Ripristino inmemoria (swap in)

verifica evento

Page 27: Sistemi Operativi: Processi - Lezione 07

27

Modello a cinque stati con swapping

Coda processi pronti

Diagramma di accodamento(swapping)

CPU

I/O Coda I/O Richiesta I/O

Processi parzialmenteeseguiti e sottoposti

a swap

swap outswap in

Page 28: Sistemi Operativi: Processi - Lezione 07

28

Cause di sospensione di un processo• Swapping

– Liberazione porzioni di memoria da parte del SO– Obiettivo: aumento grado multiprogrammazione

• Richiesta– Da parte di un utente interattivo– Da parte di un altro processo (coordinamento

attività)

• Temporizzazione– Gestione attività periodiche (monitoraggio)

• Recupero– Ripristino da situazioni erronee/incoerenti

Page 29: Sistemi Operativi: Processi - Lezione 07

29

Gestione processi:strutture di controllo

• Per gestire l'esecuzione dei processi, il SO mantiene informazioni sui processi stessi e sulle risorse utilizzate

Memoria

Dispositivi

File

Risorsedi sistema

Processi

Strutture datidi controllo

Tabella dimemoria

...

Tabella dimemoria

...Tabella dimemoria

Tabella deiprocessi

P1

Pn

Immagine P1

Immagine Pn

Page 30: Sistemi Operativi: Processi - Lezione 07

30

Tabelle di memoria• Contengono informazioni su:

– Allocazione memoria principale ai processi– Allocazione memoria secondaria ai processi– Modalità di protezione dei singoli segmenti di

memoria (read-only, read-write, execute)– Informazioni necessarie a gestire la memoria

virtuale (nei sistemi in cui essa è supportata)

• Esempi:– Pagine di memoria accessaibili al processo– File aperti (e relativi descrittori)

Page 31: Sistemi Operativi: Processi - Lezione 07

31

Immagine di un processo• L'immagine di un processo rappresenta

l'insieme di informazioni necessarie per poter coordinare l'esecuzione di più processi– Codice macchina del programma di cui il

processo risulta essere una istanza, memorizzati in aree leggibili ed eseguibili

– Dati utilizzati dal programma, memorizzati in aree di memoria leggibili e scrivibili

– Stack, utilizzato per gestire le chiamate di funzione

– Process Control Block (PCB), una collezione di attributi necessari al SO per controllare l'esecuzione del processo stesso

Page 32: Sistemi Operativi: Processi - Lezione 07

32

Immagine di un processo

Stack segmentStack

programma

Indirizzi alti

Indirizzi bassi

Lo stack cresce verso il basso

“Buco” nello spaziodi indirizzamento

Heap(malloc) L'heap cresce verso alto

Data segments BSS

Data

CodiceeseguibileText segment

Variabili non inizializzate(vengono impostate a 0)

Variabili globali inizializzate

Page 33: Sistemi Operativi: Processi - Lezione 07

33

Process Control Block• Il SO associa a ciascun processo un

descrittore di processo (Process Control Block)– Identificatori: del processo, di altri processi

relazionati– Stato del processo: running, ready, blocked,...– Privilegi: per accesso a servizi e risorse– Registri: salvataggio registri della CPU (registri

interni, program counter, stack pointer)– Informazioni di scheduling: tutto ciò che il

sistema necessita di sapere per arbitrare la assegnazione del processore ai processi in stato ready (CPU scheduling)

– informazioni di stato: evento atteso

Page 34: Sistemi Operativi: Processi - Lezione 07

34

Process Control Block

puntatore

identificatore di processo (PID)

registri

contatore di programma

stato del processo

contatore di programma

elenco dei file aperti

...

Process Control Block

Page 35: Sistemi Operativi: Processi - Lezione 07

35

Scheduling dei processi• Obiettivo della multiprogrammazione:

– massimizzare l'utilizzo della CPU tramite l'esecuzione contemporanea di più processi

– contemporaneo è da intendersi nel senso di avanzamento alternato, non nel senso di esecuzione contemporanea sulla stessa CPU

• Obiettivo del time sharing:– Commutare l'uso della CPU fra processi così

velocemente da facilitare l'interattività con gli utenti

Page 36: Sistemi Operativi: Processi - Lezione 07

36

Scheduling dei processi• In un sistema con m CPU, al più m processi

possono essere in esecuzione alla volta– Che succede se ho più di m processi in

memoria?

• L'esecuzione dei processi deve essere schedulata sulle risorse di elaborazione a disposizione– Chi decide quale processo deve essere

ripristinato in esecuzione su quale CPU?

• Scheduler

Page 37: Sistemi Operativi: Processi - Lezione 07

37

Code di scheduling• Per coordinare il passaggio di stato fra

processi, il SO fa uso massiccio di code di scheduling

• Code utilizzate:– Coda dei processi

♦contiene tutti i processi del sistema– Coda dei processi pronti (ready queue)

♦contiene tutti i processi in stato di pronto– Coda di dispositivo

♦contiene tutti i processi in attesa per l'uso del dispositivo

♦una coda distinta per dispositivo

Page 38: Sistemi Operativi: Processi - Lezione 07

38

Code di scheduling

coda deiprocessi

pronti

Primo elemento

Ultimo elemento registri

...

PCB7

registri

...

PCB2

coda unità

CDROM

Primo elemento

Ultimo elemento

codaunitàdischi

Primo elemento

Ultimo elemento registri

...

PCB3

registri

...

PCB14

registri

...

PCB6

codaterminale

0

Primo elemento

Ultimo elemento registri

...

PCB3

Page 39: Sistemi Operativi: Processi - Lezione 07

39

Scheduler• Componente del SO che seleziona i processi

dalle code• Due tipi di scheduling:

– Job scheduling– CPU scheduling

Page 40: Sistemi Operativi: Processi - Lezione 07

40

Job scheduling• Utilizzato nei sistemi batch• L'insieme dei job da eseguire viene riversato

su disco (spooling)• Lo scheduler dei job sceglie il prossimo job da

mandare in esecuzione• Obiettivo: mantenere costante il numero di job

in memoria (grado di multiprogrammazione)• Invocato con frequenza bassa• Bilancio fra processi I/O-bound e CPU-bound• Job scheduling non è integrato nel kernel dei

moderni sistemi UNIX– Implementazioni applicative (stampa, posta)

Page 41: Sistemi Operativi: Processi - Lezione 07

41

CPU scheduling• Utilizzato nei sistemi time sharing• Seleziona il prossimo processo dalla coda di

pronto per l'esecuzione• Obiettivi:

– Massimizzare numero di processi eseguiti nell'unità di tempo (throughput)

– Minimizzare la latenza di processo– Dare priorità ai processi più importanti

• Invocato con frequenza elevata (ogni 100 msec)

Page 42: Sistemi Operativi: Processi - Lezione 07

42

Context switch• Quando la CPU interrompe l'esecuzione di un

processo per passare ad un altro:1.Occorre salvare lo stato attuale del vecchio

processo2.Occorre ripristinare lo stato precedente del

nuovo processo

• Le operazioni delineate in 1. e 2. prendono il nome di context switch

• Contesto di un processo: contenuto del descrittore di processo– Registri, stato, info gestione memoria

• Durata context switch: 1usec – 1msec– Dipende fortemente dalla architettura

Page 43: Sistemi Operativi: Processi - Lezione 07

43

Cambio modalità esecuzione• I processi si alternano anche in diverse

modalità di esecuzione, caratterizzate da livelli di privilegio diversi– User mode, Kernel mode

• User mode: esecuzione applicativi• Kernel mode: esecuzione servizi del kernel

– Accesso a privilegi di livello superiore– Possibilità di esecuzione di istruzioni non

ammesse in user mode– Caratterizzato (riconoscibile) da un settaggio di

un bit di stato del processore

Page 44: Sistemi Operativi: Processi - Lezione 07

44

Modalità esecuzione e context switchp

Kernel mode

User mode

Processo

syscall()

Meccanismo per ilcambio di modo

service_call()

Hardware

Chiamatabloccante

Scheduler

Processo

Invocazionescheduler

Page 45: Sistemi Operativi: Processi - Lezione 07

45

Modi di esecuzione e context switch• Cause di context switch

– Interruzione di clock (time sharing), viene attivato lo scheduler per cedere il controllo ad un altro processo

– Interruzione di I/O, con possibile riattivazione di un processo a più alta priorità

– Nei sistemi basati su memoria virtuale, prelievo di una pagina di memoria da swap (page fault)

• Cause di cambio modo di esecuzione– Attivazione di una Interrupt Service Routine– Context switch– Chiamata di sistema

Page 46: Sistemi Operativi: Processi - Lezione 07

46

Context switchProcesso P

0Processo P

1Sistema operativo

Salva lo stato in PCB0

Ripristina lo stato da PCB1

Salva lo stato in PCB1

Ripristina lo stato da PCB1

Page 47: Sistemi Operativi: Processi - Lezione 07

47

Context switchProcesso P

0Processo P

1Sistema operativo

Salva lo stato in PCB0

Ripristina lo stato da PCB1

Salva lo stato in PCB1

Ripristina lo stato da PCB1

Interruzione o syscall bloccante

Page 48: Sistemi Operativi: Processi - Lezione 07

48

Context switchProcesso P

0Processo P

1Sistema operativo

Salva lo stato in PCB0

Ripristina lo stato da PCB1

Salva lo stato in PCB1

Ripristina lo stato da PCB1

Interruzione o syscall bloccante

Page 49: Sistemi Operativi: Processi - Lezione 07

49

Context switchProcesso P

0Processo P

1Sistema operativo

Salva lo stato in PCB0

Ripristina lo stato da PCB1

Salva lo stato in PCB1

Ripristina lo stato da PCB1

Interruzione o syscall bloccante

Page 50: Sistemi Operativi: Processi - Lezione 07

50

Context switchProcesso P

0Processo P

1Sistema operativo

Salva lo stato in PCB0

Ripristina lo stato da PCB1

Salva lo stato in PCB1

Ripristina lo stato da PCB1

Interruzione o syscall bloccante

Interruzione o syscall bloccante

Page 51: Sistemi Operativi: Processi - Lezione 07

51

Context switchProcesso P

0Processo P

1Sistema operativo

Salva lo stato in PCB0

Ripristina lo stato da PCB1

Salva lo stato in PCB1

Ripristina lo stato da PCB0\

Interruzione o syscall bloccante

Interruzione o syscall bloccante

Page 52: Sistemi Operativi: Processi - Lezione 07

52

Modello processi UNIX• Esecuzione dei processi in user mode (codice

applicativo) e kernel mode (servizi)– Lo stato running deve essere suddiviso in due

stati: user running e kernel running

• Lo scheduler implementa un meccanismo di prelazione per supportare la priorità– Un processo che ritorna da una chiamata di

sistema (lasciando il kernel mode) può essere messo in stato ready e lasciare il passo ad un processo con più alta priorità

– Nuovo stato preempted che modella la prelazione

Page 53: Sistemi Operativi: Processi - Lezione 07

53

Modello processi UNIX• Modello gerarchico di processi: un processo

padre genera processi figli• PID: process identifier (identifica il processo)• Processo padre coordinatore aspetta che i

processi figli lavoratori terminino l'esecuzione• Se al momento dell'uscita un processo figlio

non ha un processo padre che aspetta il suo completamento, entra nello stato zombie– Processo figlio morto– Ha un PCB nella tabella dei processi, in modo

tale che il processo padre possa leggere il suo stato di uscita

– Distinzione stati exited e zombie

Page 54: Sistemi Operativi: Processi - Lezione 07

54

Modello processi UNIX

preempted

Usermode

running

Kernelmode

running

exited zombie

Sleeping inmemory

SleepingSwapped out

ReadySwapped out

ready

new

Page 55: Sistemi Operativi: Processi - Lezione 07

55

Immagine di un processo

Testo

Dati

Stack utente

Memoria condivisa

Contesto utente

Program counter

Registro di stato del processore

Stack pointer

Registri generali

Contesto registri

Entry nella tabella dei processi

U area (area utente)

Tabella indirizzamento (memoria virtuale)

Stack del kernel mode

Contesto sistema

Page 56: Sistemi Operativi: Processi - Lezione 07

56

Entry della tabella dei processiStato del processoPuntatori alla U areaDimensioni del processoIdentificatori d’utente (reale ed effettivo)Identificatori di processi (pid, id del genitore)Descrittore degli eventi (valido in stato sleeping)Priorita’Segnali (mandati al processi ma non ancora gestiti)Timer (monitoring)P_link (puntatore per la lista ready)Stato della memoria (swap in/out)

Page 57: Sistemi Operativi: Processi - Lezione 07

57

User Area (U area)Puntatore alla entry della tabella dei processiDimensioni del processoIdentificatori d’utente (effettivo)Array per i gestori di segnaliTerminaleCampo di erroreParametri di I/O (es. indirizzi dei buffer)Timer (monitoring in modalita’ utente)Valore di ritorno di system callsTabella dei descrittori di file

Page 58: Sistemi Operativi: Processi - Lezione 07

58

Modello di avvio processi UNIX

• Shell tipiche:– Bourne Again SHell– Bourne– C– Korn

Comandi di shell: nome-comando [ arg1, ..., arg

n ]

Kernel(PID=0)

init(PID=1) getty login shell

getty login shell

getty login shell

Legge/etc/inittab

Legge/etc/passwd

Page 59: Sistemi Operativi: Processi - Lezione 07

59

Creazione di un processo UNIX• Durante la propria esecuzione, un processo

può creare altri processi (fork)– Processo creante: processo padre– Processo creato: processo figlio

• Ciascun processo creato, a sua volta, può creare altri processi

• Organizzazione dei processi ad albero• Un processo può ereditare dal padre:

– Tutte le risorse– Un sottoinsieme delle risorse

Page 60: Sistemi Operativi: Processi - Lezione 07

60

Albero di processi UNIX

kernel

swapperpage daemon init

utente 1 utente 2 utente 3

Page 61: Sistemi Operativi: Processi - Lezione 07

61

Creazione di un processo UNIX• Esecuzione del processo padre dopo aver

creato un processo figlio:– Il processo padre continua l'esecuzione in

maniera concorrente con i propri figli– Il processo padre attende che alcuni o tutti i

suoi figli terminino l'esecuzione

• Esecuzione del processo figlio:– Dallo stesso punto in cui si era interrotto il

padre prima di invocare la fork()

• Spazio di indirizzamento del processo figlio:– Il processo figlio è un duplicato del padre– Il processo figlio carica un programma

Page 62: Sistemi Operativi: Processi - Lezione 07

62

System call fork()• In UNIX, ogni processo è caratterizzato da un

numero identificatore univoco (PID)• Un nuovo processo viene creato per mezzo

della syscall fork()• La syscall fork:

– Duplica il descrittore del processo padre nel descrittore del processo figlio

– Genera un nuovo PID– Inserisce il descrittore di processo del figlio

nella coda di pronto

• Valore di ritorno della fork:– PID nel processo padre– 0 nel processo figlio

Page 63: Sistemi Operativi: Processi - Lezione 07

63

System call fork()• Signature: pid_t fork(void)

– Descrizione: crea un esatto duplicato del processo chiamante

– Argomenti: nessuno– Valore di ritorno:

♦Processo padre -> PID del figlio♦Processo figlio -> 0♦-1 in caso di errore

Processo padre

stack

heap

dati

testo

fork()

Processo figlio

stack

heap

dati

testo

Entrambi i processi ripartono dall'istruzione

successiva alla fork()

nel testo

Page 64: Sistemi Operativi: Processi - Lezione 07

64

Utilizzi del meccanismo di forking• Creazione di

comandi a catena (pipeline)

find . -name '*.c' -print | wc -l

• Gestione di servizi (request serving)– Web server– FTP server– “XYZ” server

shell

s

find

f

wc

w

fork() fork()pipe()

output

Serverprocess

S

fork() fork()

Childprocess

C

Childprocess

C

richieste

risposta risposta

exec() exec()

Page 65: Sistemi Operativi: Processi - Lezione 07

65

Cattivi utilizzi del forking: fork bomb• Una fork bomb è un particolare tipo di

processo che non fa altro che riprodurre processi figli, I quali a loro volta si riproducono

• Meccanismo rozzo ma efficace di negazione dei servizi (Denial of Service, DoS)– Può essere accidentale– Di solito, è intenzionale (malizioso)

• Una fork bomb fa esplicite assunzioni sul comportamento del SO:– Tabella dei processi di dimensioni limitate

(viene saturata, non si può più eseguire niente)– Ciascun processo richiede risorse di calcolo (il

sistema rallenta considerevolmente)

Page 66: Sistemi Operativi: Processi - Lezione 07

66

Cattivi utilizzi del forking: fork bomb

bomb

b

bomb

b

bomb

b

...

bomb

b

bomb

b

bomb

b

...

bomb

b

bomb

b

bomb

b

...

...

... ... ... ...

Page 67: Sistemi Operativi: Processi - Lezione 07

67

Scheletro di una fork bomb• Il tipico scheletro di una fork bomb è un ciclo

while che, per sempre, effettua una fork()• Per peggiorare le cose, si può anche allocare

della memoria– Memory leak: alloco memoria senza liberarla– Porta molto rapidamente il sistema in swap– Nei sistemi con Copy On Write, occorre scrivere

nella memoria per creare le pagine copiawhile ( 1 ) {

x=malloc(1048576); /* 1MB */*x = 0; /* forza il Copy On Write */fork();

}

Page 68: Sistemi Operativi: Processi - Lezione 07

68

Prevenzione delle fork bomb• Soluzioni comuni:

– Il SO imposta un limite al numero di processi generati da un utente (ulimit)

– Uccisione di tutti i processi (tranne kill ed init)kill -9 -1

– Modifiche al SO per impedire la diffusione del bombing

Page 69: Sistemi Operativi: Processi - Lezione 07

69

vfork()• Variante veloce della fork(), pensata per I

processi figli che caricano immediatamente altre immagini– Scenario ideale: shell (processo padre che

forka processi figli eseguenti comandi)

• Il kernel non copia la tabella di memoria del padre nelle tabelle di memoria del figlio, ma le fa condividere finché il processo figlio:– non carica una immagine (exec())– non esce (_exit())

• Nel frattempo, il processo padre si blocca• Non esiste semantica Copy-On-Write: il figlio

può cambiare i valori delle variabili del padre

Page 70: Sistemi Operativi: Processi - Lezione 07

70

Gestione dei Process IDentifier• Signature: pid_t getpid(void)

– Descrizione: ritorna il PID del processo chiamante

– Argomenti: nessuno– Valore di ritorno: il PID del processo chiamante

• Signature: pid_t getppid(void)– Descrizione: ritorna il PID del processo padre di

quello chiamante– Argomenti: nessuno– Valore di ritorno: il PID del processo padre del

processo chiamante

Page 71: Sistemi Operativi: Processi - Lezione 07

71

Identificazione di processi• Come si possono trovare I PID dei processi in

maniera estremamente rapida?

• Comando pgrep– pgrep “stringa”– Restituisce una lista di PID associati a processi

il cui nome contiene “stringa”– pgrep init -> 1

Page 72: Sistemi Operativi: Processi - Lezione 07

72

Terminazione di un processo• La syscall exit() viene utilizzata per terminare il

programma con un codice di uscita• Alcune risorse allocate dal processo vengono

liberate dal SO– Gli stream aperti vengono svuotati (flush)– I file temporanei vengono rimossi– Viene chiamata la funzione di chiusura _exit()

• Se un processo genitore termina, tutti i suoi figli si chiamano orfani– Gli orfani diventano immediatamente figli del

processo init (che ha PID=1)

Page 73: Sistemi Operativi: Processi - Lezione 07

73

Terminazione di un processo• Variante: _exit()• Il processo esce con un codice di uscita• Non svuota gli stream aperti, non cancella i file

temporanei• Chiude i descrittori di file aperti• Quando si usa la _exit()?

– Processo figlio creato con vfork()– Processo figlio che non ha caricato una

immagine con exec()

• Si impedisce che il figlio possa modificare le risorse usate dal padre

Page 74: Sistemi Operativi: Processi - Lezione 07

74

Terminazione di un processo• Signature: void exit(int status)

– Descrizione: termina l'esecuzione del processo e fornisce un codice di uscita al processo invocante

– Argomenti: il codice di uscita♦EXIT_SUCCESS (0): tutto OK♦EXIT_FAILURE (1): errore

– Valore di ritorno: nessuno

• Si possono usare anche altri codici di uscita > 0 per discriminare diverse cause di errore

Page 75: Sistemi Operativi: Processi - Lezione 07

75

Segnali• Meccanismo di notifica asincrona di eventi ad

un processo– Asincrona: non legata ad eventi interni al kernel

• Meccanismo primitivo di Inter Process Communication (IPC)

• Un segnale è una interruzione software (eccezione), inviata ad un processo– Inviata tramite tastiera (CTRL-C da terminale)– Inviata tramite il comando kill– Inviata dal kernel (SIGSEGV)

Page 76: Sistemi Operativi: Processi - Lezione 07

76

Ciclo di vita di un segnale• I segnali UNIX hanno un ciclo di vita preciso• Step 1: un processo (o il kernel) genera un

segnale (raise, send, generate)• Step 2: il kernel conserva il segnale fino a

quando non è in grado di consegnarlo• Step 3: il kernel consegna il segnale al

processo destinatario• Step 4: il kernel esegue una azione legata al

segnale

Page 77: Sistemi Operativi: Processi - Lezione 07

77

Azioni legate ad un segnale• Quali sono le possibili azioni?• Ignorare il segnale (ignore):

– Non viene intrapresa alcuna azione– Due segnali (KILL, STOP) non possono essere

ignorati

• Gestire il segnale (catch and handle):– Sospensione dell'esecuzione del processo– Salto ad una funzione (handler) definita nel

codice del programma ed assegnata al segnale– Ripristino dell'esecuzione del processo

• Eseguire una azione di default (default action):– Il kernel esegue una azione preconfigurata (ad

es., uccisione del processo)

Page 78: Sistemi Operativi: Processi - Lezione 07

78

Identificatori di segnale• I segnali sono identificati in maniera univoca

da numeri interi positivi, a partire dal numero 1• A ciascun numero è associato una costante

simbolica avente prefisso SIG• La definizione dell'intero insieme dei segnali è

definita nel file include <bits/signum.h>• Per vedere la lista, si può utilizzare il comando

di gestione dei segnali kill:kill -l

Page 79: Sistemi Operativi: Processi - Lezione 07

79

Alcuni segnali comuni• SIGKILL (9):

– Termina istantaneamente il processo, senza possibilità di effettuare operazioni di cleanup

– Non può essere gestito con un handler

• SIGTERM (15):– termina istantaneamente il processo, con

possibilità di registrare un handler per effettuare operazioni di cleanup

• SIGINT (2):– Segnale di interruzione, inviato al processo

collegato ad un terminale, in seguito a CTRL-C– Termina il processo

Page 80: Sistemi Operativi: Processi - Lezione 07

80

Alcuni segnali comuni• SIGSEGV (11):

– Il kernel termina istantaneamente il processo, in seguito ad un accesso invalido alla memoria

– Non può essere gestito con un handler

• SIGCHLD (15):– Segnale inviato al processo padre quando un

processo figlio termina l'esecuzione

• SIGUSR1 (10), SIGUSR2 (12):– Segnali configurabili tramite handler opportuni– Azione di default: terminano il processo

• E tanti, tanti altri...

Page 81: Sistemi Operativi: Processi - Lezione 07

81

Invio di segnali: il comando kill• Il comando kill permette di inviare segnali ai

processi– kill -”id segnale” “pid processo– kill -9 8732– Occorre avere I privilegi opportuni!

• Variante pkill: identifica in maniera simbolica i segnali ed i processi– pkill -KILL program

• E da programma?– Si utilizza la syscall kill()

Page 82: Sistemi Operativi: Processi - Lezione 07

82

Syscall kill()• Signature: int kill(pid_t pid, int sig)

– Descrizione: invia il segnale identificato da sig al processo identificato da pid

– Argomenti:♦ Il PID del processo destinatario del segnale♦ L'identificatore del segnale da inviare

– Valore di ritorno:♦ 0 -> tutto OK♦ -1: si è verificato un errore

Page 83: Sistemi Operativi: Processi - Lezione 07

83

Ricezione di segnali• Si utilizza la syscall signal(), che permette di

associare ad un segnale una ben specifica funzione handler

• Che prototipo deve avere la funzione handler?– void sig_handler(int signo)

• Il file include <signal.h> definisce il tipo di dato sighandler_t come puntatore ad una funzione che vuole un intero e non ritorna niente (void)– typedef void (*sighandler_t) (int);

Page 84: Sistemi Operativi: Processi - Lezione 07

84

Syscall signal()• Signature: sighandler_t signal(int signo,

sighandler_t handler)– Descrizione: sostituisce l'azione corrente del

segnale con l'azione definita dalla funzione handler

– Argomenti:♦ L'identificatore del segnale da gestire♦ Un puntatore alla funzione handler

– SIG_DFL: azione di default– SIG_IGN: ignorare il segnale– Puntatore ad una funzione effettiva

– Valore di ritorno:♦ Il puntatore alla precedente funzione handler♦ SIG_ERR in caso di errore

Page 85: Sistemi Operativi: Processi - Lezione 07

85

Handler di segnali: alcune note• Quando il kernel consegna un segnale, il

processo può eseguire una qualunque porzione di codice– L'handler non può sapere quale

• E' importante che l'handler non esegua codice “troppo complicato”– Tipicamente, imposta dei flag “volatile”, libera

memoria, esce, non fa molto altro

• L'handler deve modificare variabili che il processo non tocca MAI

• I segnali possono essere rientranti– le syscall utilizzate all'interno dell'handler pure– man 7 signal

Page 86: Sistemi Operativi: Processi - Lezione 07

86

Sincronizzazione processo padre-figlio• Il processo padre può decidere di aspettare il

termine dell'esecuzione del processo figlio, per mezzo della syscall wait()

• La syscall wait rimuove il descrittore del processo padre dalla coda di pronto fino a che il processo figlio non termina l'esecuzione

• Quando il processo figlio termina l'esecuzione, ritorna un codice di uscita (exit status) al SO– =0: tutto OK (EXIT_SUCCESS)– =1: errore (EXIT_FAILURE)

• Il SO consegna il codice di uscita alla syscall wait

Page 87: Sistemi Operativi: Processi - Lezione 07

87

Scenario wait() tempestiva

padre

figlio

fork()

• Il processo padre crea un figlio con la fork()

• Entrambi i processi eseguono concorrentemente

Running

Tabellaprocessi

Running

PID

PID

Page 88: Sistemi Operativi: Processi - Lezione 07

88

Scenario wait() tempestiva

padre

• Il processo padre invoca la wait() prima la morte del figlio, tempestivamente

• Il processo padre viene bloccato in attesa che il figlio termini la sua esecuzione

Blocked

Tabellaprocessiwait()

Runningfiglio

Page 89: Sistemi Operativi: Processi - Lezione 07

89

Scenario wait() tempestiva

padre

figlio

• Ad un certo punto, il processo figlio termina la sua esecuzione

• Il kernel imposta lo stato del figlio a Zombie– Processo figlio morto a

tutti gli effetti

– Il PCB è ancora presente nella tabella dei processi

– PCB usato per fornire al padre il valore di uscita

Running

Tabellaprocessi

ZombieX

Page 90: Sistemi Operativi: Processi - Lezione 07

90

Scenario wait() tempestiva

padre

• Il kernel imposta a pronto il processo padre, dal momento che l'evento atteso si è verificato

• Il kernel invia un segnale SIGCHLD al padre (di solito ignorato)

• Il processo padre ritorna ad eseguire dopo la wait()

• Viene letto il codice di uscita del figlio

Running

Tabellaprocessi

RunningPID,

codiceuscita

wait()

Page 91: Sistemi Operativi: Processi - Lezione 07

91

Scenario wait() tardiva

padre

figlio

fork()

• Il processo padre crea un figlio con la fork()

• Entrambi i processi eseguono concorrentemente

Running

Tabellaprocessi

Running

PID

PID

Page 92: Sistemi Operativi: Processi - Lezione 07

92

Scenario wait() tardiva

padre

figlio

• Ad un certo punto, il processo figlio termina la sua esecuzione

• Il kernel imposta lo stato del figlio a Zombie– Processo figlio morto a

tutti gli effetti

– Il PCB è ancora presente nella tabella dei processi

– PCB usato per fornire al padre il valore di uscita

Running

Tabellaprocessi

ZombieX

Page 93: Sistemi Operativi: Processi - Lezione 07

93

Scenario wait() tardiva

padre

• Il processo padre invoca la wait() dopo la morte del figlio, tardivamente

• Il kernel invia un segnale SIGCHLD al padre (di solito ignorato)

• Viene usato il PCB del figlio per comunicare lo stato di uscita al padre

• Viene eliminato il PCB del figlio

Running

Tabellaprocessi

PID,codiceuscita

wait()

ZombieX

Page 94: Sistemi Operativi: Processi - Lezione 07

94

Scenario wait() mai invocata

padre

figlio

fork()

• Il processo padre crea un figlio con la fork()

• Entrambi i processi eseguono concorrentemente

Running

Tabellaprocessi

Running

PID

PID

Page 95: Sistemi Operativi: Processi - Lezione 07

95

Scenario wait() mai invocata

padre

figlio

• Ad un certo punto, il processo figlio termina la sua esecuzione

• Il kernel invia un segnale SIGCHLD al padre (di solito ignorato)

• Il kernel imposta lo stato del figlio a Zombie

Running

Tabellaprocessi

ZombieX• Stato Zombie

– Processo figlio morto a tutti gli effetti

– Il PCB è ancora presente nella tabella dei processi

– PCB usato per fornire al padre il valore di uscita

Page 96: Sistemi Operativi: Processi - Lezione 07

96

Scenario wait() mai invocata

padre

• Finché il padre esegue, esisterà sempre un PCB del figlio in stato Zombie

• Quando il padre termina l'esecuzione, vengono ripuliti entrambi i PCB

Exiting

Tabellaprocessi

ZombieX

XX

Page 97: Sistemi Operativi: Processi - Lezione 07

97

System call wait()• Signature: pid_t wait(int *status)

– Descrizione: sospende l'esecuzione del processo chiamante fino a quando uno dei suoi processi figli termina

– Ingresso: puntatore ad un intero utilizzato per memorizzare lo “stato” del processo

– Ritorno:♦ Il PID del processo figlio terminato♦-1 in caso di errore

Page 98: Sistemi Operativi: Processi - Lezione 07

98

System call wait()• Lo stato del processo può essere letto tramite

delle macro opportune– WIFEXITED(status): restituisce 1 se il figlio è

terminato normalmente (exit()), 0 altrimenti

– WEXITSTATUS(status): restituisce il codice di uscita del processo figlio (gli 8 bit meno significativi di status: status & 255)

– WIFSIGNALED(status): restituisce 1 se il figlio è stato terminato tramite un segnale, 0 altrimenti

– WIFSTOPPED(status): restituisce 1 se il figlio è stato interrotto (SIGSTOP), 0 altrimenti

– WIFCONTINUED(status): restituisce 1 se il figlio è stato ripristinato (SIGCONT), 0 altrimenti

– ... e tante altre (man wait)

Page 99: Sistemi Operativi: Processi - Lezione 07

99

System call waitpid()• Signature: pid_t waitpid(pid_t pid, int *status,

int options)– Descrizione: sospende l'esecuzione del

processo chiamante fino a quando uno dei suoi processi figli cambia stato

– Ingresso:♦ il PID del processo (o dell'insieme di processi) da

aspettare♦ puntatore ad un intero utilizzato per memorizzare

lo “stato” del processo♦ maschera di bit contenente le opzioni di uso

– Ritorno:♦ Il PID del processo figlio terminato♦-1 in caso di errore (errno=ECHILD)

Page 100: Sistemi Operativi: Processi - Lezione 07

100

System call waitpid()• Il primo argomento pid può assumere i

seguenti valori:– -1: aspetta un qualunque processo figlio– 0: aspetta un qualunque processo figlio con

group ID pari a quello del processo chiamante– >0: aspetta un qualunque processo figlio con

PID = pid

• Le opzioni sono le seguenti:– WNOHANG: ritorna immediatamente se nessun

figlio è uscito (non aspetta)♦torna 0 se il padre ha figli, -1 altrimenti

– WUNTRACED: considera come cambio di stato anche l'interruzione (SIGSTOP)

Page 101: Sistemi Operativi: Processi - Lezione 07

101

Caricamento di immagini• UNIX mette a disposizione una famiglia di

funzioni (exec()) per sostituire l'immagine di un processo padre con quella di un eseguibile

• La sostituzione è efficiente– Non si copia l'intero contenuto della memoria

secondaria in memoria– Si associano blocchi di memoria principale a

blocchi di memoria secondaria (memory mapping)

– Si carica il blocco in memoria centrale solo quando viene utilizzato dal processore

Page 102: Sistemi Operativi: Processi - Lezione 07

102

Caricamento di immagini

Pagina 1

Spazio indirizzamentoprocesso (RAM)

Pagina 2

...

Pagina n Blocco1

Memoria secondaria (periferica)

Blocco2

Bloccon

Page 103: Sistemi Operativi: Processi - Lezione 07

103

Caricamento di immagini

Blocco 1

Spazio indirizzamentoprocesso (RAM)

Pagina 2

...

Pagina n Blocco1

Memoria secondaria (periferica)

Blocco2

Bloccon

CPU

Sostituzione di codice:le pagine vengonosostituite quando richiestedal processore.

Page 104: Sistemi Operativi: Processi - Lezione 07

104

Syscall execl• Signature: int execl(const char *path, const

char *arg, ...)– Descrizione: carica l'immagine eseguibile del

programma di nome path, passando i parametri– Argomenti:

♦Un puntatore alla stringa contenente il percorso assoluto dell'eseguibile

♦Una lista di stringhe (terminata con NULL), che saranno assegnate ad argv[0], argv[1], ...

– Valore di ritorno:♦-1 in caso di errore

• execl() è una funzione variadica (ammette un numero variabile di argomenti)

Page 105: Sistemi Operativi: Processi - Lezione 07

105

Famiglia funzioni exec()• int execlp(const char *file, const char *arg, ...);• int execle(const char *file, const char *arg, ...,

char * const envp[]);• int execv(const char *file, const char *argv[]);• int execvp(const char *file, const char *argv[]);• int execle(const char *file, const char *arg[],

char * const envp[]);

Page 106: Sistemi Operativi: Processi - Lezione 07

106

Esecuzione semplificata• Esiste una procedura estremamente

semplificata per l'esecuzione di processi• Se si vuole eseguire un comando secco

(tipicamente, un comando di shell), senza necessità di generare più figli, si può usare la chiamata system()

• Cosa fa system()?• Padre:

– fork() di un processo figlio– wait() per aspettare l'uscita del figlio

• Figlio:– execv() di una immagine

Page 107: Sistemi Operativi: Processi - Lezione 07

107

Funzione system()• Signature: int system(const char *command)

– Descrizione: crea un processo figlio ed esegue il comando “/bin/sh -c comando”, dove comando è la stringa puntata da command

– Argomenti:♦Un puntatore alla stringa contenente il

comando♦Valore di ritorno:♦ Il codice di stato della wait()♦-1 in caso di errore

• Esercizio: implementare la system() usando le chiamate fork(), execv(), waitpid()

Page 108: Sistemi Operativi: Processi - Lezione 07

108

Una piccola avvertenza• Durante l'esecuzione del comando tramite

system, nel processo figlio– il segnale SIGCHLD è bloccato (sigprocmask)– i segnali SIGINT e SIGQUIT sono ignorati

• Se il programma è lanciato da terminale, un CTRL-C viene propagato a padre e figlio– Ma non sempre il programma è lanciato da

terminale...

• Se la funzione system() è invocata all'interno di un ciclo, bisogna esplicitamente controllare lo stato di uscita del figlio

Page 109: Sistemi Operativi: Processi - Lezione 07

109

Utenti e gruppi: modello di protezione• Il modello UNIX prevede l'attribuzione di

processi e file ad utenti e gruppi di lavoro• Utente:

– Astrazione di una singola persona– Può lanciare processi e gestire file– Identificato da uno User Id (UID), numero intero

non negativo– E' associato ad uno username e ad una

password per la verifica delle credenziali– Database utenti memorizzato in /etc/passwd– Un utente (superutente, root) ha pieni poteri di

accesso alle risorse del sistema (processi, file)

Page 110: Sistemi Operativi: Processi - Lezione 07

110

Utenti e gruppi: modello di protezione• Il modello UNIX prevede l'attribuzione di

processi e file ad utenti e gruppi di lavoro• Gruppo (di lavoro):

– Astrazione di un gruppo di persone che lavorano per uno stesso obiettivo

– Ciascun utente può far parte di più gruppi, ma ne usa uno alla volta (gruppo primario)

– Possono condividere accessi a file– Identificato da un Group Id (GID), numero intero

non negativo– E' associato ad un groupname e ad una

password per la verifica delle credenziali– Database utenti memorizzato in /etc/group

Page 111: Sistemi Operativi: Processi - Lezione 07

111

Utenti e gruppi: permessi dei file• Come impatta il modello di protezione sui file?• Semplice schema a permessi• Tre distinte categorie di utenti:

– User: UID dell'utente creatore di un file– Group: GID primario dell'utente al momento

della creazione del file– Others: il resto del mondo

• Tre distinte categorie di azioni su file:– Read: è possibile leggere da file– Write: è possibile scrivere su file– eXecute: è possibile eseguire il file

Page 112: Sistemi Operativi: Processi - Lezione 07

112

Utenti e gruppi: permessi dei file• A ciascun file è associata una maschera di bit

contenente le azioni permesse (r,w,x) per ciascuna tipologia di utenti (u,g,o)

• La maschera di bit memorizza in maniera compatta chi può accedere come al file

• Diversi tipi di rappresentazione:– Stringa: rwxrwxr-x– Ottale: 775– Azione: ugo+rwx, o-w

Page 113: Sistemi Operativi: Processi - Lezione 07

113

Utenti e gruppi: diritti dei processi• Come impatta il modello di protezione sui

processi in esecuzione sulla macchina?• In un sistema UNIX, i diritti di un processo

coincidono molto spesso con i privilegi di accesso ai file– Filosofia UNIX: tutto ciò che si esegue è un

processo, tutto ciò che si rappresenta è un file

• Gli UID e GID di un processo sono quelli utilizzati per il confronto con la maschera di bit dei file

• Ma come fa un processo ad essere associato ad un UID e ad un GID?

Page 114: Sistemi Operativi: Processi - Lezione 07

114

Utenti e gruppi: diritti dei processi• Le cose, ovviamente, non sono così semplici• Un processo UNIX si porta appresso quattro (!)

UID e quattro GID diversi per regolare i diritti di acceso ai file da parte di un processo– Filesystem User ID– Real User ID– Effective User ID– Saved User ID

• La descrizione seguente vale non solo per gli UID, ma anche per i GID!

Page 115: Sistemi Operativi: Processi - Lezione 07

115

Utenti e gruppi: Filesystem User ID• Il Filesystem User ID (UID) è lo UID associato al

file su disco• Dichiara solamente chi ha scritto

originariamente il file su disco, nient'altro!– beh, dichiara anche I permessi di accesso...– ... ma nient'altro che riguardi l'esecuzione dei

processi!

Page 116: Sistemi Operativi: Processi - Lezione 07

116

Utenti e gruppi: Real User ID• Il Real User ID (UID) è lo UID dell'utente che ha

eseguito il processo• Il Real User ID può essere (e solitamente è)

diverso dal Filesystem User ID– Filesystem: chi ha scritto il file su disco– Real: chi lo sta eseguendo ora

• Il Real User ID di un processo viene impostato a quello del suo padre– Shell: imposta il Real User ID a quello

dell'utente che la sta eseguendo– Tutti i comandi (figli) eseguono con quell'UID

• Il superutente può impostare il Real User ID a qualunque valore, gli utenti normali no

Page 117: Sistemi Operativi: Processi - Lezione 07

117

Utenti e gruppi: Effective User ID• L'Effective User ID (EUID) è lo UID effettivo con

cui il processo sta eseguendo• Tutti i controlli di accesso (a file) avvengono

tramite l'EUID• L'EUID viene ereditato dal processo padre• Un momento: ma non c'era già il Real User ID?• Sì, ed in effetti, solitamente, Real User ID ed

Effective User ID coincidono• E allora a che serve differenziare in Real User

ID ed Effective User ID?– A fare cose paranormali con i poteri di un

utente normale

Page 118: Sistemi Operativi: Processi - Lezione 07

118

Utenti e gruppi: Effective User ID• Ciascun file ha, in realtà, svariati altri bit nella

bitmask dei permessi• Tali bit sono usati per specificare particolari

proprietà di un file o di una directory• Una proprietà particolare è il Set User ID (SUID)

bit, impostabile alla stregua di un qualunque permesso– chmod +s nome_file, chmod 4xyz nome_file

• Quando viene avviato un eseguibile con SUID, il kernel imposta l'EUID del file al filesystem UID– Esecuzione con i diritti del creatore, non

dell'utente! E se il creatore è root...

Page 119: Sistemi Operativi: Processi - Lezione 07

119

Utenti e gruppi: Effective User ID• Gli utenti normali possono impostare il valore

di EUID al Real UID oppure al Saved UID (introdotto a breve)

• Il superutente può impostare l'EUID al valore che desidera

• Come trovare gli eseguibili SUID?– find / -perm -4000 2>/dev/null

• Esempio: passwd

Page 120: Sistemi Operativi: Processi - Lezione 07

120

Utenti e gruppi: Saved User ID• Il Saved User ID è una copia fedele

dell'Effective User ID di un processo, effettuata nell'istante in cui questo effettua una exec()

• Utilizzato per tenere traccia del vecchio Effective User ID prima di eseguire una immagine (potenzialmente SUID)

• Il Saved User ID è inizialmente ereditato dal processo padre

• Utenti non privilegiati non possono modificare il Saved User ID

• Il superutente può impostare il Saved User ID ad un qualunque valore

Page 121: Sistemi Operativi: Processi - Lezione 07

121

Utenti e gruppi: setuid()• Signature: int setuid(uid_t uid)

Signature: int setgid(gid_t gid)– Descrizione:

♦Se EUID=0 (root), imposta Real, Effective e Saved User Id a uid (qualunque)

♦Se EUID>0 (non root), imposta Effective User Id ad uid (uid=Real oppure uid=Saved)

– Argomenti:♦ Il nuovo User ID (uid)

– Valore di ritorno:♦0: tutto OK♦-1 in caso di errore

Page 122: Sistemi Operativi: Processi - Lezione 07

122

Utenti e gruppi: seteuid()• Signature: int seteuid(uid_t euid)

Signature: int setegid(gid_t egid)– Descrizione:

♦Se EUID=0 (root), imposta l'Effective User Id a euid (qualunque)

♦Se EUID>0 (non root), imposta l'Effective User Id ad uid (uid=Real oppure uid=Saved)

–Comportamento identico a setuid()– Argomenti:

♦ Il nuovo Effective User ID (euid)– Valore di ritorno:

♦0: tutto OK♦-1 in caso di errore

Page 123: Sistemi Operativi: Processi - Lezione 07

123

Utenti e gruppi: recupero UID• Famiglia di funzioni get...id()• Non danno mai un errore• uid_t getuid(void);• uid_t getgid(void);• uid_t geteuid(void);• uid_t getegid(void);

Page 124: Sistemi Operativi: Processi - Lezione 07

124

Una piccola applicazione• Il SO Debian definisce il gruppo games come il

gruppo dei videogiocatori– Tutti gli eseguibili dei videogiochi vengono

installati nella directory /usr/games– Permessi: rwx r-x r-x (755)– Utente: root– Primary group:

♦root (nel caso in cui non si scrivano file)♦games, con setgid (nel caso in cui si scrivano

file)• In quest'ultimo caso, chiunque esegua un

videogioco prende il gruppo effettivo games– L'user effettivo rimane sempre quello normale

Page 125: Sistemi Operativi: Processi - Lezione 07

125

Una piccola applicazione• L'applicazione videogame scrive, come gruppo

games:– Gli high score (platform, sparatutto)– L'output delle partite (giochi da tavolo)

• L'applicazione vorrebbe scrivere gli altri file col gruppo primario dell'utente che ha lanciato l'eseguibile:– Traccie di debug

• Come si ottiene questo?

Page 126: Sistemi Operativi: Processi - Lezione 07

126

Una piccola applicazione• All'inizio del programma, vengono salvati i

Real ed Effective UID e GID:ruid = getuid();

euid = geteuid();

rgid = getgid();

egid = getegid();

• Successivamente, si reimpostano UID e GID in modo tale che l'utente possa scrivere file col proprio gruppo primario:setuid(ruid);

setgid(rgid);

• Qui, rgid è il GID dell'utente normale; ora sto scrivendo I file come utente normale

Page 127: Sistemi Operativi: Processi - Lezione 07

127

Una piccola applicazione• Prima di scrivere gli high score, imposto

setuid(euid);

setgid(egid);

• Ora, il GID è di nuovo quello effettivo (games):write_high_scores(&players);

• Successivamente, reimposto UID e GID a quelli “normali”setuid(ruid);

setgid(rgid);

Page 128: Sistemi Operativi: Processi - Lezione 07

128

Job Control• Task di una shell moderna:

– Lettura comando da terminale– Creazione ed esecuzione dei relativi processi

• Spesso il comando immesso è complesso, e consta di più “comandi”(cd /src/dir && tar cf - . ) | ( cd /dst/dir && tar xf -)

• Servono meccanismi per operare su “gruppi” di processi:– Identificazione– Interruzione, terminazione– Sospensione, ripristino

• Modello di Job Control

Page 129: Sistemi Operativi: Processi - Lezione 07

129

Job Control• Job Control: insieme di tutti i meccanismi

necessari per:– identificare– sospendere e riesumare– eseguire attaccati ad un terminale– eseguire staccati da un terminaleun insieme di processi

• Tale esigenza nasce dai vecchi terminali seriali– Avevano un solo “schermo”– Ci si poteva attaccare un solo comando per

volta (foreground)– Gli altri comandi eseguivano staccati dal

terminale (background)

Page 130: Sistemi Operativi: Processi - Lezione 07

130

Job Control• Job Control: insieme di tutti i meccanismi

necessari per:– identificare– sospendere e riesumare– eseguire attaccati ad un terminale– eseguire staccati da un terminaleun insieme di processi

• Tale esigenza nasce dai vecchi terminali seriali– Avevano un solo “schermo”– Ci si poteva attaccare un solo comando per

volta (foreground)– Gli altri comandi eseguivano staccati dal

terminale (background)

Page 131: Sistemi Operativi: Processi - Lezione 07

131

Gruppi di processi• I processi sono suddivisi in gruppi di processi

(process group)• Un gruppo di processi è un insieme di processi

che possono essere segnalati tutti insieme– Segnali: Terminazione, interruzione, ripristino– Processi: i componenti di una pipeline

• Ciascun processo fa parte di un process group• Ciascun process group:

– ha un processo detto “process group leader”; è l'ultimo processo in una pipeline

– è identificato da un process group ID (PGID), pari al PID del process group leader

– esiste fino a quando ha almeno un elemento

Page 132: Sistemi Operativi: Processi - Lezione 07

132

Sessioni• Quando un utente effettua un login, il processo

login crea una nuova sessione• Sessione: un insieme di process group• All'inizio ho una solo process group di un solo

processo (la shell di login)• Tale processo prende il nome di session leader• Il PID del processo session leader è usato

come session ID (identifica la sessione)• Ciascuna sessione ha associato un dispositivo

terminale (fisico o virtuale) di controllo, che gestisce le operazioni di I/O da e verso la sessione

Page 133: Sistemi Operativi: Processi - Lezione 07

133

Foreground e Background PG• I process group all'interno di una sessione

sono suddivisi in due categorie:– Un foreground process group– Uno o più background process group

• Il foreground process group è l'unico gruppo di processi ad essere attaccato direttamente al terminale sia in ingresso che in uscita– Si può interagire con i processi in esecuzione

tramite la tastiera

• I background process group sono attaccati al terminale solamente in uscita– Possono solo scrivere sul terminale, non

possono ricevere dati da terminale

Page 134: Sistemi Operativi: Processi - Lezione 07

134

Terminali• Diversi tipi di terminale:

– Veri terminali fisici (VT100, VT102) attaccati via connessioni seriali (/dev/ttyS0)

– Emulatore di terminale classico in testo, fornito dal kernel (/dev/tty1) e prenotato da getty

♦Alt-F1 + getty->login->bash– Pseudo terminale in cui il kernel fornisce un

minimo supporto (/dev/pts/0) ed un processo arbitrario si sostituisce all'emulatore di terminale classico

♦ssh -t, xterm, gnome-terminal, kterm♦Automazione domanda-risposta con uno

(pseudo) terminale: expect–Chatscript di login del modem

Page 135: Sistemi Operativi: Processi - Lezione 07

135

Interazioni con il terminale• In che modi si può interagire con il terminale,

tramite la tastiera?– Terminazione dell'emulatore di terminale: viene

inviato un segnale SIGQUIT a tutti i processi facenti parte del foreground process group

– Disconnessione rete/seriale terminale fisico: viene inviato un segnale SIGHUP (Hangup) a tutti i processi facenti parte del foreground process group

♦Window manager testuale screen: intercetta il segnale e conserva lo stato delle finestre

– Interruzione pipeline (CTRL-C): viene inviato un segnale SIGINT a tutti i processi facenti parte del foreground process group

Page 136: Sistemi Operativi: Processi - Lezione 07

136

Interazioni con il terminale• In che modi si può interagire con il terminale,

tramite la tastiera?– Sospensione pipeline (CTRL-Z): viene inviato

un segnale SIGTSTOP a tutti i processi facenti parte del foreground process group

– Ripristino pipeline in foreground (%, fg): viene inviato un segnale SIGCONT a tutti i processi facenti parte del foreground process group sospeso

Page 137: Sistemi Operativi: Processi - Lezione 07

137

Un modello a sessioni e gruppic

login

l

Login shellSessionleader

Session

p

BG PG BG PG FG PG

Terminaledi controllo

stdin

stdoutstderr

stdoutstderr

stdoutstderr

PGleader

PGleader

PGleader

Page 138: Sistemi Operativi: Processi - Lezione 07

138

Gestione dei gruppi e delle sessioni• Esecuzione di un process group in foreground

– Si lancia una pipeline normalmentels -lR / | grep passwd | less -Mr

• Esecuzione di un process group in background– Si termina una pipeline col simbolo &ls -lR / | grep passwd > output.txt 2>&1 &

– Viene stampata una riga del tipo[1] 25647

– 1: ID del job inviato– 25647: process group ID (PiD del processo

leader del gruppo, ossia l'ultimo della pipeline, grep)

Page 139: Sistemi Operativi: Processi - Lezione 07

139

Gestione dei gruppi e delle sessioni• Visione dello stato dei process group di una

sessione: comando jobs– jobs -l: elenco completo dei process group, con

process group ID relativi e stato di esecuzione– jobs -p: elenco dei process group ID

• Sospensione del process group in foreground:– CTRL-Z

• Ripristino in background di un process group sospeso:– bg %job_id (bg in per un process group unico)

• Ripristino in foreground di un process group sospeso:– fg %job_id (fg o % per un process group unico)

Page 140: Sistemi Operativi: Processi - Lezione 07

140

Creazione di una sessione• Signature: pid_t setsid(void)

– Descrizione:♦Crea una nuova sessione♦Crea un nuovo process group all'interno

della sessione♦ Imposta il processo chiamante a session e a

group leader♦Utilizzato dalle shell e dai demoni

– Argomenti: nessuno– Valore di ritorno:

♦ Il session ID della sessione, se tutto OK♦-1 in caso di errore

• Comando setsid

Page 141: Sistemi Operativi: Processi - Lezione 07

141

Ottenimento session ID• Signature: pid_t getsid(pid_t pid)

– Descrizione: ritorna il session ID della sessione in cui si trova il processo identificato da pid

– Argomenti:♦ Il pid del processo (0: processo chiamante)

– Valore di ritorno:♦ Il session ID della sessione, se tutto OK♦-1 in caso di errore

Page 142: Sistemi Operativi: Processi - Lezione 07

142

Impostazione di un process group ID• Signature: int setpgid(pid_t pid, pid_t pgid)

– Descrizione: imposta il process group ID del processo identificato da pid a pgid

♦ Pid deve riferirsi al processo invocante o ad un suo figlio che non ha invocato exec()

♦ Pid deve essere nella stessa sessione del processo invocante

♦ Pid non deve riferirsi ad un session leader

– Argomenti:♦ Il pid del processo considerato♦ Il pgid considerato

– Valore di ritorno:♦0: tutto OK♦-1 in caso di errore

Page 143: Sistemi Operativi: Processi - Lezione 07

143

Ottenimento session ID• Signature: pid_t getpgid(pid_t pid)

– Descrizione: ritorna il process group ID del processo identificato da pid

– Argomenti:♦ Il pid del processo (0: processo chiamante)

– Valore di ritorno:♦ Il processo group ID della sessione, se tutto

OK♦-1 in caso di errore

Page 144: Sistemi Operativi: Processi - Lezione 07

144

Demoni UNIX• Il demone (daemon) è un processo che:

– esegue come figlio diretto di init– non è connesso ad alcun terminale– esegue in background

• Etimologia: Maxwell's demon (1867)http://en.wikipedia.org/wiki/Maxwell%27s_demon

• Scopi:– Gestione task di sistema– Processo server: ascolta richieste, genera figli

che producono risposte

• Solitamente, un demone è avviato da root o da un utente dedicato (apache)

Page 145: Sistemi Operativi: Processi - Lezione 07

145

Passi di creazione di un demone• Step 1: il processo invoca una fork()

– Viene creato un nuovo processo figlio– Tale processo diventerà il demone

• Step 2: nel padre, si invoca la exit()– Il padre esce e rende orfano il figlio– Il figlio diventa figlio di init– Il figlio non è un process group leader

• Step 3: il processo figlio invoca setsid()– Il figlio diventa un session leader (non essendo

un process group leader, può diventarlo)– Viene anche creato un process group di cui il

processo figlio è leader– Il figlio non ha un terminale di controllo

Page 146: Sistemi Operativi: Processi - Lezione 07

146

Passi di creazione di un demone• Step 4: il figlio invoca chdir(“/”)

– Viene impostata la directory di lavoro a /– Altrimenti la directory ereditata dal padre

potrebbe essere dovunque (dipende da dove è stato invocato il processo padre)

– Tale directory non potrebbe essere più smontata, in quanto in uso (reference!) da parte del demone

– Il demone tende a durare per tutto il ciclo di vita della macchina

– O ammazzo il demone, o non smonto il filesystem contenente la directory da cui è stato invocato il demone

Page 147: Sistemi Operativi: Processi - Lezione 07

147

Passi di creazione di un demone• Step 5: il figlio imposta la maschera dei

permessi a 0 (opzionale)• Step 6: il figlio chiude tutti i descrittori di file

– Non servono– stdin, stdout, stderr non servono perché il

demone non è connesso ad alcun terminale– Gli altri descrittori non servono perché il

demone, solitamente, non fa I/O, bensì crea processi figli per la gestione di richieste

• Step 7: i descrittori stdin, stdout, stderr vengono redirezionati a /dev/null (o a qualche logfile)