\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}
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
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
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}
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
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}
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}
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
\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
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}
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
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
\begin{table}[htb]
\centering
\footnotesize
- \begin{tabular}[c]{|c|l|}
+ \begin{tabular}[c]{|l|l|}
\hline
\textbf{Policy} & \textbf{Significato} \\
\hline
\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}
\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
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:
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}
\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
{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.
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}