From: Simone Piccardi Date: Sat, 16 Apr 2005 15:55:44 +0000 (+0000) Subject: Risistemata una figura e riordinati i paragrafi sulle funzioni di gestione X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=be020c396791d8cc5f2564e56cb5be2af891edd4 Risistemata una figura e riordinati i paragrafi sulle funzioni di gestione degli identificatori dei processi. Aggiunte un po' di informazioni sulle funzioni di scheduling e qualche nota sul 2.6, iniziato a documentare sched_{set,get}affinity. --- diff --git a/img/exec_rel.dia b/img/exec_rel.dia index f06e934..79c54ec 100644 Binary files a/img/exec_rel.dia and b/img/exec_rel.dia differ diff --git a/prochand.tex b/prochand.tex index 2975f38..f970dc0 100644 --- a/prochand.tex +++ b/prochand.tex @@ -1191,7 +1191,7 @@ indicato dall'argomento \param{path}, che viene interpretato come il \begin{figure}[htb] \centering - \includegraphics[width=16cm]{img/exec_rel} + \includegraphics[width=15cm]{img/exec_rel} \caption{La interrelazione fra le sei funzioni della famiglia \func{exec}.} \label{fig:proc_exec_relat} \end{figure} @@ -1266,20 +1266,22 @@ dell'eseguibile. Se il programma dinamiche viene usato l'interprete indicato nel segmento \const{PT\_INTERP}, in genere questo è \file{/lib/ld-linux.so.1} per programmi linkati con le \acr{libc5}, e \file{/lib/ld-linux.so.2} per programmi linkati con le -\acr{glibc}. Infine nel caso il file sia uno script esso deve iniziare con una -linea nella forma \cmd{\#!/path/to/interpreter [argomenti]} dove l'interprete -indicato deve essere un programma valido (binario, non un altro script) che -verrà chiamato come se si fosse eseguito il comando \cmd{interpreter - [argomenti] filename}.\footnote{si tenga presente che con Linux quanto viene - scritto come \texttt{argomenti} viene passato all'inteprete come un unico - argomento con una unica stringa di lunghezza massima di 127 caratteri e se - questa dimensione viene ecceduta la stringa viene troncata; altri Unix hanno +\acr{glibc}. + +Infine nel caso il file sia uno script esso deve iniziare con una linea nella +forma \cmd{\#!/path/to/interpreter [argomenti]} dove l'interprete indicato +deve essere un programma valido (binario, non un altro script) che verrà +chiamato come se si fosse eseguito il comando \cmd{interpreter [argomenti] + filename}.\footnote{si tenga presente che con Linux quanto viene scritto + come \texttt{argomenti} viene passato all'inteprete come un unico argomento + con una unica stringa di lunghezza massima di 127 caratteri e se questa + dimensione viene ecceduta la stringa viene troncata; altri Unix hanno dimensioni massime diverse, e diversi comportamenti, ad esempio FreeBSD esegue la scansione della riga e la divide nei vari argomenti e se è troppo lunga restitituisce un errore di \const{ENAMETOOLONG}, una comparazione dei vari comportamenti si trova su \href{http://www.in-ulm.de/~mascheck/various/shebang/} - {\texttt{http://www.in-ulm.de/\~mascheck/various/shebang/}}.} + {\texttt{http://www.in-ulm.de/\tild mascheck/various/shebang/}}.} Con la famiglia delle \func{exec} si chiude il novero delle funzioni su cui è basata la gestione dei processi in Unix: con \func{fork} si crea un nuovo @@ -1458,7 +1460,7 @@ e gruppo effettivi all'inizio dell'esecuzione di un nuovo programma. L'\textsl{user-ID di filesystem} e il \textsl{group-ID di filesystem} sono un'estensione introdotta in Linux per rendere più sicuro l'uso di NFS -(torneremo sull'argomento in sez.~\ref{sec:proc_setfsuid}). Essi sono una +(torneremo sull'argomento in sez.~\ref{sec:proc_setuid}). Essi sono una replica dei corrispondenti identificatori del gruppo \textit{effective}, ai quali si sostituiscono per tutte le operazioni di verifica dei permessi relativi ai file (trattate in sez.~\ref{sec:file_perm_overview}). Ogni @@ -1467,14 +1469,15 @@ riportato su di essi, per cui in condizioni normali si pu ignorarne l'esistenza, in quanto saranno del tutto equivalenti ai precedenti. -\subsection{Le funzioni \func{setuid} e \func{setgid}} +\subsection{Le funzioni di gestione degli identificatori dei processi} \label{sec:proc_setuid} -Le due funzioni che vengono usate per cambiare identità (cioè utente e gruppo -di appartenenza) ad un processo sono rispettivamente \funcd{setuid} e -\funcd{setgid}; come accennato in sez.~\ref{sec:proc_access_id} in Linux esse -seguono la semantica POSIX che prevede l'esistenza dell'\textit{user-ID - salvato} e del \textit{group-ID salvato}; i loro prototipi sono: +Le due funzioni più comuni che vengono usate per cambiare identità (cioè +utente e gruppo di appartenenza) ad un processo sono rispettivamente +\funcd{setuid} e \funcd{setgid}; come accennato in +sez.~\ref{sec:proc_access_id} in Linux esse seguono la semantica POSIX che +prevede l'esistenza dell'\textit{user-ID salvato} e del \textit{group-ID + salvato}; i loro prototipi sono: \begin{functions} \headdecl{unistd.h} \headdecl{sys/types.h} @@ -1563,11 +1566,7 @@ processo, rendendo impossibile riguadagnare i privilegi di amministratore. Questo comportamento è corretto per l'uso che ne fa \cmd{login} una volta che crea una nuova shell per l'utente; ma quando si vuole cambiare soltanto l'\textsl{user-ID effettivo} del processo per cedere i privilegi occorre -ricorrere ad altre funzioni (si veda ad esempio sez.~\ref{sec:proc_seteuid}). - - -\subsection{Le funzioni \func{setreuid} e \func{setregid}} -\label{sec:proc_setreuid} +ricorrere ad altre funzioni. Le due funzioni \funcd{setreuid} e \funcd{setregid} derivano da BSD che, non supportando\footnote{almeno fino alla versione 4.3+BSD TODO, FIXME verificare @@ -1621,14 +1620,10 @@ che si imposta un qualunque valore diverso da quello dall'user-ID reale corrente, l'user-ID salvato viene automaticamente uniformato al valore dell'user-ID effettivo. - -\subsection{Le funzioni \func{seteuid} e \func{setegid}} -\label{sec:proc_seteuid} - -Le due funzioni \funcd{seteuid} e \funcd{setegid} sono un'estensione allo -standard POSIX.1 (ma sono comunque supportate dalla maggior parte degli Unix) -e vengono usate per cambiare gli identificatori del gruppo \textit{effective}; -i loro prototipi sono: +Altre due funzioni, \funcd{seteuid} e \funcd{setegid}, sono un'estensione +dello standard POSIX.1, ma sono comunque supportate dalla maggior parte degli +Unix; esse vengono usate per cambiare gli identificatori del gruppo +\textit{effective} ed i loro prototipi sono: \begin{functions} \headdecl{unistd.h} \headdecl{sys/types.h} @@ -1651,13 +1646,11 @@ all'amministratore di impostare solo l'user-ID effettivo, dato che l'uso normale di \func{setuid} comporta l'impostazione di tutti gli identificatori. -\subsection{Le funzioni \func{setresuid} e \func{setresgid}} -\label{sec:proc_setresuid} - -Le due funzioni \funcd{setresuid} e \funcd{setresgid} sono un'estensione -introdotta in Linux,\footnote{a partire dal kernel 2.1.44.} e permettono un -completo controllo su tutti e tre i gruppi di identificatori (\textit{real}, -\textit{effective} e \textit{saved}), i loro prototipi sono: +Le due funzioni \funcd{setresuid} e \funcd{setresgid} sono invece +un'estensione introdotta in Linux,\footnote{per essere precisi a partire dal + kernel 2.1.44.} e permettono un completo controllo su tutti e tre i gruppi +di identificatori (\textit{real}, \textit{effective} e \textit{saved}), i loro +prototipi sono: \begin{functions} \headdecl{unistd.h} \headdecl{sys/types.h} @@ -1710,15 +1703,13 @@ che queste funzioni sono le uniche in grado di leggere gli identificatori del gruppo \textit{saved}. -\subsection{Le funzioni \func{setfsuid} e \func{setfsgid}} -\label{sec:proc_setfsuid} - -Queste funzioni servono per impostare gli identificatori del gruppo -\textit{filesystem} che sono usati da Linux per il controllo dell'accesso ai -file. Come già accennato in sez.~\ref{sec:proc_access_id} Linux definisce -questo ulteriore gruppo di identificatori, che in circostanze normali sono -assolutamente equivalenti a quelli del gruppo \textit{effective}, dato che -ogni cambiamento di questi ultimi viene immediatamente riportato su di essi. +Infine le funzioni \func{setfsuid} e \func{setfsgid} servono per impostare gli +identificatori del gruppo \textit{filesystem} che sono usati da Linux per il +controllo dell'accesso ai file. Come già accennato in +sez.~\ref{sec:proc_access_id} Linux definisce questo ulteriore gruppo di +identificatori, che in circostanze normali sono assolutamente equivalenti a +quelli del gruppo \textit{effective}, dato che ogni cambiamento di questi +ultimi viene immediatamente riportato su di essi. C'è un solo caso in cui si ha necessità di introdurre una differenza fra gli identificatori dei gruppi \textit{effective} e \textit{filesystem}, ed è per @@ -1755,7 +1746,7 @@ coincide con uno dei di quelli del gruppo \textit{real}, \textit{effective} o \textit{saved}. -\subsection{Le funzioni \func{setgroups} e \func{getgroups}} +\subsection{Le funzioni per la gestione dei gruppi associati a un processo} \label{sec:proc_setgroups} Le ultime funzioni che esamineremo sono quelle che permettono di operare sui @@ -1867,13 +1858,6 @@ compila con il flag \cmd{-ansi}, scrivere codice portabile. -% -% Da fare !!! -% insieme alla risistemazioni dei titoli delle sezioni precedenti -% (accorpare il materiale) qualosa tipo: -% le funzioni di controllo -% estenzioni di Linux -% %\subsection{La gestione delle capabilities} %\label{sec:proc_capabilities} @@ -2026,16 +2010,21 @@ questo la priorit essere eseguito, e quando un processo potrà subentrare ad un altro nell'esecuzione. -Il meccanismo usato da Linux è piuttosto semplice, ad ogni processo è -assegnata una \textit{time-slice}, cioè un intervallo di tempo (letteralmente -una fetta) per il quale esso deve essere eseguito. Il valore della -\textit{time-slice} è controllato dalla cosiddetta \textit{nice} (o -\textit{niceness}) del processo. Essa è contenuta nel campo \var{nice} di -\struct{task\_struct}; tutti i processi vengono creati con lo stesso valore, -ed essa specifica il valore della durata iniziale della \textit{time-slice} -che viene assegnato ad un altro campo della struttura (\var{counter}) quando -il processo viene eseguito per la prima volta e diminuito progressivamente ad -ogni interruzione del timer. +Il meccanismo usato da Linux è piuttosto semplice,\footnote{in realtà nella + serie 2.6.x lo \textit{scheduler} è stato riscritto da zero e può usare + diversi algoritmi, selezionabili sia in fase di compilazione, che, nelle + versioni più recenti, all'avvio (addirittura è stato ideato un sistema + modulare che permette di cambiare lo scheduler al volo, che comunque non è + incluso nel kernel ufficiale).} ad ogni processo è assegnata una +\textit{time-slice}, cioè un intervallo di tempo (letteralmente una fetta) per +il quale esso deve essere eseguito. Il valore della \textit{time-slice} è +controllato dalla cosiddetta \textit{nice} (o \textit{niceness}) del processo. +Essa è contenuta nel campo \var{nice} di \struct{task\_struct}; tutti i +processi vengono creati con lo stesso valore, ed essa specifica il valore +della durata iniziale della \textit{time-slice} che viene assegnato ad un +altro campo della struttura (\var{counter}) quando il processo viene eseguito +per la prima volta e diminuito progressivamente ad ogni interruzione del +timer. Durante la sua esecuzione lo scheduler\index{\textit{scheduler}} scandisce la coda dei processi in stato \textit{runnable} associando, in base al valore di @@ -2201,12 +2190,21 @@ dipende dalla politica di scheduling che si due: \begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}} \item[\textit{FIFO}] \textit{First In First Out}. Il processo viene eseguito - fintanto che non cede volontariamente la CPU, si blocca, finisce o viene - interrotto da un processo a priorità più alta. -\item[\textit{RR}] \textit{Round Robin}. Ciascun processo viene eseguito a - turno per un certo periodo di tempo (una \textit{time slice}). Solo i - processi con la stessa priorità ed in stato \textit{runnable} entrano nel - circolo. + fintanto che non cede volontariamente la CPU (con \func{sched\_yield}), si + blocca, finisce o viene interrotto da un processo a priorità più alta. Se il + processo viene interrotto da uno a priorità più alta esso resterà in cima + alla lista e sarà il primo ad essere eseguito quando i processi a priorità + più alta diverranno inattivi. Se invece lo si blocca volontariamente sarà + posto in coda alla lista (ed altri processi con la stessa priorità potranno + essere eseguiti). +\item[\textit{RR}] \textit{Round Robin}. Il comportamento è del tutto analogo + a quello precedente, con la sola differenza che ciascun processo viene + eseguito al massimo per un certo periodo di tempo (la cosiddetta + \textit{time slice}) dopo di che viene automaticamente posto in fondo alla + coda dei processi con la stessa priorità. In questo modo si ha comunque una + esecuzione a turno di tutti i processi, da cui il nome della politica. Solo + i processi con la stessa priorità ed in stato \textit{runnable} entrano nel + \textsl{girotondo}. \end{basedescript} La funzione per impostare le politiche di scheduling (sia real-time che @@ -2238,7 +2236,7 @@ assolute diverse da zero o politiche \const{SCHED\_FIFO} e \const{SCHED\_RR}. \begin{table}[htb] \centering \footnotesize - \begin{tabular}[c]{|c|l|} + \begin{tabular}[c]{|l|l|} \hline \textbf{Policy} & \textbf{Significato} \\ \hline @@ -2249,8 +2247,8 @@ assolute diverse da zero o politiche \const{SCHED\_FIFO} e \const{SCHED\_RR}. \const{SCHED\_OTHER}& Scheduling ordinario\\ \hline \end{tabular} - \caption{Valori dell'argomento \param{policy} per la funzione - \func{sched\_setscheduler}. } + \caption{Valori dell'argomento \param{policy} per la funzione + \func{sched\_setscheduler}.} \label{tab:proc_sched_policy} \end{table} @@ -2271,6 +2269,12 @@ zero \label{fig:sig_sched_param} \end{figure} +Si tenga presente che quando si imposta una politica di scheduling real-time +per un processo (o se ne cambia la priorità con \func{sched\_setparam}) questo +viene messo in cima alla lista dei processi con la stessa priorità; questo +comporta che verrà eseguito subito, interrompendo eventuali altri processi con +la stessa priorità in quel momento in esecuzione. + Lo standard POSIX.1b prevede comunque che i due valori della massima e minima priorità statica possano essere ottenuti, per ciascuna delle politiche di scheduling \textit{real-time}, tramite le due funzioni @@ -2310,25 +2314,6 @@ volontariamente la CPU (in tal caso, tornando nello stato \textit{runnable} sarà reinserito in coda alla lista); l'esecuzione viene ripresa subito solo nel caso che esso sia stato interrotto da un processo a priorità più alta. -La priorità assoluta può essere riletta indietro dalla funzione -\funcd{sched\_getscheduler}, il cui prototipo è: -\begin{prototype}{sched.h} -{int sched\_getscheduler(pid\_t pid)} - Legge la politica di scheduling per il processo \param{pid}. - - \bodydesc{La funzione ritorna la politica di scheduling in caso di successo - e -1 in caso di errore, nel qual caso \var{errno} può assumere i valori: - \begin{errlist} - \item[\errcode{ESRCH}] il processo \param{pid} non esiste. - \item[\errcode{EINVAL}] il valore di \param{pid} è negativo. - \end{errlist}} -\end{prototype} - -La funzione restituisce il valore (secondo quanto elencato in -tab.~\ref{tab:proc_sched_policy}) della politica di scheduling per il processo -specificato; se \param{pid} è nullo viene restituito quello del processo -chiamante. - Se si intende operare solo sulla priorità assoluta di un processo si possono usare le funzioni \funcd{sched\_setparam} e \funcd{sched\_getparam}, i cui prototipi sono: @@ -2345,7 +2330,10 @@ prototipi sono: e -1 in caso di errore, nel qual caso \var{errno} può assumere i valori: \begin{errlist} \item[\errcode{ESRCH}] il processo \param{pid} non esiste. - \item[\errcode{EINVAL}] il valore di \param{pid} è negativo. + \item[\errcode{EINVAL}] il valore di \param{p} non ha senso per la + politica scelta. + \item[\errcode{EPERM}] il processo non ha i privilegi sufficienti per + eseguire l'operazione. \end{errlist}} \end{functions} @@ -2354,7 +2342,31 @@ L'uso di \func{sched\_setparam} che \func{sched\_setscheduler} specificando 0 come valore di \param{pid} si opera sul processo corrente. La disponibilità di entrambe le funzioni può essere verificata controllando la macro \macro{\_POSIX\_PRIORITY\_SCHEDULING} che è -definita nell'header \file{sched.h}. +definita nell'header \file{sched.h}. + +Si tenga presente che per eseguire la funzione il processo chiamante deve +avere un user-ID effettivo uguale all'user-ID reale o a quello effettivo del +processo di cui vuole cambiare la priorità, oppure deve avere i privilegi di +amministratore (con la capacità \const{CAP\_SYS\_NICE}). + +La priorità assoluta può essere riletta indietro dalla funzione +\funcd{sched\_getscheduler}, il cui prototipo è: +\begin{prototype}{sched.h} +{int sched\_getscheduler(pid\_t pid)} + Legge la politica di scheduling per il processo \param{pid}. + + \bodydesc{La funzione ritorna la politica di scheduling in caso di successo + e -1 in caso di errore, nel qual caso \var{errno} può assumere i valori: + \begin{errlist} + \item[\errcode{ESRCH}] il processo \param{pid} non esiste. + \item[\errcode{EINVAL}] il valore di \param{pid} è negativo. + \end{errlist}} +\end{prototype} + +La funzione restituisce il valore (secondo quanto elencato in +tab.~\ref{tab:proc_sched_policy}) della politica di scheduling per il processo +specificato; se \param{pid} è nullo viene restituito quello del processo +chiamante. L'ultima funzione che permette di leggere le informazioni relative ai processi real-time è \funcd{sched\_rr\_get\_interval}, che permette di ottenere la @@ -2364,7 +2376,7 @@ il suo prototipo {int sched\_rr\_get\_interval(pid\_t pid, struct timespec *tp)} Legge in \param{tp} la durata della \textit{time slice} per il processo \param{pid}. - \bodydesc{La funzione ritorna 0in caso di successo e -1 in caso di errore, + \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di errore, nel qual caso \var{errno} può assumere i valori: \begin{errlist} \item[\errcode{ESRCH}] il processo \param{pid} non esiste. @@ -2396,6 +2408,35 @@ l'esecuzione non sar in modalità \textit{fifo}, per permettere l'esecuzione degli altri processi con pari priorità quando la sezione più urgente è finita. +Infine con il supporto dei sistemi multiprocessore sono state introdotte delle +funzioni che permettono di controllare ... + + +\begin{functions} + \headdecl{sched.h} + + \funcdecl{int sched\_setaffinity(pid\_t pid, unsigned int len, unsigned long + *mask)} + Imposta la maschera di affinità del processo \param{pid}. + + \funcdecl{int sched\_getaffinity(pid\_t pid, unsigned int len, unsigned long + *mask)} + Legge la maschera di affinità del processo \param{pid}. + + \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di errore, + nel qual caso \var{errno} può assumere i valori: + \begin{errlist} + \item[\errcode{ESRCH}] il processo \param{pid} non esiste. + \item[\errcode{EINVAL}] la maschera \param{mask} fa riferimento a + processori che non esistono o la sua lunghezza \param{len} è minore di + quella usata dal kernel. + \item[\errcode{EPERM}] il processo non ha i privilegi sufficienti per + eseguire l'operazione. + \end{errlist} + ed inoltre anche \errval{EFAULT}.} +\end{functions} + + \section{Problematiche di programmazione multitasking} \label{sec:proc_multi_prog}