From 9b4e35959dc9df4830ce828e462893d4a776ced9 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Sun, 19 Aug 2018 02:30:34 +0200 Subject: [PATCH] =?utf8?q?Nuovo=20capitolo=20sulla=20gestione=20avanzata?= =?utf8?q?=20dei=20processi,=20in=20cui=20si=20=C3=A8=20spostata=20la=20se?= =?utf8?q?zione=20omonima=20in=20coda=20al=20capitolo=20sulla=20gestione?= =?utf8?q?=20dei=20processi=20e=20si=20metteranno=20anche=20tutte=20le=20f?= =?utf8?q?unzioni=20di=20gestione=20delle=20funzionalit=C3=A0=20di=20sicur?= =?utf8?q?ezza=20(a=20partire=20dalle=20capabilities).?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- gapil.tex | 5 +- procadv.tex | 796 +++++++++++++++++++++++++++++++++++++++++++++++++ process.tex | 14 +- prochand.tex | 815 +++------------------------------------------------ thread.tex | 3 +- 5 files changed, 841 insertions(+), 792 deletions(-) create mode 100644 procadv.tex diff --git a/gapil.tex b/gapil.tex index cbd8ba2..34d2f1b 100644 --- a/gapil.tex +++ b/gapil.tex @@ -193,14 +193,13 @@ hyperfootnotes=false]{hyperref} \include{prochand} \include{filedir} \include{fileio} -%\include{fileunix} -%\include{filestd} \include{system} \include{signal} \include{session} \include{fileadv} +\include{procadv} \include{ipc} -%\include{thread} +\include{thread} % Commentare sotto se si genera la prima parte \part{Programmazione di rete} diff --git a/procadv.tex b/procadv.tex new file mode 100644 index 0000000..4b83f8e --- /dev/null +++ b/procadv.tex @@ -0,0 +1,796 @@ +\chapter{La gestione avanzata dei processi} +\label{cha:proc_advanced} + +In questo capitolo affronteremo le tematiche relative alla gestione avanzata +dei processi, trattando le \textit{system call} dedicate alle funzionalità più +specifiche ed avanzate, il cui uso è in genere piuttosto ridotto. Inizieremo +con le funzioni che attengono agli aspetti di controllo, passando alle +gestione delle modalità di creazione ed alle funzionalità attinenti i +\textit{namespace} e le funzionalità avanzate relative alla gestione della +sicurezza. Infine affronteremo le funzioni di gestione per una serie di +funzionalità specialistiche come la gestione della virgola mobile, le porte di +I/O ecc. + +\section{Funzioni di gestione e controllo} +\label{sec:proc_manage_control} + +In questa sezione prenderemo in esame alcune specifice \textit{system call} +dedicate al controllo processi sia per quanto riguarda l'impostazione di +caratteristiche specialistiche, che per quanto riguarda l'analisi ed il +controllo della loro esecuzione. + +\subsection{La funzione \func{prctl}} +\label{sec:process_prctl} + +Benché la gestione ordinaria dei processi possa essere effettuata attraverso +le funzioni che abbiamo già esaminato nei capitoli \ref{cha:process_interface} +e \ref{cha:process_handling}, esistono una serie di proprietà e +caratteristiche specifiche dei proecessi per la cui gestione è stata +predisposta una apposita \textit{system call} che fornisce una interfaccia +generica per tutte le operazioni specialistiche. La funzione di sistema è +\funcd{prctl} ed il suo prototipo è:\footnote{la funzione non è standardizzata + ed è specifica di Linux, anche se ne esiste una analoga in IRIX; è stata + introdotta con il kernel 2.1.57.} + +\begin{funcproto}{ +\fhead{sys/prctl.h} +\fdecl{int prctl(int option, unsigned long arg2, unsigned long arg3, unsigned + long arg4, \\ +\phantom{int prctl(}unsigned long arg5)} +\fdesc{Esegue una operazione speciale sul processo corrente.} +} + +{La funzione ritorna $0$ o un valore positivo dipendente dall'operazione in + caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà + valori diversi a seconda del tipo di operazione richiesta, sono possibili: + \errval{EACCESS}, \errval{EBADF}, \errval{EBUSY}, \errval{EFAULT}, + \errval{EINVAL}, \errval{ENXIO}, \errval{EOPNOTSUPP} o \errval{EPERM}.} +\end{funcproto} + +La funzione ritorna in caso di successo un valore nullo o positivo, e $-1$ in +caso di errore. Il significato degli argomenti della funzione successivi al +primo, il valore di ritorno in caso di successo, il tipo di errore restituito +in \var{errno} dipendono dall'operazione eseguita, indicata tramite il primo +argomento, \param{option}. Questo è un valore intero che identifica +l'operazione, e deve essere specificato con l'uso di una delle costanti +predefinite del seguente elenco.\footnote{l'elenco potrebbe non risultare + aggiornato, in quanto nuove operazioni vengono aggiunte nello sviluppo del + kernel.} Tratteremo esplicitamente per ciascuna di esse il significato del +il valore di ritorno in caso di successo, ma solo quando non corrisponde +all'ordinario valore nullo (dato per implicito). + +%TODO: trattare PR_CAP_AMBIENT, dal 4.3 +%TODO: trattare PR_CAP_FP_*, dal 4.0, solo per MIPS +%TODO: trattare PR_MPX_*_MANAGEMENT, dal 3.19 +%TODO: trattare PR_*NO_NEW_PRIVS, dal 3.5 + +\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}} +\item[\constd{PR\_CAPBSET\_READ}] Controlla la disponibilità di una delle + \textit{capability} (vedi sez.~\ref{sec:proc_capabilities}). La funzione + ritorna 1 se la capacità specificata nell'argomento \param{arg2} (con una + delle costanti di tab.~\ref{tab:proc_capabilities}) è presente nel + \textit{capabilities bounding set} del processo e zero altrimenti, + se \param{arg2} non è un valore valido si avrà un errore di \errval{EINVAL}. + Introdotta a partire dal kernel 2.6.25. + +\item[\constd{PR\_CAPBSET\_DROP}] Rimuove permanentemente una delle + \textit{capabilities} (vedi sez.~\ref{sec:proc_capabilities}) dal processo e + da tutti i suoi discendenti. La funzione cancella la capacità specificata + nell'argomento \param{arg2} con una delle costanti di + tab.~\ref{tab:proc_capabilities} dal \textit{capabilities bounding set} del + processo. L'operazione richiede i privilegi di amministratore (la capacità + \const{CAP\_SETPCAP}), altrimenti la chiamata fallirà con un errore di + \errcode{EPERM}; se il valore di \param{arg2} non è valido o se il supporto + per le \textit{file capabilities} non è stato compilato nel kernel la + chiamata fallirà con un errore di \errval{EINVAL}. Introdotta a partire dal + kernel 2.6.25. + +\item[\constd{PR\_SET\_DUMPABLE}] Imposta il flag che determina se la + terminazione di un processo a causa di un segnale per il quale è prevista la + generazione di un file di \textit{core dump} (vedi + sez.~\ref{sec:sig_standard}) lo genera effettivamente. In genere questo flag + viene attivato automaticamente, ma per evitare problemi di sicurezza (la + generazione di un file da parte di processi privilegiati può essere usata + per sovrascriverne altri) viene cancellato quando si mette in esecuzione un + programma con i bit \acr{suid} e \acr{sgid} attivi (vedi + sez.~\ref{sec:file_special_perm}) o con l'uso delle funzioni per la modifica + degli \ids{UID} dei processi (vedi sez.~\ref{sec:proc_setuid}). + + L'operazione è stata introdotta a partire dal kernel 2.3.20, fino al kernel + 2.6.12 e per i kernel successivi al 2.6.17 era possibile usare solo un + valore 0 (espresso anche come \constd{SUID\_DUMP\_DISABLE}) di \param{arg2} + per disattivare il flag ed un valore 1 (espresso anche come + \constd{SUID\_DUMP\_USER}) per attivarlo. Nei kernel dal 2.6.13 al 2.6.17 è + stato supportato anche il valore 2, che causava la generazione di un + \textit{core dump} leggibile solo dall'amministratore, ma questa + funzionalità è stata rimossa per motivi di sicurezza, in quanto consentiva + ad un utente normale di creare un file di \textit{core dump} appartenente + all'amministratore in directory dove l'utente avrebbe avuto permessi di + accesso. Specificando un valore diverso da 0 o 1 si ottiene un errore di + \errval{EINVAL}. + +\item[\constd{PR\_GET\_DUMPABLE}] Ottiene come valore di ritorno della funzione + lo stato corrente del flag che controlla la effettiva generazione dei + \textit{core dump}. Introdotta a partire dal kernel 2.3.20. + +\item[\constd{PR\_SET\_ENDIAN}] Imposta la \textit{endianness} del processo + chiamante secondo il valore fornito in \param{arg2}. I valori possibili sono + sono: \constd{PR\_ENDIAN\_BIG} (\textit{big endian}), + \constd{PR\_ENDIAN\_LITTLE} (\textit{little endian}), e + \constd{PR\_ENDIAN\_PPC\_LITTLE} (lo pseudo \textit{little endian} del + PowerPC). Introdotta a partire dal kernel 2.6.18, solo per architettura + PowerPC. + +\item[\constd{PR\_GET\_ENDIAN}] Ottiene il valore della \textit{endianness} del + processo chiamante, salvato sulla variabile puntata da \param{arg2} che deve + essere passata come di tipo ``\ctyp{int *}''. Introdotta a partire dal + kernel 2.6.18, solo su PowerPC. + +\item[\constd{PR\_SET\_FPEMU}] Imposta i bit di controllo per l'emulazione + della virgola mobile su architettura ia64, secondo il valore + di \param{arg2}, si deve passare \constd{PR\_FPEMU\_NOPRINT} per emulare in + maniera trasparente l'accesso alle operazioni in virgola mobile, o + \constd{PR\_FPEMU\_SIGFPE} per non emularle ed inviare il segnale + \signal{SIGFPE} (vedi sez.~\ref{sec:sig_prog_error}). Introdotta a partire + dal kernel 2.4.18, solo su architettura ia64. + +\item[\constd{PR\_GET\_FPEMU}] Ottiene il valore dei flag di controllo + dell'emulazione della virgola mobile, salvato all'indirizzo puntato + da \param{arg2}, che deve essere di tipo ``\ctyp{int *}''. Introdotta a + partire dal kernel 2.4.18, solo su architettura ia64. + +\item[\constd{PR\_SET\_FPEXC}] Imposta la modalità delle eccezioni in virgola + mobile (\textit{floating-point exception mode}) al valore di \param{arg2}. + I valori possibili sono: + \begin{itemize*} + \item \constd{PR\_FP\_EXC\_SW\_ENABLE} per usare FPEXC per le eccezioni, + \item \constd{PR\_FP\_EXC\_DIV} per la divisione per zero in virgola mobile, + \item \constd{PR\_FP\_EXC\_OVF} per gli overflow, + \item \constd{PR\_FP\_EXC\_UND} per gli underflow, + \item \constd{PR\_FP\_EXC\_RES} per risultati non esatti, + \item \constd{PR\_FP\_EXC\_INV} per operazioni invalide, + \item \constd{PR\_FP\_EXC\_DISABLED} per disabilitare le eccezioni, + \item \constd{PR\_FP\_EXC\_NONRECOV} per usare la modalità di eccezione + asincrona non recuperabile, + \item \constd{PR\_FP\_EXC\_ASYNC} per usare la modalità di eccezione + asincrona recuperabile, + \item \constd{PR\_FP\_EXC\_PRECISE} per la modalità precisa di + eccezione.\footnote{trattasi di gestione specialistica della gestione + delle eccezioni dei calcoli in virgola mobile che, i cui dettagli al + momento vanno al di là dello scopo di questo testo.} + \end{itemize*} +Introdotta a partire dal kernel 2.4.21, solo su PowerPC. + +\item[\constd{PR\_GET\_FPEXC}] Ottiene il valore della modalità delle eccezioni + delle operazioni in virgola mobile, salvata all'indirizzo + puntato \param{arg2}, che deve essere di tipo ``\ctyp{int *}''. Introdotta + a partire dal kernel 2.4.21, solo su PowerPC. + +\item[\constd{PR\_SET\_KEEPCAPS}] Consente di controllare quali + \textit{capabilities} vengono cancellate quando si esegue un cambiamento di + \ids{UID} del processo (per i dettagli si veda + sez.~\ref{sec:proc_capabilities}, in particolare quanto illustrato a + pag.~\pageref{sec:capability-uid-transition}). Un valore nullo (il default) + per \param{arg2} comporta che vengano cancellate, il valore 1 che vengano + mantenute, questo valore viene sempre cancellato attraverso una \func{exec}. + L'uso di questo flag è stato sostituito, a partire dal kernel 2.6.26, dal + flag \const{SECURE\_KEEP\_CAPS} dei \textit{securebits} (vedi + sez.~\ref{sec:proc_capabilities} e l'uso di \const{PR\_SET\_SECUREBITS} più + avanti) e si è impostato con essi \const{SECURE\_KEEP\_CAPS\_LOCKED} si + otterrà un errore di \errval{EPERM}. Introdotta a partire dal kernel + 2.2.18. + +\item[\constd{PR\_GET\_KEEPCAPS}] Ottiene come valore di ritorno della funzione + il valore del flag di controllo delle \textit{capabilities} impostato con + \const{PR\_SET\_KEEPCAPS}. Introdotta a partire dal kernel 2.2.18. + +\item[\constd{PR\_SET\_NAME}] Imposta il nome del processo chiamante alla + stringa puntata da \param{arg2}, che deve essere di tipo ``\ctyp{char *}''. Il + nome può essere lungo al massimo 16 caratteri, e la stringa deve essere + terminata da NUL se più corta. Introdotta a partire dal kernel 2.6.9. + +\item[\constd{PR\_GET\_NAME}] Ottiene il nome del processo chiamante nella + stringa puntata da \param{arg2}, che deve essere di tipo ``\ctyp{char *}''; + si devono allocare per questo almeno 16 byte, e il nome sarà terminato da + NUL se più corto. Introdotta a partire dal kernel 2.6.9. + +\item[\constd{PR\_SET\_PDEATHSIG}] Consente di richiedere l'emissione di un + segnale, che sarà ricevuto dal processo chiamante, in occorrenza della + terminazione del proprio processo padre; in sostanza consente di invertire + il ruolo di \signal{SIGCHLD}. Il valore di \param{arg2} deve indicare il + numero del segnale, o 0 per disabilitare l'emissione. Il valore viene + automaticamente cancellato per un processo figlio creato con \func{fork}. + Introdotta a partire dal kernel 2.1.57. + +\item[\constd{PR\_GET\_PDEATHSIG}] Ottiene il valore dell'eventuale segnale + emesso alla terminazione del padre, salvato all'indirizzo + puntato \param{arg2}, che deve essere di tipo ``\ctyp{int *}''. Introdotta a + partire dal kernel 2.3.15. + +\item[\constd{PR\_SET\_PTRACER}] Imposta un \ids{PID} per il ``\textit{tracer + process}'' usando \param{arg2}. Una impostazione successiva sovrascrive la + precedente, ed un valore nullo cancella la disponibilità di un + ``\textit{tracer process}''. Questa è una funzionalità fornita da + \textit{``Yama''}, uno specifico \textit{Linux Security Modules}, e serve a + consentire al processo indicato, quando le restrizioni introdotte da questo + modulo sono attive, di usare \func{ptrace}\unavref{ (vedi + sez.\ref{sec:process_ptrace})} sul processo chiamante, anche se quello + indicato non ne è un progenitore. Il valore \constd{PR\_SET\_PTRACER\_ANY} + consente a tutti i processi l'uso di \func{ptrace}. L'uso si \textit{Yama} + attiene alla gestione della sicurezza dei processi, e consente di introdurre + una restrizione all'uso di \func{ptrace}, che è spesso sorgente di + compromissioni. Si tratta di un uso specialistico che va al di là dello + scopo di queste dispense, per i dettagli si consulti la documentazione su + \textit{Yama} nei sorgenti del kernel. Introdotta a partire dal kernel 3.4. + +\itindbeg{secure~computing~mode} +\item[\constd{PR\_SET\_SECCOMP}] Imposta il cosiddetto \textit{secure computing + mode} per il processo corrente. Prevede come unica possibilità + che \param{arg2} sia impostato ad 1. Una volta abilitato il \textit{secure + computing mode} il processo potrà utilizzare soltanto un insieme + estremamente limitato di \textit{system call}: \func{read}, \func{write}, + \func{\_exit} e \funcm{sigreturn}. Ogni altra \textit{system call} porterà + all'emissione di un \signal{SIGKILL} (vedi sez.~\ref{sec:sig_termination}). + Il \textit{secure computing mode} è stato ideato per fornire un supporto per + l'esecuzione di codice esterno non fidato e non verificabile a scopo di + calcolo;\footnote{lo scopo è quello di poter vendere la capacità di calcolo + della proprio macchina ad un qualche servizio di calcolo distribuito senza + comprometterne la sicurezza eseguendo codice non sotto il proprio + controllo.} in genere i dati vengono letti o scritti grazie ad un socket o + una \textit{pipe}, e per evitare problemi di sicurezza non sono possibili + altre operazioni se non quelle citate. Introdotta a partire dal kernel + 2.6.23, disponibile solo se si è abilitato il supporto nel kernel con + \texttt{CONFIG\_SECCOMP}. + +% TODO a partire dal kernel 3.5 è stato introdotto la possibilità di usare un +% terzo argomento se il secondo è SECCOMP_MODE_FILTER, vedi +% Documentation/prctl/seccomp_filter.txt +% vedi anche http://lwn.net/Articles/600250/ + +% TODO documentare PR_SET_SECCOMP introdotto a partire dal kernel 3.5. Vedi: +% * Documentation/prctl/seccomp_filter.txt +% * http://lwn.net/Articles/475043/ + +% TODO a partire dal kernel 3.17 è stata introdotta la nuova syscall seccomp, +% vedi http://lwn.net/Articles/600250/ e http://lwn.net/Articles/603321/ + +\item[\constd{PR\_GET\_SECCOMP}] Ottiene come valore di ritorno della funzione + lo stato corrente del \textit{secure computing mode}, al momento attuale la + funzione è totalmente inutile in quanto l'unico valore ottenibile è 0, dato + che la chiamata di questa funzione in \textit{secure computing mode} + comporterebbe l'emissione di \signal{SIGKILL}, è stata comunque definita per + eventuali estensioni future. Introdotta a partire dal kernel 2.6.23. +\itindend{secure~computing~mode} + +\item[\constd{PR\_SET\_SECUREBITS}] Imposta i \textit{securebits} per il + processo chiamante al valore indicato da \param{arg2}; per i dettagli sul + significato dei \textit{securebits} si veda + sez.~\ref{sec:proc_capabilities}, ed in particolare i valori di + tab.~\ref{tab:securebits_values} e la relativa trattazione. L'operazione + richiede i privilegi di amministratore (la capacità \const{CAP\_SETPCAP}), + altrimenti la chiamata fallirà con un errore di \errval{EPERM}. Introdotta a + partire dal kernel 2.6.26. + +\item[\constd{PR\_GET\_SECUREBITS}] Ottiene come valore di ritorno della + funzione l'impostazione corrente per i \textit{securebits}. Introdotta a + partire dal kernel 2.6.26. + +\item[\constd{PR\_SET\_TIMING}] Imposta il metodo di temporizzazione del + processo da indicare con il valore di \param{arg2}, attualmente i valori + possibili sono due, con \constd{PR\_TIMING\_STATISTICAL} si usa il metodo + statistico tradizionale, con \constd{PR\_TIMING\_TIMESTAMP} il più accurato + basato su dei \textit{timestamp}, quest'ultimo però non è ancora + implementato ed il suo uso comporta la restituzione di un errore di + \errval{EINVAL}. Introdotta a partire dal kernel 2.6.0-test4. + +\item[\constd{PR\_GET\_TIMING}] Ottiene come valore di ritorno della funzione + il metodo di temporizzazione del processo attualmente in uso (uno dei due + valori citati per \const{PR\_SET\_TIMING}). Introdotta a partire dal kernel + 2.6.0-test4. + +\item[\constd{PR\_SET\_TSC}] Imposta il flag che indica se il processo + chiamante può leggere il registro di processore contenente il contatore dei + \textit{timestamp} (TSC, o \textit{Time Stamp Counter}) da indicare con il + valore di \param{arg2}. Si deve specificare \constd{PR\_TSC\_ENABLE} per + abilitare la lettura o \constd{PR\_TSC\_SIGSEGV} per disabilitarla con la + generazione di un segnale di \signal{SIGSEGV} (vedi + sez.~\ref{sec:sig_prog_error}). La lettura viene automaticamente + disabilitata se si attiva il \textit{secure computing mode} (vedi + \const{PR\_SET\_SECCOMP}). Introdotta a partire dal kernel + 2.6.26, solo su x86. + +\item[\constd{PR\_GET\_TSC}] Ottiene il valore del flag che controlla la + lettura del contattore dei \textit{timestamp}, salvato all'indirizzo + puntato \param{arg2}, che deve essere di tipo ``\ctyp{int *}''. Introdotta a + partire dal kernel 2.6.26, solo su x86. +% articoli sul TSC e relativi problemi: http://lwn.net/Articles/209101/, +% http://blog.cr0.org/2009/05/time-stamp-counter-disabling-oddities.html, +% http://en.wikipedia.org/wiki/Time_Stamp_Counter + +\item[\constd{PR\_SET\_UNALIGN}] Imposta la modalità di controllo per l'accesso + a indirizzi di memoria non allineati, che in varie architetture risultano + illegali, da indicare con il valore di \param{arg2}. Si deve specificare il + valore \constd{PR\_UNALIGN\_NOPRINT} per ignorare gli accessi non allineati, + ed il valore \constd{PR\_UNALIGN\_SIGBUS} per generare un segnale di + \signal{SIGBUS} (vedi sez.~\ref{sec:sig_prog_error}) in caso di accesso non + allineato. Introdotta con diverse versioni su diverse architetture. + +\item[\const{PR\_GET\_UNALIGN}] Ottiene il valore della modalità di controllo + per l'accesso a indirizzi di memoria non allineati, salvato all'indirizzo + puntato \param{arg2}, che deve essere di tipo \code{(int *)}. Introdotta con + diverse versioni su diverse architetture. +\item[\const{PR\_MCE\_KILL}] Imposta la politica di gestione degli errori + dovuti a corruzione della memoria per problemi hardware. Questo tipo di + errori vengono riportati dall'hardware di controllo della RAM e vengono + gestiti dal kernel,\footnote{la funzionalità è disponibile solo sulle + piattaforme più avanzate che hanno il supporto hardware per questo tipo di + controlli.} ma devono essere opportunamente riportati ai processi che + usano quella parte di RAM che presenta errori; nel caso specifico questo + avviene attraverso l'emissione di un segnale di \signal{SIGBUS} (vedi + sez.~\ref{sec:sig_prog_error}).\footnote{in particolare viene anche + impostato il valore di \var{si\_code} in \struct{siginfo\_t} a + \const{BUS\_MCEERR\_AO}; per il significato di tutto questo si faccia + riferimento alla trattazione di sez.~\ref{sec:sig_sigaction}.} + + Il comportamento di default prevede che per tutti i processi si applichi la + politica generale di sistema definita nel file + \sysctlfiled{vm/memory\_failure\_early\_kill}, ma specificando + per \param{arg2} il valore \constd{PR\_MCE\_KILL\_SET} è possibile impostare + con il contenuto di \param{arg3} una politica specifica del processo + chiamante. Si può tornare alla politica di default del sistema utilizzando + invece per \param{arg2} il valore \constd{PR\_MCE\_KILL\_CLEAR}. In tutti i + casi, per compatibilità con eventuali estensioni future, tutti i valori + degli argomenti non utilizzati devono essere esplicitamente posti a zero, + pena il fallimento della chiamata con un errore di \errval{EINVAL}. + + In caso di impostazione di una politica specifica del processo con + \const{PR\_MCE\_KILL\_SET} i valori di \param{arg3} possono essere soltanto + due, che corrispondono anche al valore che si trova nell'impostazione + generale di sistema di \texttt{memory\_failure\_early\_kill}, con + \constd{PR\_MCE\_KILL\_EARLY} si richiede l'emissione immediata di + \signal{SIGBUS} non appena viene rilevato un errore, mentre con + \constd{PR\_MCE\_KILL\_LATE} il segnale verrà inviato solo quando il processo + tenterà un accesso alla memoria corrotta. Questi due valori corrispondono + rispettivamente ai valori 1 e 0 di + \texttt{memory\_failure\_early\_kill}.\footnote{in sostanza nel primo caso + viene immediatamente inviato il segnale a tutti i processi che hanno la + memoria corrotta mappata all'interno del loro spazio degli indirizzi, nel + secondo caso prima la pagina di memoria viene tolta dallo spazio degli + indirizzi di ciascun processo, mentre il segnale viene inviato solo quei + processi che tentano di accedervi.} Si può usare per \param{arg3} anche un + terzo valore, \constd{PR\_MCE\_KILL\_DEFAULT}, che corrisponde a impostare + per il processo la politica di default.\footnote{si presume la politica di + default corrente, in modo da non essere influenzati da un eventuale + successivo cambiamento della stessa.} Introdotta a partire dal kernel + 2.6.32. +\item[\constd{PR\_MCE\_KILL\_GET}] Ottiene come valore di ritorno della + funzione la politica di gestione degli errori dovuti a corruzione della + memoria. Tutti gli argomenti non utilizzati (al momento tutti) devono essere + nulli pena la ricezione di un errore di \errval{EINVAL}. Introdotta a + partire dal kernel 2.6.32. +\itindbeg{child~reaper} +\item[\constd{PR\_SET\_CHILD\_SUBREAPER}] Se \param{arg2} è diverso da zero + imposta l'attributo di \textit{child reaper} per il processo, se nullo lo + cancella. Lo stato di \textit{child reaper} è una funzionalità, introdotta + con il kernel 3.4, che consente di far svolgere al processo che ha questo + attributo il ruolo di ``\textsl{genitore adottivo}'' per tutti i processi + suoi ``\textsl{discendenti}'' che diventano orfani, in questo modo il + processo potrà ricevere gli stati di terminazione alla loro uscita, + sostituendo in questo ruolo \cmd{init} (si ricordi quanto illustrato in + sez.~\ref{sec:proc_termination}). Il meccanismo è stato introdotto ad uso + dei programmi di gestione dei servizi, per consentire loro di ricevere gli + stati di terminazione di tutti i processi che lanciano, anche se questi + eseguono una doppia \func{fork}; nel comportamento ordinario infatti questi + verrebbero adottati da \cmd{init} ed il programma che li ha lanciati non + sarebbe più in grado di riceverne lo stato di terminazione. Se un processo + con lo stato di \textit{child reaper} termina prima dei suoi discendenti, + svolgerà questo ruolo il più prossimo antenato ad avere lo stato di + \textit{child reaper}, +\item[\constd{PR\_GET\_CHILD\_SUBREAPER}] Ottiene l'impostazione relativa allo + lo stato di \textit{child reaper} del processo chiamante, salvata come + \textit{value result} all'indirizzo puntato da \param{arg2} (da indicare + come di tipo \code{int *}). Il valore viene letto come valore logico, se + diverso da 0 lo stato di \textit{child reaper} è attivo altrimenti è + disattivo. Introdotta a partire dal kernel 3.4. +\itindend{child~reaper} + + +% TODO documentare PR_MPX_INIT e PR_MPX_RELEASE, vedi +% http://lwn.net/Articles/582712/ + +% TODO documentare PR_SET_MM_MAP aggiunta con il kernel 3.18, per impostare i +% parametri di base del layout dello spazio di indirizzi di un processo (area +% codice e dati, stack, brack pointer ecc. vedi +% http://git.kernel.org/linus/f606b77f1a9e362451aca8f81d8f36a3a112139e + +% TODO documentare ARCH_SET_CPUID e ARCH_GET_CPUID, introdotte con il kernel +% 4.12, vedi https://lwn.net/Articles/721182/ +\label{sec:prctl_operation} +\end{basedescript} + + +%\subsection{La funzione \func{ptrace}} +%\label{sec:process_ptrace} + +%Da fare + +% TODO: trattare PTRACE_SEIZE, aggiunta con il kernel 3.1 +% TODO: trattare PTRACE_O_EXITKILL, aggiunta con il kernel 3.8 (vedi +% http://lwn.net/Articles/529060/) +% TODO: trattare PTRACE_GETSIGMASK e PTRACE_SETSIGMASK introdotte con il +% kernel 3.11 +% TODO: trattare PTRACE_O_SUSPEND_SECCOMP, aggiunta con il kernel 4.3, vedi +% http://lwn.net/Articles/656675/ + + +\section{La gestione avanzata della creazione dei processi} +\label{sec:process_adv_creation} + +In questa sezione tratteremo le funzionalità avanzate relative alla creazione +dei processi e del loro ambiente, sia per quanto riguarda l'utilizzo delle +stesse per la creazione dei \textit{thread} che per la gestione dei +\textit{namespace} che sono alla base dei cosidetti \textit{container}. + + +\subsection{La \textit{system call} \func{clone}} +\label{sec:process_clone} + +La funzione tradizionale con cui creare un nuovo processo in un sistema +Unix-like, come illustrato in sez.~\ref{sec:proc_fork}, è \func{fork}, ma con +l'introduzione del supporto del kernel per i \textit{thread}\unavref{ (vedi + cap.~\ref{cha:threads})}, si è avuta la necessità di una interfaccia che +consentisse un maggiore controllo sulla modalità con cui vengono creati nuovi +processi, che poi è stata utilizzata anche per fornire supporto per le +tecnologie di virtualizzazione dei processi (i cosiddetti \textit{container}) +su cui torneremo in sez.~\ref{sec:process_namespaces}. + +Per questo l'interfaccia per la creazione di un nuovo processo è stata +delegata ad una nuova \textit{system call}, \funcm{sys\_clone}, che consente +di reimplementare anche la tradizionale \func{fork}. In realtà in questo caso +più che di nuovi processi si può parlare della creazioni di nuovi +``\textit{task}'' del kernel che possono assumere la veste sia di un processo +classico isolato dagli altri come quelli trattati finora, che di un +\textit{thread} in cui la memoria viene condivisa fra il processo chiamante ed +il nuovo processo creato, come quelli che vedremo in +sez.~\ref{sec:linux_thread}. Per evitare confusione fra \textit{thread} e +processi ordinari, abbiamo deciso di usare la nomenclatura \textit{task} per +indicare la unità di esecuzione generica messa a disposizione del kernel che +\texttt{sys\_clone} permette di creare. + +La \textit{system call} richiede soltanto due argomenti: il +primo, \param{flags}, consente di controllare le modalità di creazione del +nuovo \textit{task}, il secondo, \param{child\_stack}, imposta l'indirizzo +dello \textit{stack} per il nuovo \textit{task}, e deve essere indicato quando +si intende creare un \textit{thread}. L'esecuzione del programma creato da +\func{sys\_clone} riprende, come per \func{fork}, da dopo l'esecuzione della +stessa. + +La necessità di avere uno \textit{stack} alternativo c'è solo quando si +intende creare un \textit{thread}, in tal caso infatti il nuovo \textit{task} +vede esattamente la stessa memoria del \textit{task} +``\textsl{padre}'',\footnote{in questo caso per padre si intende semplicemente + il \textit{task} che ha eseguito \func{sys\_clone} rispetto al \textit{task} + da essa creato, senza nessuna delle implicazioni che il concetto ha per i + processi.} e nella sua esecuzione alla prima chiamata di una funzione +andrebbe a scrivere sullo \textit{stack} usato anche dal padre (si ricordi +quanto visto in sez.~\ref{sec:proc_mem_layout} riguardo all'uso dello +\textit{stack}). + +Per evitare di doversi garantire contro la evidente possibilità di +\textit{race condition} che questa situazione comporta (vedi +sez.~\ref{sec:proc_race_cond} per una spiegazione della problematica) è +necessario che il chiamante allochi preventivamente un'area di memoria. In +genere lo si fa con una \func{malloc} che allochi un buffer che la funzione +imposterà come \textit{stack} del nuovo processo, avendo ovviamente cura di +non utilizzarlo direttamente nel processo chiamante. + +In questo modo i due \textit{task} avranno degli \textit{stack} indipendenti e +non si dovranno affrontare problematiche di \textit{race condition}. Si tenga +presente inoltre che in molte architetture di processore lo \textit{stack} +cresce verso il basso, pertanto in tal caso non si dovrà specificare +per \param{child\_stack} il puntatore restituito da \func{malloc}, ma un +puntatore alla fine del buffer da essa allocato. + +Dato che tutto ciò è necessario solo per i \textit{thread} che condividono la +memoria, la \textit{system call}, a differenza della funzione di libreria che +vedremo a breve, consente anche di passare per \param{child\_stack} il valore +\val{NULL}, che non imposta un nuovo \textit{stack}. Se infatti si crea un +processo, questo ottiene un suo nuovo spazio degli indirizzi (è sottinteso +cioè che non si stia usando il flag \const{CLONE\_VM} che vedremo a breve) ed +in questo caso si applica la semantica del \textit{copy on write} illustrata +in sez.~\ref{sec:proc_fork}, per cui le pagine dello \textit{stack} verranno +automaticamente copiate come le altre e il nuovo processo avrà un suo +\textit{stack} totalmente indipendente da quello del padre. + +Dato che l'uso principale della nuova \textit{system call} è quello relativo +alla creazione dei \textit{thread}, la \acr{glibc} definisce una funzione di +libreria con una sintassi diversa, orientata a questo scopo, e la +\textit{system call} resta accessibile solo se invocata esplicitamente come +visto in sez.~\ref{sec:proc_syscall}.\footnote{ed inoltre per questa + \textit{system call} non è disponibile la chiamata veloce con + \texttt{vsyscall}.} La funzione di libreria si chiama semplicemente +\funcd{clone} ed il suo prototipo è: + +\begin{funcproto}{ +\fhead{sched.h} +\fdecl{int clone(int (*fn)(void *), void *child\_stack, int flags, void *arg, + ... \\ +\phantom{int clone(}/* pid\_t *ptid, struct user\_desc *tls, pid\_t *ctid */ )} +\fdesc{Crea un nuovo processo o \textit{thread}.} +} +{La funzione ritorna il \textit{Thread ID} assegnato al nuovo processo in caso + di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei + valori: +\begin{errlist} + \item[\errcode{EAGAIN}] sono già in esecuzione troppi processi. + \item[\errcode{EINVAL}] si è usata una combinazione non valida di flag o + un valore nullo per \param{child\_stack}. + \item[\errcode{ENOMEM}] non c'è memoria sufficiente per creare una nuova + \texttt{task\_struct} o per copiare le parti del contesto del chiamante + necessarie al nuovo \textit{task}. + \item[\errcode{EPERM}] non si hanno i privilegi di amministratore + richiesti dai flag indicati. +\end{errlist}} +\end{funcproto} + +% NOTE: una pagina con la descrizione degli argomenti: +% * http://www.lindevdoc.org/wiki/Clone + +La funzione prende come primo argomento \param{fn} il puntatore alla funzione +che verrà messa in esecuzione nel nuovo processo, che può avere un unico +argomento di tipo puntatore a \ctyp{void}, il cui valore viene passato dal +terzo argomento \param{arg}. Per quanto il precedente prototipo possa +intimidire nella sua espressione, in realtà l'uso è molto semplice basterà +definire una qualunque funzione \param{fn} che restituisce un intero ed ha +come argomento un puntatore a \ctyp{void}, e \code{fn(arg)} sarà eseguita in +un nuovo processo. + +Il nuovo processo resterà in esecuzione fintanto che la funzione \param{fn} +non ritorna, o esegue \func{exit} o viene terminata da un segnale. Il valore +di ritorno della funzione (o quello specificato con \func{exit}) verrà +utilizzato come stato di uscita della funzione. I tre +argomenti \param{ptid}, \param{tls} e \param{ctid} sono opzionali e sono +presenti solo a partire dal kernel 2.6 e sono stati aggiunti come supporto per +le funzioni di gestione dei \textit{thread} (la \textit{Native Thread Posix + Library}, vedi sez.~\ref{sec:linux_ntpl}) nella \acr{glibc}, essi vengono +utilizzati soltanto se si sono specificati rispettivamente i flag +\const{CLONE\_PARENT\_SETTID}, \const{CLONE\_SETTLS} e +\const{CLONE\_CHILD\_SETTID}. + +La funzione ritorna un l'identificatore del nuovo \textit{task}, denominato +\texttt{Thread ID} (da qui in avanti \ids{TID}) il cui significato è analogo +al \ids{PID} dei normali processi e che a questo corrisponde qualora si crei +un processo ordinario e non un \textit{thread}. + +Il comportamento di \func{clone}, che si riflette sulle caratteristiche del +nuovo processo da essa creato, è controllato principalmente +dall'argomento \param{flags}, che deve essere specificato come maschera +binaria, ottenuta con un OR aritmetico di una delle costanti del seguente +elenco, che illustra quelle attualmente disponibili:\footnote{si fa + riferimento al momento della stesura di questa sezione, cioè con il kernel + 3.2.} + +\begin{basedescript}{\desclabelwidth{1.5 cm}\desclabelstyle{\nextlinelabel}} + +\item[\constd{CLONE\_CHILD\_CLEARTID}] cancella il valore del \textit{thread + ID} posto all'indirizzo dato dall'argomento \param{ctid}, eseguendo un + riattivazione del \textit{futex} (vedi sez.~\ref{sec:xxx_futex}) a + quell'indirizzo. Questo flag viene utilizzato dalla librerie di gestione dei + \textit{thread} ed è presente dal kernel 2.5.49. + +\item[\constd{CLONE\_CHILD\_SETTID}] scrive il \ids{TID} del \textit{thread} + figlio all'indirizzo dato dall'argomento \param{ctid}. Questo flag viene + utilizzato dalla librerie di gestione dei \textit{thread} ed è presente dal + kernel 2.5.49. + +\item[\constd{CLONE\_FILES}] se impostato il nuovo processo condividerà con il + padre la \textit{file descriptor table} (vedi sez.~\ref{sec:file_fd}), + questo significa che ogni \textit{file descriptor} aperto da un processo + verrà visto anche dall'altro e che ogni chiusura o cambiamento dei + \textit{file descriptor flag} di un \textit{file descriptor} verrà per + entrambi. + + Se non viene impostato il processo figlio eredita una copia della + \textit{file descriptor table} del padre e vale la semantica classica della + gestione dei \textit{file descriptor}, che costituisce il comportamento + ordinario di un sistema unix-like e che illustreremo in dettaglio in + sez.~\ref{sec:file_shared_access}. + +\item[\constd{CLONE\_FS}] se questo flag viene impostato il nuovo processo + condividerà con il padre le informazioni relative all'albero dei file, ed in + particolare avrà la stessa radice (vedi sez.~\ref{sec:file_chroot}), la + stessa directory di lavoro (vedi sez.~\ref{sec:file_work_dir}) e la stessa + \textit{umask} (sez.~\ref{sec:file_perm_management}). Una modifica di una + qualunque di queste caratteristiche in un processo, avrà effetto anche + sull'altro. Se assente il nuovo processo riceverà una copia delle precedenti + informazioni, che saranno così indipendenti per i due processi, come avviene + nel comportamento ordinario di un sistema unix-like. + +\item[\constd{CLONE\_IO}] se questo flag viene impostato il nuovo il nuovo + processo condividerà con il padre il contesto dell'I/O, altrimenti, come + come avviene nel comportamento ordinario con una \func{fork} otterrà un suo + contesto dell'I/O. + + Il contesto dell'I/O viene usato dagli \textit{scheduler} di I/O (visti in + sez.~\ref{sec:io_priority}) e se questo è lo stesso per diversi processi + questi vengono trattati come se fossero lo stesso, condividendo il tempo per + l'accesso al disco, e possono interscambiarsi nell'accesso a disco. L'uso di + questo flag consente, quando più \textit{thread} eseguono dell'I/O per conto + dello stesso processo (ad esempio con le funzioni di I/O asincrono di + sez.~\ref{sec:file_asyncronous_io}), migliori prestazioni. + +%TODO : tutti i CLONE_NEW* attengono ai namespace, ed è meglio metterli nella +%relativa sezione da creare a parte + +% \item[\constd{CLONE\_NEWIPC}] è uno dei flag ad uso dei \textit{container}, +% introdotto con il kernel 2.6.19. L'uso di questo flag crea per il nuovo +% processo un nuovo \textit{namespace} per il sistema di IPC, sia per quello +% di SysV (vedi sez.~\ref{sec:ipc_sysv}) che, dal kernel 2.6.30, per le code +% di messaggi POSIX (vedi sez.~\ref{sec:ipc_posix_mq}); si applica cioè a +% tutti quegli oggetti che non vegono identificati con un \textit{pathname} +% sull'albero dei file. + +% L'uso di questo flag richiede privilegi di amministratore (più precisamente +% la capacità \const{CAP\_SYS\_ADMIN}) e non può essere usato in combinazione +% con \const{CLONE\_SYSVSEM}. + +% \item[\constd{CLONE\_NEWNET}] +% \item[\constd{CLONE\_NEWNS}] +% \item[\constd{CLONE\_NEWPID}] +% \item[\constd{CLONE\_NEWUTS}] + + +% TODO trattare CLONE_NEWCGROUP introdotto con il kernel 4.6, vedi +% http://lwn.net/Articles/680566/ + +\item[\constd{CLONE\_PARENT}] +\item[\constd{CLONE\_PARENT\_SETTID}] +\item[\constd{CLONE\_PID}] + +\item[\constd{CLONE\_PTRACE}] se questo flag viene impostato ed il processo + chiamante viene tracciato (vedi sez.~\ref{sec:process_ptrace}) anche il + figlio viene tracciato. + +\item[\constd{CLONE\_SETTLS}] +\item[\constd{CLONE\_SIGHAND}] +\item[\constd{CLONE\_STOPPED}] +\item[\constd{CLONE\_SYSVSEM}] +\item[\constd{CLONE\_THREAD}] + +\item[\constd{CLONE\_UNTRACED}] se questo flag viene impostato un processo non + può più forzare \const{CLONE\_PTRACE} su questo processo. + +\item[\constd{CLONE\_VFORK}] se questo flag viene impostato il chiamante viene + fermato fintato che il figlio appena creato non rilascia la sua memoria + virtuale con una chiamata a \func{exec} o \func{exit}, viene quindi + replicato il comportamento di \func{vfork}. + +\item[\constd{CLONE\_VM}] se questo flag viene impostato il nuovo processo + condividerà con il padre la stessa memoria virtuale, e le scritture in + memoria fatte da uno qualunque dei processi saranno visibili dall'altro, + così come ogni mappatura in memoria (vedi sez.~\ref{sec:file_memory_map}). + + Se non viene impostato il processo figlio otterrà una copia dello spazio + degli indirizzi e si otterrà il comportamento ordinario di un processo di un + sistema unix-like creato con la funzione \func{fork}. +\end{basedescript} + + + +\subsection{La gestione dei \textit{namespace}} +\label{sec:process_namespaces} + +\itindbeg{namespace} +Come accennato all'inizio di sez.~\ref{sec:process_clone} oltre al controllo +delle caratteristiche dei processi usate per la creazione dei \textit{thread}, +l'uso di \func{clone} consente, ad uso delle nuove funzionalità di +virtualizzazione dei processi, di creare nuovi ``\textit{namespace}'' per una +serie di proprietà generali (come l'elenco dei \ids{PID}, l'albero dei file, i +\textit{mount point}, la rete, il sistema di IPC, ecc.). + +L'uso dei ``\textit{namespace}'' consente creare gruppi di processi che vedono +le suddette proprietà in maniera indipendente fra loro. I processi di ciascun +gruppo vengono così eseguiti come in una sorta di spazio separato da quello +degli altri gruppi, che costituisce poi quello che viene chiamato un +\textit{container}. + +\itindend{namespace} + + +\itindbeg{container} + +\itindend{container} + + +%TODO sezione separata sui namespace + +%TODO trattare unshare, vedi anche http://lwn.net/Articles/532748/ + +%TODO: trattare la funzione setns e i namespace file descriptors (vedi +% http://lwn.net/Articles/407495/) introdotti con il kernel 3.0, altre +% informazioni su setns qui: http://lwn.net/Articles/532748/ +% http://lwn.net/Articles/531498/ + + +\section{La gestione avanzata della sicurezza} +\label{sec:process_security} + +Tratteremo in questa sezione le funzionalità più avanzate relative alla +gestione della sicurezza, a partire dalle \textit{capabilities} e dalle +funzionalità di \textit{Secure Computing}, fino alle funzionalità relative +alla gestione delle chiavi crittografiche. + + +% TODO: trattare keyctl (man 2 keyctl) + +% TODO trattare le funzioni di protezione della memoria pkey_alloc, pkey_free, +% pkey_mprotect, introdotte con il kernel 4.8, vedi +% http://lwn.net/Articles/689395/ e Documentation/x86/protection-keys.txt + +%TODO trattare kcmp aggiunta con il kernel 3.5, vedi +% https://lwn.net/Articles/478111/ + + +\section{Funzionalità avanzate e specialistiche} +\label{sec:process_special} + + + +\subsection{La gestione delle operazioni in virgola mobile} +\label{sec:process_fenv} + +Da fare. + +% TODO eccezioni ed arrotondamenti per la matematica in virgola mobile +% consultare la manpage di fenv, math_error, fpclassify, matherr, isgreater, +% isnan, nan, INFINITY + + +\subsection{L'accesso alle porte di I/O} +\label{sec:process_io_port} + +% +% TODO l'I/O sulle porte di I/O +% consultare le manpage di ioperm, iopl e outb +% non c'entra nulla qui, va trovato un altro posto (altri meccanismi di I/O in +% fileintro ?) + +Da fare + + +%\subsection{La gestione di architetture a nodi multipli} +%\label{sec:process_NUMA} + +% TODO trattare i cpuset, che attiene anche a NUMA, e che possono essere usati +% per associare l'uso di gruppi di processori a gruppi di processi (vedi +% manpage omonima) +% TODO trattare getcpu, che attiene anche a NUMA, mettere qui anche +% sched_getcpu, che potrebbe essere indipendente ma richiama getcpu + +%TODO trattare le funzionalità per il NUMA +% vedi man numa e, mbind, get_mempolicy, set_mempolicy, +% le pagine di manuale relative +% vedere anche dove metterle... + +% \subsection{La gestione dei moduli} +% \label{sec:kernel_modules} + +% da fare + +%TODO trattare init_module e finit_module (quest'ultima introdotta con il +%kernel 3.8) + +%%%% Altre cose di cui non è chiara la collocazione: + +%TODO trattare membarrier, introdotta con il kernel 4.3 +% vedi http://lwn.net/Articles/369567/ http://lwn.net/Articles/369640/ +% http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=5b25b13ab08f616efd566347d809b4ece54570d1 +% vedi anche l'ulteriore opzione "expedited" introdotta con il kernel 4.14 +% (https://lwn.net/Articles/728795/) + + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "gapil" +%%% End: diff --git a/process.tex b/process.tex index a1bee2b..6408f6f 100644 --- a/process.tex +++ b/process.tex @@ -744,11 +744,11 @@ riposte nella \textit{swap}. \itindend{page~fault} -Normalmente questo è il prezzo da pagare per avere un multitasking reale, ed -in genere il sistema è molto efficiente in questo lavoro; quando però ci siano -esigenze specifiche di prestazioni è possibile usare delle funzioni che -permettono di bloccare il meccanismo della paginazione e mantenere fisse delle -pagine in memoria (vedi sez.~\ref{sec:proc_mem_lock}). +Normalmente questo è il prezzo da pagare per avere un \textit{multitasking} +reale, ed in genere il sistema è molto efficiente in questo lavoro; quando +però ci siano esigenze specifiche di prestazioni è possibile usare delle +funzioni che permettono di bloccare il meccanismo della paginazione e +mantenere fisse delle pagine in memoria (vedi sez.~\ref{sec:proc_mem_lock}). \index{paginazione|)} \index{memoria~virtuale|)} @@ -2330,8 +2330,8 @@ Benché questo non sia un libro sul linguaggio C, è opportuno affrontare alcune delle problematiche generali che possono emergere nella programmazione con questo linguaggio e di quali precauzioni o accorgimenti occorre prendere per risolverle. Queste problematiche non sono specifiche di sistemi unix-like o -multitasking, ma avendo trattato in questo capitolo il comportamento dei -processi visti come entità a sé stanti, le riportiamo qui. +\textit{multitasking}, ma avendo trattato in questo capitolo il comportamento +dei processi visti come entità a sé stanti, le riportiamo qui. \subsection{Il passaggio di variabili e valori di ritorno nelle funzioni} diff --git a/prochand.tex b/prochand.tex index 1fade9b..8d50557 100644 --- a/prochand.tex +++ b/prochand.tex @@ -22,7 +22,7 @@ all'interno del sistema. Saranno cioè affrontati i dettagli della creazione e della terminazione dei processi, della gestione dei loro attributi e privilegi, e di tutte le funzioni a questo connesse. Infine nella sezione finale introdurremo alcune problematiche generiche della programmazione in -ambiente multitasking. +ambiente \textit{multitasking}. \section{Le funzioni di base della gestione dei processi} @@ -281,10 +281,11 @@ processo era attraverso l'uso di questa funzione,\footnote{in realtà oggi la \func{fork} viene implementata tramite \func{clone}, cosa che consente una migliore interazione coi \textit{thread}.} essa quindi riveste un ruolo centrale tutte le volte che si devono scrivere programmi che usano il -multitasking.\footnote{oggi questa rilevanza, con la diffusione dell'uso dei - \textit{thread}\unavref{ che tratteremo al cap.~\ref{cha:threads}}, è in - parte minore, ma \func{fork} resta comunque la funzione principale per la - creazione di processi.} Il prototipo di \funcd{fork} è: +\textit{multitasking}.\footnote{oggi questa rilevanza, con la diffusione + dell'uso dei \textit{thread}\unavref{ che tratteremo al + cap.~\ref{cha:threads}}, è in parte minore, ma \func{fork} resta comunque + la funzione principale per la creazione di processi.} Il prototipo di +\funcd{fork} è: \begin{funcproto}{ \fhead{unistd.h} @@ -904,10 +905,10 @@ che il processo padre ancora non ha avuto il tempo di gestirli. \subsection{Le funzioni di attesa e ricezione degli stati di uscita} \label{sec:proc_wait} -Uno degli usi più comuni delle capacità multitasking di un sistema unix-like -consiste nella creazione di programmi di tipo server, in cui un processo -principale attende le richieste che vengono poi soddisfatte da una serie di -processi figli. +Uno degli usi più comuni delle capacità \textit{multitasking} di un sistema +unix-like consiste nella creazione di programmi di tipo server, in cui un +processo principale attende le richieste che vengono poi soddisfatte da una +serie di processi figli. Si è già sottolineato al paragrafo precedente come in questo caso diventi necessario gestire esplicitamente la conclusione dei figli onde evitare di @@ -1913,7 +1914,7 @@ caso \var{errno} uno dei valori: \begin{errlist} \item[\errcode{EAGAIN}] (solo per \func{setuid}) la chiamata cambierebbe l'\ids{UID} reale ma il kernel non dispone temporaneamente delle risorse per - farlo, oppure, per i kernel precendenti il 3.1, il cambiamento + farlo, oppure, per i kernel precedenti il 3.1, il cambiamento dell'\ids{UID} reale farebbe superare il limite per il numero dei processi \const{RLIMIT\_NPROC} (vedi sez.~\ref{sec:sys_resource_limit}). \item[\errcode{EINVAL}] il valore di dell'argomento non è valido per il @@ -2367,8 +2368,8 @@ ed oggetto di numerose ricerche; in generale essa dipende in maniera essenziale anche dal tipo di utilizzo che deve essere fatto del sistema, per cui non esiste un meccanismo che sia valido per tutti gli usi. -La caratteristica specifica di un sistema multitasking come Linux è quella del -cosiddetto \itindex{preemptive~multitasking} \textit{preemptive +La caratteristica specifica di un sistema \textit{multitasking} come Linux è +quella del cosiddetto \itindex{preemptive~multitasking} \textit{preemptive multitasking}: questo significa che al contrario di altri sistemi (che usano invece il cosiddetto \itindex{cooperative~multitasking} \textit{cooperative multitasking}) non sono i singoli processi, ma il kernel stesso a decidere @@ -3657,764 +3658,15 @@ rimosso a partire dal kernel 2.6.25. %TODO verificare http://lwn.net/Articles/355987/ -\section{Funzioni di gestione avanzata} -\label{sec:proc_advanced_control} -Nelle precedenti sezioni si sono trattate la gran parte delle funzioni che -attengono alla gestione ordinaria dei processi e delle loro proprietà più -comuni. Tratteremo qui alcune \textit{system call} dedicate alla gestione di -funzionalità dei processi molto specifiche ed avanzate, il cui uso è in genere -piuttosto ridotto. Trattandosi di problematiche abbastanza complesse, che -spesso presuppongono la conoscenza di altri argomenti trattati nel seguito -della guida, si può saltare questa sezione in una prima lettura, tornando su -di essa in un secondo tempo. - - -\subsection{La funzione \func{prctl}} -\label{sec:process_prctl} - -Benché la gestione ordinaria possa essere effettuata attraverso le funzioni -che abbiamo già esaminato nelle sezioni precedenti, esistono una serie di -proprietà e caratteristiche particolari dei processi non coperte da esse, per -la cui gestione è stata predisposta una apposita \textit{system call} che -fornisce una interfaccia generica per tutte le operazioni specialistiche. La -funzione di sistema è \funcd{prctl} ed il suo prototipo è:\footnote{la - funzione non è standardizzata ed è specifica di Linux, anche se ne esiste - una analoga in IRIX; è stata introdotta con il kernel 2.1.57.} - -\begin{funcproto}{ -\fhead{sys/prctl.h} -\fdecl{int prctl(int option, unsigned long arg2, unsigned long arg3, unsigned - long arg4, \\ -\phantom{int prctl(}unsigned long arg5)} -\fdesc{Esegue una operazione speciale sul processo corrente.} -} - -{La funzione ritorna $0$ o un valore positivo dipendente dall'operazione in - caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà - valori diversi a seconda del tipo di operazione richiesta, sono possibili: - \errval{EACCESS}, \errval{EBADF}, \errval{EBUSY}, \errval{EFAULT}, - \errval{EINVAL}, \errval{ENXIO}, \errval{EOPNOTSUPP} o \errval{EPERM}.} -\end{funcproto} - -La funzione ritorna in caso di successo un valore nullo o positivo, e $-1$ in -caso di errore. Il significato degli argomenti della funzione successivi al -primo, il valore di ritorno in caso di successo, il tipo di errore restituito -in \var{errno} dipendono dall'operazione eseguita, indicata tramite il primo -argomento, \param{option}. Questo è un valore intero che identifica -l'operazione, e deve essere specificato con l'uso di una delle costanti -predefinite del seguente elenco.\footnote{l'elenco potrebbe non risultare - aggiornato, in quanto nuove operazioni vengono aggiunte nello sviluppo del - kernel.} Tratteremo esplicitamente per ciascuna di esse il significato del -il valore di ritorno in caso di successo, ma solo quando non corrisponde -all'ordinario valore nullo (dato per implicito). - -%TODO: trattare PR_CAP_AMBIENT, dal 4.3 -%TODO: trattare PR_CAP_FP_*, dal 4.0, solo per MIPS -%TODO: trattare PR_MPX_*_MANAGEMENT, dal 3.19 -%TODO: trattare PR_*NO_NEW_PRIVS, dal 3.5 -%TODO: trattare PR_SET_PTRACER, dal 3.4 - -\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}} -\item[\constd{PR\_CAPBSET\_READ}] Controlla la disponibilità di una delle - \textit{capability} (vedi sez.~\ref{sec:proc_capabilities}). La funzione - ritorna 1 se la capacità specificata nell'argomento \param{arg2} (con una - delle costanti di tab.~\ref{tab:proc_capabilities}) è presente nel - \textit{capabilities bounding set} del processo e zero altrimenti, - se \param{arg2} non è un valore valido si avrà un errore di \errval{EINVAL}. - Introdotta a partire dal kernel 2.6.25. - -\item[\constd{PR\_CAPBSET\_DROP}] Rimuove permanentemente una delle - \textit{capabilities} (vedi sez.~\ref{sec:proc_capabilities}) dal processo e - da tutti i suoi discendenti. La funzione cancella la capacità specificata - nell'argomento \param{arg2} con una delle costanti di - tab.~\ref{tab:proc_capabilities} dal \textit{capabilities bounding set} del - processo. L'operazione richiede i privilegi di amministratore (la capacità - \const{CAP\_SETPCAP}), altrimenti la chiamata fallirà con un errore di - \errcode{EPERM}; se il valore di \param{arg2} non è valido o se il supporto - per le \textit{file capabilities} non è stato compilato nel kernel la - chiamata fallirà con un errore di \errval{EINVAL}. Introdotta a partire dal - kernel 2.6.25. - -\item[\constd{PR\_SET\_DUMPABLE}] Imposta il flag che determina se la - terminazione di un processo a causa di un segnale per il quale è prevista la - generazione di un file di \textit{core dump} (vedi - sez.~\ref{sec:sig_standard}) lo genera effettivamente. In genere questo flag - viene attivato automaticamente, ma per evitare problemi di sicurezza (la - generazione di un file da parte di processi privilegiati può essere usata - per sovrascriverne altri) viene cancellato quando si mette in esecuzione un - programma con i bit \acr{suid} e \acr{sgid} attivi (vedi - sez.~\ref{sec:file_special_perm}) o con l'uso delle funzioni per la modifica - degli \ids{UID} dei processi (vedi sez.~\ref{sec:proc_setuid}). - - L'operazione è stata introdotta a partire dal kernel 2.3.20, fino al kernel - 2.6.12 e per i kernel successivi al 2.6.17 era possibile usare solo un - valore 0 (espresso anche come \constd{SUID\_DUMP\_DISABLE}) di \param{arg2} - per disattivare il flag ed un valore 1 (espresso anche come - \constd{SUID\_DUMP\_USER}) per attivarlo. Nei kernel dal 2.6.13 al 2.6.17 è - stato supportato anche il valore 2, che causava la generazione di un - \textit{core dump} leggibile solo dall'amministratore, ma questa - funzionalità è stata rimossa per motivi di sicurezza, in quanto consentiva - ad un utente normale di creare un file di \textit{core dump} appartenente - all'amministratore in directory dove l'utente avrebbe avuto permessi di - accesso. Specificando un valore diverso da 0 o 1 si ottiene un errore di - \errval{EINVAL}. - -\item[\constd{PR\_GET\_DUMPABLE}] Ottiene come valore di ritorno della funzione - lo stato corrente del flag che controlla la effettiva generazione dei - \textit{core dump}. Introdotta a partire dal kernel 2.3.20. - -\item[\constd{PR\_SET\_ENDIAN}] Imposta la \textit{endianness} del processo - chiamante secondo il valore fornito in \param{arg2}. I valori possibili sono - sono: \constd{PR\_ENDIAN\_BIG} (\textit{big endian}), - \constd{PR\_ENDIAN\_LITTLE} (\textit{little endian}), e - \constd{PR\_ENDIAN\_PPC\_LITTLE} (lo pseudo \textit{little endian} del - PowerPC). Introdotta a partire dal kernel 2.6.18, solo per architettura - PowerPC. - -\item[\constd{PR\_GET\_ENDIAN}] Ottiene il valore della \textit{endianness} del - processo chiamante, salvato sulla variabile puntata da \param{arg2} che deve - essere passata come di tipo ``\ctyp{int *}''. Introdotta a partire dal - kernel 2.6.18, solo su PowerPC. - -\item[\constd{PR\_SET\_FPEMU}] Imposta i bit di controllo per l'emulazione - della virgola mobile su architettura ia64, secondo il valore - di \param{arg2}, si deve passare \constd{PR\_FPEMU\_NOPRINT} per emulare in - maniera trasparente l'accesso alle operazioni in virgola mobile, o - \constd{PR\_FPEMU\_SIGFPE} per non emularle ed inviare il segnale - \signal{SIGFPE} (vedi sez.~\ref{sec:sig_prog_error}). Introdotta a partire - dal kernel 2.4.18, solo su architettura ia64. - -\item[\constd{PR\_GET\_FPEMU}] Ottiene il valore dei flag di controllo - dell'emulazione della virgola mobile, salvato all'indirizzo puntato - da \param{arg2}, che deve essere di tipo ``\ctyp{int *}''. Introdotta a - partire dal kernel 2.4.18, solo su architettura ia64. - -\item[\constd{PR\_SET\_FPEXC}] Imposta la modalità delle eccezioni in virgola - mobile (\textit{floating-point exception mode}) al valore di \param{arg2}. - I valori possibili sono: - \begin{itemize*} - \item \constd{PR\_FP\_EXC\_SW\_ENABLE} per usare FPEXC per le eccezioni, - \item \constd{PR\_FP\_EXC\_DIV} per la divisione per zero in virgola mobile, - \item \constd{PR\_FP\_EXC\_OVF} per gli overflow, - \item \constd{PR\_FP\_EXC\_UND} per gli underflow, - \item \constd{PR\_FP\_EXC\_RES} per risultati non esatti, - \item \constd{PR\_FP\_EXC\_INV} per operazioni invalide, - \item \constd{PR\_FP\_EXC\_DISABLED} per disabilitare le eccezioni, - \item \constd{PR\_FP\_EXC\_NONRECOV} per usare la modalità di eccezione - asincrona non recuperabile, - \item \constd{PR\_FP\_EXC\_ASYNC} per usare la modalità di eccezione - asincrona recuperabile, - \item \constd{PR\_FP\_EXC\_PRECISE} per la modalità precisa di - eccezione.\footnote{trattasi di gestione specialistica della gestione - delle eccezioni dei calcoli in virgola mobile che, i cui dettagli al - momento vanno al di là dello scopo di questo testo.} - \end{itemize*} -Introdotta a partire dal kernel 2.4.21, solo su PowerPC. - -\item[\constd{PR\_GET\_FPEXC}] Ottiene il valore della modalità delle eccezioni - delle operazioni in virgola mobile, salvata all'indirizzo - puntato \param{arg2}, che deve essere di tipo ``\ctyp{int *}''. Introdotta - a partire dal kernel 2.4.21, solo su PowerPC. - -\item[\constd{PR\_SET\_KEEPCAPS}] Consente di controllare quali - \textit{capabilities} vengono cancellate quando si esegue un cambiamento di - \ids{UID} del processo (per i dettagli si veda - sez.~\ref{sec:proc_capabilities}, in particolare quanto illustrato a - pag.~\pageref{sec:capability-uid-transition}). Un valore nullo (il default) - per \param{arg2} comporta che vengano cancellate, il valore 1 che vengano - mantenute, questo valore viene sempre cancellato attraverso una \func{exec}. - L'uso di questo flag è stato sostituito, a partire dal kernel 2.6.26, dal - flag \const{SECURE\_KEEP\_CAPS} dei \textit{securebits} (vedi - sez.~\ref{sec:proc_capabilities} e l'uso di \const{PR\_SET\_SECUREBITS} più - avanti) e si è impostato con essi \const{SECURE\_KEEP\_CAPS\_LOCKED} si - otterrà un errore di \errval{EPERM}. Introdotta a partire dal kernel - 2.2.18. - -\item[\constd{PR\_GET\_KEEPCAPS}] Ottiene come valore di ritorno della funzione - il valore del flag di controllo delle \textit{capabilities} impostato con - \const{PR\_SET\_KEEPCAPS}. Introdotta a partire dal kernel 2.2.18. - -\item[\constd{PR\_SET\_NAME}] Imposta il nome del processo chiamante alla - stringa puntata da \param{arg2}, che deve essere di tipo ``\ctyp{char *}''. Il - nome può essere lungo al massimo 16 caratteri, e la stringa deve essere - terminata da NUL se più corta. Introdotta a partire dal kernel 2.6.9. - -\item[\constd{PR\_GET\_NAME}] Ottiene il nome del processo chiamante nella - stringa puntata da \param{arg2}, che deve essere di tipo ``\ctyp{char *}''; - si devono allocare per questo almeno 16 byte, e il nome sarà terminato da - NUL se più corto. Introdotta a partire dal kernel 2.6.9. - -\item[\constd{PR\_SET\_PDEATHSIG}] Consente di richiedere l'emissione di un - segnale, che sarà ricevuto dal processo chiamante, in occorrenza della - terminazione del proprio processo padre; in sostanza consente di invertire - il ruolo di \signal{SIGCHLD}. Il valore di \param{arg2} deve indicare il - numero del segnale, o 0 per disabilitare l'emissione. Il valore viene - automaticamente cancellato per un processo figlio creato con \func{fork}. - Introdotta a partire dal kernel 2.1.57. - -\item[\constd{PR\_GET\_PDEATHSIG}] Ottiene il valore dell'eventuale segnale - emesso alla terminazione del padre, salvato all'indirizzo - puntato \param{arg2}, che deve essere di tipo ``\ctyp{int *}''. Introdotta a - partire dal kernel 2.3.15. - -\item[\constd{PR\_SET\_PTRACER}] Imposta un \ids{PID} per il ``\textit{tracer - process}'' usando \param{arg2}. Una impostazione successiva sovrascrive la - precedente, ed un valore nullo cancella la disponibilità di un - ``\textit{tracer process}''. Questa è una funzionalità fornita da - \textit{``Yama''}, uno specifico \textit{Linux Security Modules}, e serve a - consentire al processo indicato, quando le restrioni introdotte da questo - modulo sono attive, di usare \func{ptrace}\unavref{ (vedi - sez.\ref{sec:process_ptrace})} sul processo chiamante, anche se quello - indicato non ne è un progenitore. Il valore \constd{PR\_SET\_PTRACER\_ANY} - consente a tutti i processi l'uso di \func{ptrace}. L'uso si \textit{Yama} - attiene alla gestione della sicurezza dei processi, e consente di introdurre - una restrizione all'uso di \func{ptrace}, che è spesso sorgente di - compromissioni. Si tratta di un uso specialistico che va al di là dello - scopo di queste dispense, per i dettagli si consulti la documentazione su - \textit{Yama} nei sorgenti del kernel. Introdotta a partire dal kernel 3.4. - -\itindbeg{secure~computing~mode} -\item[\constd{PR\_SET\_SECCOMP}] Imposta il cosiddetto \textit{secure computing - mode} per il processo corrente. Prevede come unica possibilità - che \param{arg2} sia impostato ad 1. Una volta abilitato il \textit{secure - computing mode} il processo potrà utilizzare soltanto un insieme - estremamente limitato di \textit{system call}: \func{read}, \func{write}, - \func{\_exit} e \funcm{sigreturn}. Ogni altra \textit{system call} porterà - all'emissione di un \signal{SIGKILL} (vedi sez.~\ref{sec:sig_termination}). - Il \textit{secure computing mode} è stato ideato per fornire un supporto per - l'esecuzione di codice esterno non fidato e non verificabile a scopo di - calcolo;\footnote{lo scopo è quello di poter vendere la capacità di calcolo - della proprio macchina ad un qualche servizio di calcolo distribuito senza - comprometterne la sicurezza eseguendo codice non sotto il proprio - controllo.} in genere i dati vengono letti o scritti grazie ad un socket o - una \textit{pipe}, e per evitare problemi di sicurezza non sono possibili - altre operazioni se non quelle citate. Introdotta a partire dal kernel - 2.6.23, disponibile solo se si è abilitato il supporto nel kernel con - \texttt{CONFIG\_SECCOMP}. - -% TODO a partire dal kernel 3.5 è stato introdotto la possibilità di usare un -% terzo argomento se il secondo è SECCOMP_MODE_FILTER, vedi -% Documentation/prctl/seccomp_filter.txt -% vedi anche http://lwn.net/Articles/600250/ - -% TODO documentare PR_SET_SECCOMP introdotto a partire dal kernel 3.5. Vedi: -% * Documentation/prctl/seccomp_filter.txt -% * http://lwn.net/Articles/475043/ - -% TODO a partire dal kernel 3.17 è stata introdotta la nuova syscall seccomp, -% vedi http://lwn.net/Articles/600250/ e http://lwn.net/Articles/603321/ - -\item[\constd{PR\_GET\_SECCOMP}] Ottiene come valore di ritorno della funzione - lo stato corrente del \textit{secure computing mode}, al momento attuale la - funzione è totalmente inutile in quanto l'unico valore ottenibile è 0, dato - che la chiamata di questa funzione in \textit{secure computing mode} - comporterebbe l'emissione di \signal{SIGKILL}, è stata comunque definita per - eventuali estensioni future. Introdotta a partire dal kernel 2.6.23. -\itindend{secure~computing~mode} - -\item[\constd{PR\_SET\_SECUREBITS}] Imposta i \textit{securebits} per il - processo chiamante al valore indicato da \param{arg2}; per i dettagli sul - significato dei \textit{securebits} si veda - sez.~\ref{sec:proc_capabilities}, ed in particolare i valori di - tab.~\ref{tab:securebits_values} e la relativa trattazione. L'operazione - richiede i privilegi di amministratore (la capacità \const{CAP\_SETPCAP}), - altrimenti la chiamata fallirà con un errore di \errval{EPERM}. Introdotta a - partire dal kernel 2.6.26. - -\item[\constd{PR\_GET\_SECUREBITS}] Ottiene come valore di ritorno della - funzione l'impostazione corrente per i \textit{securebits}. Introdotta a - partire dal kernel 2.6.26. - -\item[\constd{PR\_SET\_TIMING}] Imposta il metodo di temporizzazione del - processo da indicare con il valore di \param{arg2}, attualmente i valori - possibili sono due, con \constd{PR\_TIMING\_STATISTICAL} si usa il metodo - statistico tradizionale, con \constd{PR\_TIMING\_TIMESTAMP} il più accurato - basato su dei \textit{timestamp}, quest'ultimo però non è ancora - implementato ed il suo uso comporta la restituzione di un errore di - \errval{EINVAL}. Introdotta a partire dal kernel 2.6.0-test4. - -\item[\constd{PR\_GET\_TIMING}] Ottiene come valore di ritorno della funzione - il metodo di temporizzazione del processo attualmente in uso (uno dei due - valori citati per \const{PR\_SET\_TIMING}). Introdotta a partire dal kernel - 2.6.0-test4. - -\item[\constd{PR\_SET\_TSC}] Imposta il flag che indica se il processo - chiamante può leggere il registro di processore contenente il contatore dei - \textit{timestamp} (TSC, o \textit{Time Stamp Counter}) da indicare con il - valore di \param{arg2}. Si deve specificare \constd{PR\_TSC\_ENABLE} per - abilitare la lettura o \constd{PR\_TSC\_SIGSEGV} per disabilitarla con la - generazione di un segnale di \signal{SIGSEGV} (vedi - sez.~\ref{sec:sig_prog_error}). La lettura viene automaticamente - disabilitata se si attiva il \textit{secure computing mode} (vedi - \const{PR\_SET\_SECCOMP}). Introdotta a partire dal kernel - 2.6.26, solo su x86. - -\item[\constd{PR\_GET\_TSC}] Ottiene il valore del flag che controlla la - lettura del contattore dei \textit{timestamp}, salvato all'indirizzo - puntato \param{arg2}, che deve essere di tipo ``\ctyp{int *}''. Introdotta a - partire dal kernel 2.6.26, solo su x86. -% articoli sul TSC e relativi problemi: http://lwn.net/Articles/209101/, -% http://blog.cr0.org/2009/05/time-stamp-counter-disabling-oddities.html, -% http://en.wikipedia.org/wiki/Time_Stamp_Counter - -\item[\constd{PR\_SET\_UNALIGN}] Imposta la modalità di controllo per l'accesso - a indirizzi di memoria non allineati, che in varie architetture risultano - illegali, da indicare con il valore di \param{arg2}. Si deve specificare il - valore \constd{PR\_UNALIGN\_NOPRINT} per ignorare gli accessi non allineati, - ed il valore \constd{PR\_UNALIGN\_SIGBUS} per generare un segnale di - \signal{SIGBUS} (vedi sez.~\ref{sec:sig_prog_error}) in caso di accesso non - allineato. Introdotta con diverse versioni su diverse architetture. - -\item[\const{PR\_GET\_UNALIGN}] Ottiene il valore della modalità di controllo - per l'accesso a indirizzi di memoria non allineati, salvato all'indirizzo - puntato \param{arg2}, che deve essere di tipo \code{(int *)}. Introdotta con - diverse versioni su diverse architetture. -\item[\const{PR\_MCE\_KILL}] Imposta la politica di gestione degli errori - dovuti a corruzione della memoria per problemi hardware. Questo tipo di - errori vengono riportati dall'hardware di controllo della RAM e vengono - gestiti dal kernel,\footnote{la funzionalità è disponibile solo sulle - piattaforme più avanzate che hanno il supporto hardware per questo tipo di - controlli.} ma devono essere opportunamente riportati ai processi che - usano quella parte di RAM che presenta errori; nel caso specifico questo - avviene attraverso l'emissione di un segnale di \signal{SIGBUS} (vedi - sez.~\ref{sec:sig_prog_error}).\footnote{in particolare viene anche - impostato il valore di \var{si\_code} in \struct{siginfo\_t} a - \const{BUS\_MCEERR\_AO}; per il significato di tutto questo si faccia - riferimento alla trattazione di sez.~\ref{sec:sig_sigaction}.} - - Il comportamento di default prevede che per tutti i processi si applichi la - politica generale di sistema definita nel file - \sysctlfiled{vm/memory\_failure\_early\_kill}, ma specificando - per \param{arg2} il valore \constd{PR\_MCE\_KILL\_SET} è possibile impostare - con il contenuto di \param{arg3} una politica specifica del processo - chiamante. Si può tornare alla politica di default del sistema utilizzando - invece per \param{arg2} il valore \constd{PR\_MCE\_KILL\_CLEAR}. In tutti i - casi, per compatibilità con eventuali estensioni future, tutti i valori - degli argomenti non utilizzati devono essere esplicitamente posti a zero, - pena il fallimento della chiamata con un errore di \errval{EINVAL}. - - In caso di impostazione di una politica specifica del processo con - \const{PR\_MCE\_KILL\_SET} i valori di \param{arg3} possono essere soltanto - due, che corrispondono anche al valore che si trova nell'impostazione - generale di sistema di \texttt{memory\_failure\_early\_kill}, con - \constd{PR\_MCE\_KILL\_EARLY} si richiede l'emissione immediata di - \signal{SIGBUS} non appena viene rilevato un errore, mentre con - \constd{PR\_MCE\_KILL\_LATE} il segnale verrà inviato solo quando il processo - tenterà un accesso alla memoria corrotta. Questi due valori corrispondono - rispettivamente ai valori 1 e 0 di - \texttt{memory\_failure\_early\_kill}.\footnote{in sostanza nel primo caso - viene immediatamente inviato il segnale a tutti i processi che hanno la - memoria corrotta mappata all'interno del loro spazio degli indirizzi, nel - secondo caso prima la pagina di memoria viene tolta dallo spazio degli - indirizzi di ciascun processo, mentre il segnale viene inviato solo quei - processi che tentano di accedervi.} Si può usare per \param{arg3} anche un - terzo valore, \constd{PR\_MCE\_KILL\_DEFAULT}, che corrisponde a impostare - per il processo la politica di default.\footnote{si presume la politica di - default corrente, in modo da non essere influenzati da un eventuale - successivo cambiamento della stessa.} Introdotta a partire dal kernel - 2.6.32. -\item[\constd{PR\_MCE\_KILL\_GET}] Ottiene come valore di ritorno della - funzione la politica di gestione degli errori dovuti a corruzione della - memoria. Tutti gli argomenti non utilizzati (al momento tutti) devono essere - nulli pena la ricezione di un errore di \errval{EINVAL}. Introdotta a - partire dal kernel 2.6.32. -\itindbeg{child~reaper} -\item[\constd{PR\_SET\_CHILD\_SUBREAPER}] Se \param{arg2} è diverso da zero - imposta l'attributo di \textit{child reaper} per il processo, se nullo lo - cancella. Lo stato di \textit{child reaper} è una funzionalità, introdotta - con il kernel 3.4, che consente di far svolgere al processo che ha questo - attributo il ruolo di ``\textsl{genitore adottivo}'' per tutti i processi - suoi ``\textsl{discendenti}'' che diventano orfani, in questo modo il - processo potrà ricevere gli stati di terminazione alla loro uscita, - sostituendo in questo ruolo \cmd{init} (si ricordi quanto illustrato in - sez.~\ref{sec:proc_termination}). Il meccanismo è stato introdotto ad uso - dei programmi di gestione dei servizi, per consentire loro di ricevere gli - stati di terminazione di tutti i processi che lanciano, anche se questi - eseguono una doppia \func{fork}; nel comportamento ordinario infatti questi - verrebbero adottati da \cmd{init} ed il programma che li ha lanciati non - sarebbe più in grado di riceverne lo stato di terminazione. Se un processo - con lo stato di \textit{child reaper} termina prima dei suoi discendenti, - svolgerà questo ruolo il più prossimo antenato ad avere lo stato di - \textit{child reaper}, -\item[\constd{PR\_GET\_CHILD\_SUBREAPER}] Ottiene l'impostazione relativa allo - lo stato di \textit{child reaper} del processo chiamante, salvata come - \textit{value result} all'indirizzo puntato da \param{arg2} (da indicare - come di tipo \code{int *}). Il valore viene letto come valore logico, se - diverso da 0 lo stato di \textit{child reaper} è attivo altrimenti è - disattivo. Introdotta a partire dal kernel 3.4. -\itindend{child~reaper} - - -% TODO documentare PR_MPX_INIT e PR_MPX_RELEASE, vedi -% http://lwn.net/Articles/582712/ - -% TODO documentare PR_SET_MM_MAP aggiunta con il kernel 3.18, per impostare i -% parametri di base del layout dello spazio di indirizzi di un processo (area -% codice e dati, stack, brack pointer ecc. vedi -% http://git.kernel.org/linus/f606b77f1a9e362451aca8f81d8f36a3a112139e - -% TODO documentare ARCH_SET_CPUID e ARCH_GET_CPUID, introdotte con il kernel -% 4.12, vedi https://lwn.net/Articles/721182/ - - -\label{sec:prctl_operation} -\end{basedescript} - - -\subsection{La \textit{system call} \func{clone}} -\label{sec:process_clone} - -La funzione tradizionale con cui creare un nuovo processo in un sistema -Unix-like, come illustrato in sez.~\ref{sec:proc_fork}, è \func{fork}, ma con -l'introduzione del supporto del kernel per i \textit{thread} (vedi -cap.~\ref{cha:threads}), si è avuta la necessità di una interfaccia che -consentisse un maggiore controllo sulla modalità con cui vengono creati nuovi -processi, che poi è stata utilizzata anche per fornire supporto per le -tecnologie di virtualizzazione dei processi (i cosiddetti \textit{container}). - -Per questo l'interfaccia per la creazione di un nuovo processo è stata -delegata ad una nuova \textit{system call}, \funcm{sys\_clone}, che consente -di reimplementare anche la tradizionale \func{fork}. In realtà in questo caso -più che di nuovi processi si può parlare della creazioni di nuovi -``\textit{task}'' del kernel che possono assumere la veste sia di un processo -classico isolato dagli altri come quelli trattati finora, che di un -\textit{thread} in cui la memoria viene condivisa fra il processo chiamante ed -il nuovo processo creato, come quelli che vedremo in -sez.~\ref{sec:linux_thread}. Per evitare confusione fra \textit{thread} e -processi ordinari, abbiamo deciso di usare la nomenclatura \textit{task} per -indicare la unità di esecuzione generica messa a disposizione del kernel che -\texttt{sys\_clone} permette di creare. - -\itindbeg{namespace} -\itindbeg{container} - -Oltre a questo la funzione consente, ad uso delle nuove funzionalità di -virtualizzazione dei processi, di creare nuovi ``\textit{namespace}'' per una -serie di proprietà generali (come l'elenco dei \ids{PID}, l'albero dei file, i -\textit{mount point}, la rete, il sistema di IPC, ecc.). L'uso dei -``\textit{namespace}'' consente creare gruppi di processi che vedono le -suddette proprietà in maniera indipendente fra loro. I processi di ciascun -gruppo vengono così eseguiti come in una sorta di spazio separato da quello -degli altri gruppi, che costituisce poi quello che viene chiamato un -\textit{container}. - -\itindend{namespace} -\itindend{container} - -La \textit{system call} richiede soltanto due argomenti: il -primo, \param{flags}, consente di controllare le modalità di creazione del -nuovo \textit{task}, il secondo, \param{child\_stack}, imposta l'indirizzo -dello \textit{stack} per il nuovo \textit{task}, e deve essere indicato quando -si intende creare un \textit{thread}. L'esecuzione del programma creato da -\func{sys\_clone} riprende, come per \func{fork}, da dopo l'esecuzione della -stessa. - -La necessità di avere uno \textit{stack} alternativo c'è solo quando si -intende creare un \textit{thread}, in tal caso infatti il nuovo \textit{task} -vede esattamente la stessa memoria del \textit{task} -``\textsl{padre}'',\footnote{in questo caso per padre si intende semplicemente - il \textit{task} che ha eseguito \func{sys\_clone} rispetto al \textit{task} - da essa creato, senza nessuna delle implicazioni che il concetto ha per i - processi.} e nella sua esecuzione alla prima chiamata di una funzione -andrebbe a scrivere sullo \textit{stack} usato anche dal padre (si ricordi -quanto visto in sez.~\ref{sec:proc_mem_layout} riguardo all'uso dello -\textit{stack}). - -Per evitare di doversi garantire contro la evidente possibilità di -\textit{race condition} che questa situazione comporta (vedi -sez.~\ref{sec:proc_race_cond} per una spiegazione della problematica) è -necessario che il chiamante allochi preventivamente un'area di memoria. In -genere lo si fa con una \func{malloc} che allochi un buffer che la funzione -imposterà come \textit{stack} del nuovo processo, avendo ovviamente cura di -non utilizzarlo direttamente nel processo chiamante. - -In questo modo i due \textit{task} avranno degli \textit{stack} indipendenti e -non si dovranno affrontare problematiche di \textit{race condition}. Si tenga -presente inoltre che in molte architetture di processore lo \textit{stack} -cresce verso il basso, pertanto in tal caso non si dovrà specificare -per \param{child\_stack} il puntatore restituito da \func{malloc}, ma un -puntatore alla fine del buffer da essa allocato. - -Dato che tutto ciò è necessario solo per i \textit{thread} che condividono la -memoria, la \textit{system call}, a differenza della funzione di libreria che -vedremo a breve, consente anche di passare per \param{child\_stack} il valore -\val{NULL}, che non imposta un nuovo \textit{stack}. Se infatti si crea un -processo, questo ottiene un suo nuovo spazio degli indirizzi (è sottinteso -cioè che non si stia usando il flag \const{CLONE\_VM} che vedremo a breve) ed -in questo caso si applica la semantica del \textit{copy on write} illustrata -in sez.~\ref{sec:proc_fork}, per cui le pagine dello \textit{stack} verranno -automaticamente copiate come le altre e il nuovo processo avrà un suo -\textit{stack} totalmente indipendente da quello del padre. - -Dato che l'uso principale della nuova \textit{system call} è quello relativo -alla creazione dei \textit{thread}, la \acr{glibc} definisce una funzione di -libreria con una sintassi diversa, orientata a questo scopo, e la -\textit{system call} resta accessibile solo se invocata esplicitamente come -visto in sez.~\ref{sec:proc_syscall}.\footnote{ed inoltre per questa - \textit{system call} non è disponibile la chiamata veloce con - \texttt{vsyscall}.} La funzione di libreria si chiama semplicemente -\funcd{clone} ed il suo prototipo è: - -\begin{funcproto}{ -\fhead{sched.h} -\fdecl{int clone(int (*fn)(void *), void *child\_stack, int flags, void *arg, - ... \\ -\phantom{int clone(}/* pid\_t *ptid, struct user\_desc *tls, pid\_t *ctid */ )} -\fdesc{Crea un nuovo processo o \textit{thread}.} -} -{La funzione ritorna il \textit{Thread ID} assegnato al nuovo processo in caso - di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei - valori: -\begin{errlist} - \item[\errcode{EAGAIN}] sono già in esecuzione troppi processi. - \item[\errcode{EINVAL}] si è usata una combinazione non valida di flag o - un valore nullo per \param{child\_stack}. - \item[\errcode{ENOMEM}] non c'è memoria sufficiente per creare una nuova - \texttt{task\_struct} o per copiare le parti del contesto del chiamante - necessarie al nuovo \textit{task}. - \item[\errcode{EPERM}] non si hanno i privilegi di amministratore - richiesti dai flag indicati. -\end{errlist}} -\end{funcproto} - -% NOTE: una pagina con la descrizione degli argomenti: -% * http://www.lindevdoc.org/wiki/Clone - -La funzione prende come primo argomento \param{fn} il puntatore alla funzione -che verrà messa in esecuzione nel nuovo processo, che può avere un unico -argomento di tipo puntatore a \ctyp{void}, il cui valore viene passato dal -terzo argomento \param{arg}. Per quanto il precedente prototipo possa -intimidire nella sua espressione, in realtà l'uso è molto semplice basterà -definire una qualunque funzione \param{fn} che restituisce un intero ed ha -come argomento un puntatore a \ctyp{void}, e \code{fn(arg)} sarà eseguita in -un nuovo processo. - -Il nuovo processo resterà in esecuzione fintanto che la funzione \param{fn} -non ritorna, o esegue \func{exit} o viene terminata da un segnale. Il valore -di ritorno della funzione (o quello specificato con \func{exit}) verrà -utilizzato come stato di uscita della funzione. I tre -argomenti \param{ptid}, \param{tls} e \param{ctid} sono opzionali e sono -presenti solo a partire dal kernel 2.6 e sono stati aggiunti come supporto per -le funzioni di gestione dei \textit{thread} (la \textit{Native Thread Posix - Library}, vedi sez.~\ref{sec:linux_ntpl}) nella \acr{glibc}, essi vengono -utilizzati soltanto se si sono specificati rispettivamente i flag -\const{CLONE\_PARENT\_SETTID}, \const{CLONE\_SETTLS} e -\const{CLONE\_CHILD\_SETTID}. - -La funzione ritorna un l'identificatore del nuovo \textit{task}, denominato -\texttt{Thread ID} (da qui in avanti \ids{TID}) il cui significato è analogo -al \ids{PID} dei normali processi e che a questo corrisponde qualora si crei -un processo ordinario e non un \textit{thread}. - -Il comportamento di \func{clone}, che si riflette sulle caratteristiche del -nuovo processo da essa creato, è controllato principalmente -dall'argomento \param{flags}, che deve essere specificato come maschera -binaria, ottenuta con un OR aritmetico di una delle costanti del seguente -elenco, che illustra quelle attualmente disponibili:\footnote{si fa - riferimento al momento della stesura di questa sezione, cioè con il kernel - 3.2.} - -\begin{basedescript}{\desclabelwidth{1.5 cm}\desclabelstyle{\nextlinelabel}} - -\item[\constd{CLONE\_CHILD\_CLEARTID}] cancella il valore del \textit{thread - ID} posto all'indirizzo dato dall'argomento \param{ctid}, eseguendo un - riattivazione del \textit{futex} (vedi sez.~\ref{sec:xxx_futex}) a - quell'indirizzo. Questo flag viene utilizzato dalla librerie di gestione dei - \textit{thread} ed è presente dal kernel 2.5.49. - -\item[\constd{CLONE\_CHILD\_SETTID}] scrive il \ids{TID} del \textit{thread} - figlio all'indirizzo dato dall'argomento \param{ctid}. Questo flag viene - utilizzato dalla librerie di gestione dei \textit{thread} ed è presente dal - kernel 2.5.49. - -\item[\constd{CLONE\_FILES}] se impostato il nuovo processo condividerà con il - padre la \textit{file descriptor table} (vedi sez.~\ref{sec:file_fd}), - questo significa che ogni \textit{file descriptor} aperto da un processo - verrà visto anche dall'altro e che ogni chiusura o cambiamento dei - \textit{file descriptor flag} di un \textit{file descriptor} verrà per - entrambi. - - Se non viene impostato il processo figlio eredita una copia della - \textit{file descriptor table} del padre e vale la semantica classica della - gestione dei \textit{file descriptor}, che costituisce il comportamento - ordinario di un sistema unix-like e che illustreremo in dettaglio in - sez.~\ref{sec:file_shared_access}. - -\item[\constd{CLONE\_FS}] se questo flag viene impostato il nuovo processo - condividerà con il padre le informazioni relative all'albero dei file, ed in - particolare avrà la stessa radice (vedi sez.~\ref{sec:file_chroot}), la - stessa directory di lavoro (vedi sez.~\ref{sec:file_work_dir}) e la stessa - \textit{umask} (sez.~\ref{sec:file_perm_management}). Una modifica di una - qualunque di queste caratteristiche in un processo, avrà effetto anche - sull'altro. Se assente il nuovo processo riceverà una copia delle precedenti - informazioni, che saranno così indipendenti per i due processi, come avviene - nel comportamento ordinario di un sistema unix-like. - -\item[\constd{CLONE\_IO}] se questo flag viene impostato il nuovo il nuovo - processo condividerà con il padre il contesto dell'I/O, altrimenti, come - come avviene nel comportamento ordinario con una \func{fork} otterrà un suo - contesto dell'I/O. - - Il contesto dell'I/O viene usato dagli \textit{scheduler} di I/O (visti in - sez.~\ref{sec:io_priority}) e se questo è lo stesso per diversi processi - questi vengono trattati come se fossero lo stesso, condividendo il tempo per - l'accesso al disco, e possono interscambiarsi nell'accesso a disco. L'uso di - questo flag consente, quando più \textit{thread} eseguono dell'I/O per conto - dello stesso processo (ad esempio con le funzioni di I/O asincrono di - sez.~\ref{sec:file_asyncronous_io}), migliori prestazioni. - -%TODO : tutti i CLONE_NEW* attengono ai namespace, ed è meglio metterli nella -%relativa sezione da creare a parte - -% \item[\constd{CLONE\_NEWIPC}] è uno dei flag ad uso dei \textit{container}, -% introdotto con il kernel 2.6.19. L'uso di questo flag crea per il nuovo -% processo un nuovo \textit{namespace} per il sistema di IPC, sia per quello -% di SysV (vedi sez.~\ref{sec:ipc_sysv}) che, dal kernel 2.6.30, per le code -% di messaggi POSIX (vedi sez.~\ref{sec:ipc_posix_mq}); si applica cioè a -% tutti quegli oggetti che non vegono identificati con un \textit{pathname} -% sull'albero dei file. - -% L'uso di questo flag richiede privilegi di amministratore (più precisamente -% la capacità \const{CAP\_SYS\_ADMIN}) e non può essere usato in combinazione -% con \const{CLONE\_SYSVSEM}. - -% \item[\constd{CLONE\_NEWNET}] -% \item[\constd{CLONE\_NEWNS}] -% \item[\constd{CLONE\_NEWPID}] -% \item[\constd{CLONE\_NEWUTS}] - - -% TODO trattare CLONE_NEWCGROUP introdotto con il kernel 4.6, vedi -% http://lwn.net/Articles/680566/ - -\item[\constd{CLONE\_PARENT}] -\item[\constd{CLONE\_PARENT\_SETTID}] -\item[\constd{CLONE\_PID}] - -\item[\constd{CLONE\_PTRACE}] se questo flag viene impostato ed il processo - chiamante viene tracciato (vedi sez.~\ref{sec:process_ptrace}) anche il - figlio viene tracciato. - -\item[\constd{CLONE\_SETTLS}] -\item[\constd{CLONE\_SIGHAND}] -\item[\constd{CLONE\_STOPPED}] -\item[\constd{CLONE\_SYSVSEM}] -\item[\constd{CLONE\_THREAD}] - -\item[\constd{CLONE\_UNTRACED}] se questo flag viene impostato un processo non - può più forzare \const{CLONE\_PTRACE} su questo processo. - -\item[\constd{CLONE\_VFORK}] se questo flag viene impostato il chiamante viene - fermato fintato che il figlio appena creato non rilascia la sua memoria - virtuale con una chiamata a \func{exec} o \func{exit}, viene quindi - replicato il comportamento di \func{vfork}. - -\item[\constd{CLONE\_VM}] se questo flag viene impostato il nuovo processo - condividerà con il padre la stessa memoria virtuale, e le scritture in - memoria fatte da uno qualunque dei processi saranno visibili dall'altro, - così come ogni mappatura in memoria (vedi sez.~\ref{sec:file_memory_map}). - - Se non viene impostato il processo figlio otterrà una copia dello spazio - degli indirizzi e si otterrà il comportamento ordinario di un processo di un - sistema unix-like creato con la funzione \func{fork}. -\end{basedescript} - - -\subsection{I \textit{namespace} ed i \textit{container}} -\label{sec:process_namespaces} - - -%TODO sezione separata sui namespace - -%TODO trattare unshare, vedi anche http://lwn.net/Articles/532748/ - -%TODO: trattare la funzione setns e i namespace file descriptors (vedi -% http://lwn.net/Articles/407495/) introdotti con il kernel 3.0, altre -% informazioni su setns qui: http://lwn.net/Articles/532748/ -% http://lwn.net/Articles/531498/ - - -% TODO trattare le funzioni di protezione della memoria pkey_alloc, pkey_free, -% pkey_mprotect, introdotte con il kernel 4.8, vedi -% http://lwn.net/Articles/689395/ e Documentation/x86/protection-keys.txt - -%TODO trattare kcmp aggiunta con il kernel 3.5, vedi -% https://lwn.net/Articles/478111/ - -%\subsection{La funzione \func{ptrace}} -%\label{sec:process_ptrace} - -%Da fare - -% TODO: trattare PTRACE_SEIZE, aggiunta con il kernel 3.1 -% TODO: trattare PTRACE_O_EXITKILL, aggiunta con il kernel 3.8 (vedi -% http://lwn.net/Articles/529060/) -% TODO: trattare PTRACE_GETSIGMASK e PTRACE_SETSIGMASK introdotte con il -% kernel 3.11 -% TODO: trattare PTRACE_O_SUSPEND_SECCOMP, aggiunta con il kernel 4.3, vedi -% http://lwn.net/Articles/656675/ - -%\subsection{La gestione delle operazioni in virgola mobile} -%\label{sec:process_fenv} - -%Da fare. - -% TODO eccezioni ed arrotondamenti per la matematica in virgola mobile -% consultare la manpage di fenv, math_error, fpclassify, matherr, isgreater, -% isnan, nan, INFINITY - - -%\subsection{L'accesso alle porte di I/O} -%\label{sec:process_io_port} - -% -% TODO l'I/O sulle porte di I/O -% consultare le manpage di ioperm, iopl e outb -% non c'entra nulla qui, va trovato un altro posto (altri meccanismi di I/O in -% fileintro ?) - -%Da fare - - -%\subsection{La gestione di architetture a nodi multipli} -%\label{sec:process_NUMA} - -% TODO trattare i cpuset, che attiene anche a NUMA, e che possono essere usati -% per associare l'uso di gruppi di processori a gruppi di processi (vedi -% manpage omonima) -% TODO trattare getcpu, che attiene anche a NUMA, mettere qui anche -% sched_getcpu, che potrebbe essere indipendente ma richiama getcpu - -%TODO trattare le funzionalità per il NUMA -% vedi man numa e, mbind, get_mempolicy, set_mempolicy, -% le pagine di manuale relative -% vedere anche dove metterle... - -% \subsection{La gestione dei moduli} -% \label{sec:kernel_modules} - -% da fare - -%TODO trattare init_module e finit_module (quest'ultima introdotta con il -%kernel 3.8) - -%%%% Altre cose di cui non è chiara la collocazione: - -%TODO trattare membarrier, introdotta con il kernel 4.3 -% vedi http://lwn.net/Articles/369567/ http://lwn.net/Articles/369640/ -% http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=5b25b13ab08f616efd566347d809b4ece54570d1 -% vedi anche l'ulteriore opzione "expedited" introdotta con il kernel 4.14 -% (https://lwn.net/Articles/728795/) - -\section{Problematiche di programmazione multitasking} +\section{Problematiche di programmazione \textit{multitasking}} \label{sec:proc_multi_prog} Benché i processi siano strutturati in modo da apparire il più possibile come -indipendenti l'uno dall'altro, nella programmazione in un sistema multitasking -occorre tenere conto di una serie di problematiche che normalmente non -esistono quando si ha a che fare con un sistema in cui viene eseguito un solo -programma alla volta. +indipendenti l'uno dall'altro, nella programmazione in un sistema +\textit{multitasking} occorre tenere conto di una serie di problematiche che +normalmente non esistono quando si ha a che fare con un sistema in cui viene +eseguito un solo programma alla volta. Per questo motivo, essendo questo argomento di carattere generale, ci è parso opportuno introdurre sinteticamente queste problematiche, che ritroveremo a @@ -4432,10 +3684,10 @@ quando si ha la certezza che, qualora essa venga effettuata, tutti i passaggi che devono essere compiuti per realizzarla verranno eseguiti senza possibilità di interruzione in una fase intermedia. -In un ambiente multitasking il concetto è essenziale, dato che un processo può -essere interrotto in qualunque momento dal kernel che mette in esecuzione un -altro processo o dalla ricezione di un segnale. Occorre pertanto essere -accorti nei confronti delle possibili \textit{race condition} (vedi +In un ambiente \textit{multitasking} il concetto è essenziale, dato che un +processo può essere interrotto in qualunque momento dal kernel che mette in +esecuzione un altro processo o dalla ricezione di un segnale. Occorre pertanto +essere accorti nei confronti delle possibili \textit{race condition} (vedi sez.~\ref{sec:proc_race_cond}) derivanti da operazioni interrotte in una fase in cui non erano ancora state completate. @@ -4489,13 +3741,13 @@ passi, e può essere compromessa dall'intervento di un altro processo che accede alla stessa risorsa quando ancora non tutti i passi sono stati completati. -Dato che in un sistema multitasking ogni processo può essere interrotto in -qualunque momento per farne subentrare un altro in esecuzione, niente può -assicurare un preciso ordine di esecuzione fra processi diversi o che una -sezione di un programma possa essere eseguita senza interruzioni da parte di -altri. Queste situazioni comportano pertanto errori estremamente subdoli e -difficili da tracciare, in quanto nella maggior parte dei casi tutto -funzionerà regolarmente, e solo occasionalmente si avranno degli errori. +Dato che in un sistema \textit{multitasking} ogni processo può essere +interrotto in qualunque momento per farne subentrare un altro in esecuzione, +niente può assicurare un preciso ordine di esecuzione fra processi diversi o +che una sezione di un programma possa essere eseguita senza interruzioni da +parte di altri. Queste situazioni comportano pertanto errori estremamente +subdoli e difficili da tracciare, in quanto nella maggior parte dei casi tutto +funzionerà regolarmente, e solo occasionalmente si avranno degli errori. Per questo occorre essere ben consapevoli di queste problematiche, e del fatto che l'unico modo per evitarle è quello di riconoscerle come tali e prendere @@ -4521,7 +3773,7 @@ essere soggetto a \textit{race condition} dato potrebbe essere interrotto in qualunque momento da un altro \textit{thread}. In tal caso occorre pianificare con estrema attenzione l'uso delle variabili ed utilizzare i vari meccanismi di sincronizzazione che anche in questo caso sono disponibili (torneremo su -queste problematiche di questo tipo in cap.~\ref{sez:thread_xxx}) +queste problematiche di questo tipo in cap.~\ref{sez:pthread_sync}) \itindbeg{deadlock} @@ -4560,7 +3812,7 @@ Si dice \textsl{rientrante} una funzione che può essere interrotta in qualunque punto della sua esecuzione ed essere chiamata una seconda volta da un altro \textit{thread} di esecuzione senza che questo comporti nessun problema nell'esecuzione della stessa. La problematica è comune nella -programmazione \textit{multi-thread}, ma si hanno gli stessi problemi quando +programmazione con i \textit{thread}, ma si hanno gli stessi problemi quando si vogliono chiamare delle funzioni all'interno dei gestori dei segnali. Fintanto che una funzione opera soltanto con le variabili locali è rientrante; @@ -4618,7 +3870,7 @@ varie funzioni di libreria, che sono identificate aggiungendo il suffisso % LocalWords: shmctl ioperm iopl chroot ptrace accounting swap reboot hangup % LocalWords: vhangup mknod lease permitted inherited inheritable bounding AND % LocalWords: capability capget capset header ESRCH undef version obj clear PT -% LocalWords: pag ssize length proc capgetp preemptive cache runnable +% LocalWords: pag ssize length proc capgetp preemptive cache runnable idled % LocalWords: SIGSTOP soft slice nice niceness counter which SC switch side % LocalWords: getpriority who setpriority RTLinux RTAI Adeos fault FIFO COUNT % LocalWords: yield Robin setscheduler policy param OTHER priority setparam to @@ -4650,7 +3902,8 @@ varie funzioni di libreria, che sono identificate aggiungendo il suffisso % LocalWords: NEWUTS SETTLS SIGHAND SYSVSEM UNTRACED tls ctid CLEARTID panic % LocalWords: loader EISDIR SIGTRAP uninterrutible killable EQUAL sizeof XOR % LocalWords: destset srcset ALLOC num cpus setsize emacs pager getty TID -% LocalWords: reaper SUBREAPER Library futex +% LocalWords: reaper SUBREAPER Library futex klogd named rpc statd NPROC +% LocalWords: EACCESS EBADF EBUSY ENXIO EOPNOTSUPP DISABLE tracer Yama %%% Local Variables: %%% mode: latex diff --git a/thread.tex b/thread.tex index d9b5646..6dce4cc 100644 --- a/thread.tex +++ b/thread.tex @@ -117,7 +117,8 @@ della \acr{glibc}. - +\section{La sincronizzazione dei \textit{thread}} +\label{sec:pthread_sync} \subsection{I \textit{mutex}} \label{sec:pthread_mutex} -- 2.30.2