From f67bf0a685d61f70c3536e1f258b96a658162f9e Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Fri, 18 Oct 2002 14:21:42 +0000 Subject: [PATCH] Correzioni varie, ed aggiunte le tabelle dei dati primitivi. --- fileadv.tex | 60 +++++++++++++++++++++++++----------------- filedir.tex | 34 ++++++++++++++++-------- intro.tex | 74 +++++++++++++++++++++++++++++++++++++++++++++++++--- process.tex | 13 +++++---- prochand.tex | 22 ++++++++-------- 5 files changed, 148 insertions(+), 55 deletions(-) diff --git a/fileadv.tex b/fileadv.tex index 4543962..f0d7570 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -1228,6 +1228,16 @@ bloccare l'accesso al file da parte di altri processi, cos sovrapposizioni, e garantire la atomicità delle operazioni di scrittura. + +\subsection{Il file locking in Linux} +\label{sec:file_linux_file_lock} + +L'implementazione del \textit{file locking} in Linux, benché perfettamente +funzionante, resta una sovrapposizione di diverse interfacce, risultante in +una complessità + + + \subsection{L'\textit{advisory locking}} \label{sec:file_record_locking} @@ -1293,8 +1303,10 @@ intero file, funzione usata per richiedere e rimuovere un \textit{file lock} \end{prototype} Il comportamento della funzione è specificato dal valore dell'argomento -\param{operation}, da passare come maschera binaria dei valori riportati in -\tabref{tab:file_flock_operation}. +\param{operation}, da passare come maschera binaria dei valori riportati in +\tabref{tab:file_flock_operation}. Quando si chiude un file i lock esistenti +su di esso vengono sempre cancellati. + \begin{table}[htb] \centering @@ -1315,20 +1327,15 @@ Il comportamento della funzione \label{tab:file_flock_operation} \end{table} - -Con \func{flock} il blocco è associato direttamente al file (cioè rispetto -allo schema di \secref{sec:file_fd} fa riferimento all'inode e non al file -descriptor); pertanto sia \func{dup} che \func{fork} non creano altre istanze -del blocco ma piuttosto degli ulteriori riferimenti allo stesso \textit{file - lock}. - -La funzione blocca direttamente il file (cioè rispetto allo schema di -\secref{fig:file_stat_struct} fa riferimento alla struttura \var{file}, non al -file descriptor). Pertanto sia \func{dup} che \func{fork} non creano ulteriori -istanze di un \textit{file lock} quanto piuttosto degli ulteriori riferimenti -allo stesso \textit{file lock}. Questo comporta che un lock può essere rimosso -su uno qualunque dei file descriptor che fanno riferimento allo stesso file, -ed esso . +La funzione esegue il blocco direttamente il file (cioè rispetto allo schema +di \secref{fig:file_stat_struct} il blocco è mantenuto in riferimento alla +struttura \var{file}, non al file descriptor). Pertanto sia \func{dup} che +\func{fork} non creano ulteriori istanze di un \textit{file lock} quanto +piuttosto degli ulteriori riferimenti allo stesso. Questo comporta che un +\textit{file lock} può essere rimosso su uno qualunque dei file descriptor che +fanno riferimento allo stesso file: quindi se si toglie il blocco in un +processo figlio o su un file descriptor duplicato, questo sarà cancellato +rispettivamente anche nel processo padre e sul file descriptor originario. La seconda interfaccia per l'\textit{advisory locking} disponibile in Linux è @@ -1360,15 +1367,26 @@ per } \end{prototype} +Si tenga presente che \func{flock} non è in grado di funzionare per i file +manetenuti su NFS, in questo caso, se si ha la necessità di eseguire il +\textit{file locking}, occorre usare l'interfaccia basata su \func{fcntl} che +può funzionare anche attraverso NFS, a condizione che sia il client che il +server supportino questa funzionalità. + + +La standardizzatione operata con POSIX.1 ha adottato le API per il +\textit{file locking} originarie di System V, basate sulla funzione + Al contrario di \func{flock} con \func{fcntl} è possibile bloccare anche solo -delle sezioni di un file. La funzione prende come argomento +delle sezioni di un file. La funzione prende come argomento una struttura +\var{flock} la cui definizione è riportata in \figref{fig:struct_flock}. \begin{figure}[!htb] \footnotesize \centering \begin{minipage}[c]{15cm} \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{} -struct struct { +struct flock { short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */ off_t l_start; /* Offset where the lock begins. */ @@ -1385,12 +1403,6 @@ struct struct { - -Si tenga conto che \func{flock} non è in grado di eseguire il \textit{file - locking} su NFS, se si ha questa necessità occorre usare \func{fcntl} che -funziona anche attraverso NFS, posto che il server supporti il \textit{file - locking}. - \subsection{Il \textit{mandatory locking}} \label{sec:file_mand_locking} diff --git a/filedir.tex b/filedir.tex index 2832634..cc4b004 100644 --- a/filedir.tex +++ b/filedir.tex @@ -381,7 +381,7 @@ stringa con un carattere nullo e la tronca alla dimensione specificata da \begin{figure}[htb] \centering - \includegraphics[width=7cm]{img/link_loop} + \includegraphics[width=9cm]{img/link_loop} \caption{Esempio di loop nel filesystem creato con un link simbolico.} \label{fig:file_link_loop} \end{figure} @@ -929,7 +929,7 @@ riservati per estensioni come tempi pi \footnotesize \centering \begin{minipage}[c]{15cm} - \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} + \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{} struct stat { dev_t st_dev; /* device */ ino_t st_ino; /* inode */ @@ -953,9 +953,9 @@ struct stat { \label{fig:file_stat_struct} \end{figure} -Si noti come i vari membri della struttura siano specificati come tipi nativi -del sistema (di quelli definiti in \tabref{tab:xxx_sys_types}, e dichiarati in -\file{sys/types.h}). +Si noti come i vari membri della struttura siano specificati come tipi +primitivi del sistema (di quelli definiti in +\tabref{tab:intro_primitive_types}, e dichiarati in \file{sys/types.h}). \subsection{I tipi di file} @@ -1295,13 +1295,25 @@ Cambia i tempi di ultimo accesso e modifica dell'inode specificato da \end{errlist}} \end{prototype} -La struttura \var{utimebuf} usata da \func{utime} è definita come: -\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} +La funzione prende come argomento \param{times} una struttura \var{utimebuf}, +la cui definizione è riportata in \figref{fig:struct_utimebuf}, con la quale +si possono specificare i nuovi valori che si vogliono impostare per tempi. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{} struct utimbuf { time_t actime; /* access time */ time_t modtime; /* modification time */ }; -\end{lstlisting} + \end{lstlisting} + \end{minipage} + \normalsize + \caption{La struttura \type{utimbuf}, usata da \func{utime} per modificare i + tempi dei file.} + \label{fig:struct_utimebuf} +\end{figure} L'effetto della funzione e i privilegi necessari per eseguirla dipendono da cosa è l'argomento \param{times}; se è \macro{NULL} la funzione imposta il @@ -1314,9 +1326,9 @@ cambiamento di stato del file, che viene comunque cambiato dal kernel tutte le volte che si modifica l'inode (quindi anche alla chiamata di \func{utime}). Questo serve anche come misura di sicurezza per evitare che si possa modificare un file nascondendo completamente le proprie tracce. In realtà la -cosa resta possibile, se si è in grado di accedere al device, scrivendo -direttamente sul disco senza passare attraverso il filesystem, ma ovviamente -in questo modo la cosa è molto più complicata da realizzare. +cosa resta possibile, se si è in grado di accedere al file di dispositivo, +scrivendo direttamente sul disco senza passare attraverso il filesystem, ma +ovviamente in questo modo la cosa è molto più complicata da realizzare. diff --git a/intro.tex b/intro.tex index 77178be..1dfaaf9 100644 --- a/intro.tex +++ b/intro.tex @@ -297,9 +297,19 @@ quelli definiti negli altri standard descritti nelle sezioni successive. \textbf{Standard} & \textbf{Contenuto} \\ \hline \hline - \texttt{stdio.h} & I/O bufferizzato in standard ANSI C.\\ - \texttt{stdlib.h} & definizioni della libreria standard.\\ - \texttt{...} & Da completare.\\ + \file{assert.h}& Verifica le asserzioni fatte in un programma.\\ + \file{cpio.h} & .\\ + \file{} & .\\ + \file{} & .\\ + \file{} & .\\ + \file{} & .\\ + \file{} & .\\ + \file{} & .\\ + \file{} & .\\ + \file{} & .\\ + \file{} & .\\ + \file{stdio.h} & I/O bufferizzato in standard ANSI C.\\ + \file{stdlib.h}& definizioni della libreria standard.\\ \hline \end{tabular} \caption{Elenco dei vari file di include definiti dallo standard POSIX.} @@ -307,7 +317,6 @@ quelli definiti negli altri standard descritti nelle sezioni successive. \end{table} - In realtà \acr{glibc} ed i relativi header file definiscono un insieme di funzionalità in cui sono incluse come sottoinsieme anche quelle previste dallo standard ANSI C. È possibile ottenere una conformità stretta allo standard @@ -317,6 +326,63 @@ header file soltanto le funzionalit usare le varie estensioni al linguaggio e al preprocessore da esso supportate. +\subsection{I tipi di dati primitivi} +\label{sec:intro_data_types} + +Uno dei problemi di portabilità del codice più comune è quello dei tipi di +dati utilizzati nei programmi, che spesso variano da sistema a sistema, o +anche da una architettura ad un altra (ad esempio passando da macchine con +processori 32 bit a 64). + +Storicamente alcuni tipi di dati definiti dallo standard ANSI C sono sempre +stati associati ad alcune variabili nei sistemi Unix, ad esempio la posizione +corrente all'interno di un file è sempre stato associato ad un intero a 32 +bit, mentre il numero di dispositivo è sempre stato associato ad un intero a +16 bit. Tutto questo ovviamente costituisce un incubo per la portabilità tutte +le volte che, con l'evolversi delle piattaforme hardware, alcuni di questi +tipi si sono rivelati inadeguati, e se ne è dovuto cambiare la dimensione. + +\begin{table}[htb] + \footnotesize + \centering + \begin{tabular}[c]{|l|l|} + \hline + \textbf{Tipo} & \textbf{Contenuto} \\ + \hline + \hline + \type{caddr\_t} & core address.\\ + \type{clock\_t} & contatore del tempo di sistema.\\ + \type{dev\_t} & Numero di dispositivo.\\ + \type{gid\_t} & Identificatore di un gruppo.\\ + \type{ino\_t} & Numero di \textit{inode}.\\ + \type{key\_t} & Chiave per il System V IPC.\\ + \type{loff\_t} & Posizione corrente in un file.\\ + \type{mode\_t} & Attributi di un file.\\ + \type{nlink\_t} & Contatore dei link su un file.\\ + \type{off\_t} & Posizione corrente in un file.\\ + \type{pid\_t} & Identificatore di un processo.\\ + \type{rlim\_t} & Limite sulle risorse.\\ + \type{sigset\_t}& Insieme di segnali.\\ + \type{ssize\_t} & Dimensione di un oggetto.\\ + \type{ssize\_t} & Dimensione in numero byte ritornata dalle funzioni.\\ + \type{ptrdiff\_t}& Differenza fra due puntatori.\\ + \type{time\_t} & Numero di secondi (in tempo di calendario).\\ + \type{uid\_t} & Identificatore di un utente.\\ + \hline + \end{tabular} + \caption{Elenco dei tipi primitivi, definiti in \file{sys/types.h}.} + \label{tab:intro_primitive_types} +\end{table} + +Per questo motivo tutte le funzioni di libreria di solito non fanno +riferimento ai tipi standard del linguaggio C, ma ad una serie di \textsl{tipi + primitivi}, riportati in \tabref{tab:intro_primitive_types}, caratteristici +di ogni sistema, definiti nell'header file \file{sys/types.h}, che associano i +tipi utilizzati dalle funzioni di sistema ai tipi elementari supportati dal +compilatore C. + + + \subsection{Lo standard IEEE -- POSIX} \label{sec:intro_posix} diff --git a/process.tex b/process.tex index 9a23884..961a25a 100644 --- a/process.tex +++ b/process.tex @@ -1028,11 +1028,12 @@ configurazione. La shell ad esempio ne usa molte per il suo funzionamento (come \var{PATH} per la ricerca dei comandi, o \cmd{IFS} per la scansione degli argomenti), e -alcune di esse (come \var{HOME}, \var{USER}, etc.) sono definite al login. In -genere è cura dell'amministratore definire le opportune variabili di ambiente -in uno script di avvio. Alcune servono poi come riferimento generico per molti -programmi (come \var{EDITOR} che indica l'editor preferito da invocare in caso -di necessità). +alcune di esse (come \var{HOME}, \var{USER}, etc.) sono definite al login (per +i dettagli si veda \secref{sec:sess_login}). In genere è cura +dell'amministratore definire le opportune variabili di ambiente in uno script +di avvio. Alcune servono poi come riferimento generico per molti programmi +(come \var{EDITOR} che indica l'editor preferito da invocare in caso di +necessità). Gli standard POSIX e XPG3 definiscono alcune di queste variabili (le più comuni), come riportato in \tabref{tab:proc_env_var}. GNU/Linux le supporta @@ -1041,6 +1042,7 @@ controllare \cmd{man environ}. \begin{table}[htb] \centering + \footnotesize \begin{tabular}[c]{|l|c|c|c|p{7cm}|} \hline \textbf{Variabile} & \textbf{POSIX} & \textbf{XPG3} @@ -1088,6 +1090,7 @@ in \tabref{tab:proc_env_func}. \begin{table}[htb] \centering + \footnotesize \begin{tabular}[c]{|l|c|c|c|c|c|c|} \hline \textbf{Funzione} & \textbf{ANSI C} & \textbf{POSIX.1} & \textbf{XPG3} & diff --git a/prochand.tex b/prochand.tex index 534049e..3f09375 100644 --- a/prochand.tex +++ b/prochand.tex @@ -2117,9 +2117,10 @@ priorit nel caso di Linux non si tratta di un vero hard real-time, in quanto in presenza di eventuali interrupt il kernel interrompe l'esecuzione di un processo qualsiasi sia la sua priorità,\footnote{questo a meno che non si - siano installate le patch di RTLinux o RTAI, con i quali è possibile + siano installate le patch di RTLinux, RTAI o Adeos, con i quali è possibile ottenere un sistema effettivamente hard real-time. In tal caso infatti gli - interrupt vengono intercettati dall'interfaccia real-time, e gestiti + interrupt vengono intercettati dall'interfaccia real-time (o nel caso di + Adeos gestiti dalle code del nano-kernel), in modo da poterlo controllare direttamente qualora ci sia la necessità di avere un processo con priorità più elevata di un \textit{interrupt handler}.} mentre con l'incorrere in un page fault\index{page fault} si possono avere ritardi non previsti. Se @@ -2143,17 +2144,16 @@ eseguito per primo quello con priorit processi con la stessa priorità assoluta questi vengono tenuti in una coda tocca al kernel decidere quale deve essere eseguito. - - Il meccanismo con cui vengono gestiti questi processi dipende dalla politica di scheduling che si è scelto; lo standard ne prevede due: -\begin{basedescript}{\desclabelwidth{3cm}\desclabelstyle{\nextlinelabel}} -\item[\textit{FIFO}] 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{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. +\begin{basedescript}{\desclabelwidth{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. \end{basedescript} La funzione per impostare le politiche di scheduling (sia real-time che -- 2.30.2