From: Simone Piccardi Date: Fri, 4 Oct 2019 08:07:47 +0000 (+0200) Subject: Varie correzioni, completata revisione capitolo sull'I/O su file X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=fa15a3f1ecd64efd8440e46d398fd9976abc3d25 Varie correzioni, completata revisione capitolo sull'I/O su file --- diff --git a/fileadv.tex b/fileadv.tex index 15b32e4..c3300a6 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -5835,15 +5835,25 @@ file uno \textit{sparse file} a posteriori. % TODO aggiungere FALLOC_FL_INSERT vedi http://lwn.net/Articles/629965/ - % TODO aggiungere i file hints di fcntl (F_GET_RW_HINT e compagnia) % con RWH_WRITE_LIFE_EXTREME e RWH_WRITE_LIFE_SHORT aggiunte con % il kernel 4.13 (vedi https://lwn.net/Articles/727385/) +\subsection{Altre funzionalità avanzate} +\label{sec:file_seal_et_al} + +da fare + % TODO non so dove trattarli, ma dal 2.6.39 ci sono i file handle, vedi % http://lwn.net/Articles/432757/ (probabilmente da associare alle % at-functions) +% TODO: trattare i file seal, vedi fcntl / F_ADD_SEAL e memfd_create + +% TODO trattare qui ioctl_ficlonerange ? + + + % LocalWords: dell'I locking multiplexing cap sez system call socket BSD GID % LocalWords: descriptor client deadlock NONBLOCK EAGAIN polling select kernel diff --git a/fileio.tex b/fileio.tex index 59efa44..6639ac3 100644 --- a/fileio.tex +++ b/fileio.tex @@ -1,4 +1,4 @@ -%% fileio.tex (merge fileunix.tex - filestd.tex) +s%% fileio.tex (merge fileunix.tex - filestd.tex) %% %% Copyright (C) 2000-2019 Simone Piccardi. Permission is granted to %% copy, distribute and/or modify this document under the terms of the GNU Free @@ -2857,8 +2857,8 @@ Per le operazioni di manipolazione e di controllo delle varie proprietà e caratteristiche di un file descriptor, viene usata la funzione di sistema \funcd{fcntl},\footnote{ad esempio si gestiscono con questa funzione varie modalità di I/O asincrono (vedi sez.~\ref{sec:file_asyncronous_operation}) e - il \textit{file locking} (vedi sez.~\ref{sec:file_locking}).} il cui -prototipo è: + il \textit{file locking} (vedi sez.~\ref{sec:file_locking}) e altre + funzionalità avanzate che tratteremo più avanti.} il cui prototipo è: \begin{funcproto}{ \fhead{unistd.h} @@ -2866,13 +2866,13 @@ prototipo è: \fdecl{int fcntl(int fd, int cmd)} \fdecl{int fcntl(int fd, int cmd, int arg)} \fdecl{int fcntl(int fd, int cmd, ...)} -\fdesc{Esegue una operazione di controllo sul file.} +\fdesc{Esegue una operazione di controllo su un file descriptor.} } {La funzione ha valori di ritorno diversi a seconda dell'operazione richiesta in caso di successo mentre ritorna sempre $-1$ per un errore, nel qual caso \var{errno} assumerà valori diversi che dipendono dal tipo di operazione, - gli unici con signifiato generico sono: + gli unici con significato generico sono: \begin{errlist} \item[\errcode{EBADF}] \param{fd} non è un file aperto. \item[\errcode{EINVAL}] \param{cmd} non è un comando supportato dal kernel @@ -2964,9 +2964,9 @@ il nome indicato nel precedente prototipo), è riportata di seguito: \item[\constd{F\_GETLK}] richiede un controllo sul \textit{file lock} specificato nella struttura \struct{flock} puntata dal terzo argomento (che pertanto dovrà essere di tipo \ctyp{struct flock *}) sovrascrivendone il - contenuto con il risultato, ritorna un valore nullo in caso di successo o + contenuto con il risultato; ritorna un valore nullo in caso di successo o $-1$ in caso di errore. Come per i due successivi comandi oltre a - \errval{EBADF} se il terzo argomento non è un puntatore valido restituisce + \errval{EBADF}, se il terzo argomento non è un puntatore valido, restituisce l'errore generico \errcode{EFAULT}. Questa funzionalità è trattata in dettaglio in sez.~\ref{sec:file_posix_lock}. @@ -3083,8 +3083,8 @@ il nome indicato nel precedente prototipo), è riportata di seguito: l'identificatore del processo, \textit{thread} o \textit{process group} che è preposto alla ricezione dei segnali \signal{SIGIO} e \signal{SIGURG} per gli eventi associati al file descriptor \param{fd}. Ritorna un valore nullo - in caso di successo o $-1$ in caso di errore. Oltre a \errval{EBADF} e da - \errval{EFAULT} se \param{owner} non è un puntatore valido. + in caso di successo o $-1$ in caso di errore. Oltre a \errval{EBADF} l'unico + altro errore è \errval{EFAULT} se \param{owner} non è un puntatore valido. Il comando, che è disponibile solo a partire dal kernel 2.6.32, effettua lo stesso compito di \const{F\_GETOWN} di cui costituisce una evoluzione che @@ -3115,8 +3115,8 @@ il nome indicato nel precedente prototipo), è riportata di seguito: un tipo di identificatore valido. Come \const{F\_GETOWN\_EX} il comando richiede come terzo argomento il - puntatore ad una struttura \struct{f\_owner\_ex} la cui definizione è - riportata in fig.~\ref{fig:f_owner_ex}, in cui il campo \var{type} indica il + puntatore ad una struttura \struct{f\_owner\_ex} (la cui definizione è + riportata in fig.~\ref{fig:f_owner_ex}) in cui il campo \var{type} indica il tipo di identificatore che si intende usare, mentre il relativo valore è specificato nel campo \var{pid}, che assume lo stesso significato del terzo argomenti di \const{F\_SETOWN}. @@ -3128,18 +3128,19 @@ il nome indicato nel precedente prototipo), è riportata di seguito: di \const{F\_SETOWN} se si specifica un \textit{Tread ID} questo riceverà sia \signal{SIGIO} (o il segnale impostato con \const{F\_SETSIG}) che \signal{SIGURG}. Il comando è specifico di Linux, è disponibile solo a - partire dal kernel 2.6.32, ed è utilizzabile solo se si è definita la macro + partire dal kernel 2.6.32 ed è utilizzabile solo se si è definita la macro \macro{\_GNU\_SOURCE}. -\item[\constd{F\_GETSIG}] restituisce il valore del segnale inviato dai vari - meccanismi di I/O asincrono associati al file descriptor \param{fd} (quelli - trattati in sez.~\ref{sec:file_asyncronous_operation}) in caso di successo o - $-1$ in caso di errore, il terzo argomento viene ignorato. Non sono previsti - errori diversi da \errval{EBADF}. Un valore nullo indica che si sta usando - il segnale predefinito, che è \signal{SIGIO}. Un valore diverso da zero - indica il segnale che è stato impostato con \const{F\_SETSIG}, che può - essere anche lo stesso \signal{SIGIO}. Il comando è specifico di Linux ed - utilizzabile solo se si è definita la macro \macro{\_GNU\_SOURCE}. +\item[\constd{F\_GETSIG}] restituisce in caso di successo il valore del + segnale inviato dai vari meccanismi di I/O asincrono associati al file + descriptor \param{fd} (quelli trattati in + sez.~\ref{sec:file_asyncronous_operation}) o $-1$ in caso di errore, il + terzo argomento viene ignorato. Non sono previsti errori diversi da + \errval{EBADF}. Un valore nullo indica che si sta usando il segnale + predefinito, che è \signal{SIGIO}. Un valore diverso da zero indica il + segnale che è stato impostato con \const{F\_SETSIG}, che può essere anche lo + stesso \signal{SIGIO}. Il comando è specifico di Linux ed utilizzabile solo + se si è definita la macro \macro{\_GNU\_SOURCE}. \item[\constd{F\_SETSIG}] imposta il segnale inviato dai vari meccanismi di I/O asincrono associati al file descriptor \param{fd} (quelli trattati in @@ -3177,15 +3178,16 @@ il nome indicato nel precedente prototipo), è riportata di seguito: valori di tab.~\ref{tab:file_lease_fctnl}), \errcode{ENOMEM} se non c'è memoria sufficiente per creare il \textit{file lease}, \errcode{EACCES} se non si è il proprietario del file e non si hanno i privilegi di - amministratore (per la precisione occorre la capacità \const{CAP\_LEASE}). - - Il supporto il supporto per i \textit{file lease}, che consente ad un - processo che detiene un \textit{lease} su un file di riceve una notifica - qualora un altro processo cerchi di eseguire una \func{open} o una - \func{truncate} su di esso è stato introdotto a partire dai kernel della - serie 2.4 Il comando è specifico di Linux ed utilizzabile solo se si è - definita la macro \macro{\_GNU\_SOURCE}. Questa funzionalità è trattata in - dettaglio in sez.~\ref{sec:file_asyncronous_lease}. + amministratore (per la precisione occorre la capacità \const{CAP\_LEASE}, + vedi sez.~\ref{sec:proc_capabilities}). + + Il supporto per i \textit{file lease}, che consente ad un processo che + detiene un \textit{lease} su un file di ricevere una notifica qualora un + altro processo cerchi di eseguire una \func{open} o una \func{truncate} su + di esso, è stato introdotto a partire dai kernel della serie 2.4. Il comando + è specifico di Linux ed utilizzabile solo se si è definita la macro + \macro{\_GNU\_SOURCE}. Questa funzionalità è trattata in dettaglio in + sez.~\ref{sec:file_asyncronous_lease}. \item[\constd{F\_NOTIFY}] attiva il meccanismo di notifica asincrona per cui viene riportato al processo chiamante, tramite il segnale \signal{SIGIO} (o @@ -3222,27 +3224,25 @@ il nome indicato nel precedente prototipo), è riportata di seguito: I processi non privilegiati (occorre la capacità \const{CAP\_SYS\_RESOURCE}) non possono impostare un valore superiore a quello indicato da - \sysctlfiled{fs/pipe-size-max}. Il comando è specifico di Linux, è + \sysctlfiled{fs/pipe-max-size}. Il comando è specifico di Linux, è disponibile solo a partire dal kernel 2.6.35, ed è utilizzabile solo se si è definita la macro \macro{\_GNU\_SOURCE}. \item[\constd{F\_GET\_SEALS}] restituisce in caso di successo l'insieme dei - \textit{file seal} presenti su \param{fd}, 0 se non ve ne sono o $-1$ in + \textit{file seal} presenti su \param{fd}: 0 se non ve ne sono o $-1$ in caso di errore, il terzo argomento viene ignorato. Oltre a \errval{EBADF} se il file non supporta i \textit{file seal} viene restituito un errore di \errval{EINVAL}. Il comando è specifico di Linux, è disponibile solo a partire dal kernel 3.17. Questa funzionalità è trattata in dettaglio in - sez.~\ref{sec:file_seal}. + sez.~\ref{sec:file_seal_et_al}. \item[\constd{F\_ADD\_SEALS}] aggiunge i \textit{file seal} espressi come maschera binaria nell'argomento \param{arg} a quelli presenti su \param{fd}, ritorna un valore nullo in caso di successo o $-1$ in caso di errore. Il comando è specifico di Linux, è disponibile solo a partire dal kernel 3.17. Questa funzionalità è trattata in dettaglio in - sez.~\ref{sec:file_seal}. + sez.~\ref{sec:file_seal_et_al}. - % TODO: trovare dove trattare i file seal - \item[\constd{F\_GET\_RW\_HINT}] legge il valore dei \textit{read/write hints} associati all'\textit{inode} a cui fa riferimento \param{fd} nella variabile puntata dal terzo argomento che deve essere di tipo \ctyp{uint64\_t @@ -3278,9 +3278,6 @@ il nome indicato nel precedente prototipo), è riportata di seguito: \end{basedescript} -% TODO: trattare RWH_WRITE_LIFE_EXTREME e RWH_WRITE_LIFE_SHORT aggiunte con -% il kernel 4.13 (vedi https://lwn.net/Articles/727385/) - La maggior parte delle funzionalità controllate dai comandi di \func{fcntl} sono avanzate e richiedono degli approfondimenti ulteriori, saranno pertanto riprese più avanti quando affronteremo le problematiche ad esse relative. In @@ -3288,7 +3285,7 @@ particolare le tematiche relative all'I/O asincrono e ai vari meccanismi di notifica saranno trattate in maniera esaustiva in sez.~\ref{sec:file_asyncronous_operation}, quelle relative al \textit{file locking} saranno esaminate in sez.~\ref{sec:file_locking}, quelle relative -ai \textit{file seal} in sez.~\ref{sec:file_seal} e quelle relative ai +ai \textit{file seal} in sez.~\ref{sec:file_seal_et_al} e quelle relative ai \textit{read/write hints} in sez.~\ref{sec:file_fadvise}. L'uso di questa funzione con i socket verrà trattato in sez.~\ref{sec:sock_ctrl_func}. @@ -3355,16 +3352,16 @@ sistematica le operazioni che si possono gestire con \func{ioctl}, un breve elenco di alcuni esempi di esse è il seguente: \begin{itemize*} \item il cambiamento dei font di un terminale. -\item l'esecuzione di una traccia audio di un CDROM. +\item l'esecuzione di una traccia audio di un CD. \item i comandi di avanti veloce e di riavvolgimento di un nastro. \item il comando di espulsione di un dispositivo rimovibile. \item l'impostazione della velocità trasmissione di una linea seriale. \item l'impostazione della frequenza e della durata dei suoni emessi dallo speaker. -\item l'impostazione degli attributi dei file su un filesystem - ext2.\footnote{i comandi \texttt{lsattr} e \texttt{chattr} fanno questo con - delle \func{ioctl} dedicate, usabili solo su questo filesystem e derivati - successivi (come ext3).} +\item l'impostazione degli attributi dei file (vedi + sez.~\ref{sec:file_perm_management}) su un filesystem.\footnote{i comandi + \texttt{lsattr} e \texttt{chattr} fanno questo con delle \func{ioctl} + dedicate, usabili solo sui filesystem che li supportano.} \end{itemize*} In generale ogni dispositivo ha un suo insieme di operazioni specifiche @@ -3453,7 +3450,6 @@ due funzioni sono rimaste. % EXT4_IOC_SHUTDOWN (dal 4.10), XFS_IOC_GOINGDOWN e futura FS_IOC_SHUTDOWN % ioctl di btrfs, vedi http://lwn.net/Articles/580732/ -% \chapter{} \section{L'interfaccia standard ANSI C} \label{sec:files_std_interface} @@ -3470,9 +3466,10 @@ standard (che sono state implementate la prima volta da Ritchie nel 1976 e da allora sono rimaste sostanzialmente immutate), vengono a costituire il nucleo della \acr{glibc} per la gestione dei file. -Esamineremo in questa sezione le funzioni base dell'interfaccia degli -\textit{stream}, analoghe a quelle di sez.~\ref{sec:file_unix_interface} per i -file descriptor. In particolare vedremo come aprire, leggere, scrivere e +Esamineremo in questa sezione le funzioni base di questa interfaccia che +chiameremo, per distinguerla dalla precedente ``degli \textit{stream}''. Esse +sono analoghe a quelle di sez.~\ref{sec:file_unix_interface} per i file +descriptor, ed in particolare vedremo come aprire, leggere, scrivere e cambiare la posizione corrente in uno \textit{stream}. @@ -3721,7 +3718,16 @@ essere aperti con le funzioni delle librerie standard del C. scrittura.\\ \hline \texttt{b} & Specifica che il file è binario, non ha alcun effetto. \\ - \texttt{x} & L'apertura fallisce se il file esiste già. \\ + \texttt{c} & Evita che l'apertura e seguenti letture o scritture diventino + un \textit{cancellation point} per i \textit{thread}; + presente dalla \acr{glibc} 2.3.3. \\ + \texttt{e} & Apre il file con il flag di \const{O\_CLOEXEC}; presente + dalla \acr{glibc} 2.7. \\ + \texttt{m} & Cerca di accedere al file con \func{mmap} invece + che con le funzioni di I/O classiche; presente + dalla \acr{glibc} 2.3. \\ + \texttt{x} & L'apertura fallisce se il file esiste già (ignorato con + \func{fdopen}).\\ \hline \end{tabular} \caption{Modalità di apertura di uno \textit{stream} dello standard ANSI C @@ -3732,24 +3738,35 @@ essere aperti con le funzioni delle librerie standard del C. In realtà lo standard ANSI C prevede un totale di 15 possibili valori diversi per \param{mode}, ma in tab.~\ref{tab:file_fopen_mode} si sono riportati solo i sei valori effettivi, ad essi può essere aggiunto pure -il carattere \texttt{b} (come ultimo carattere o nel mezzo agli altri per +il carattere ``\texttt{b}'' (come ultimo carattere o nel mezzo agli altri per le stringhe di due caratteri) che in altri sistemi operativi serve a distinguere i file binari dai file di testo; in un sistema POSIX questa distinzione non esiste e il valore viene accettato solo per compatibilità, ma non ha alcun effetto. La \acr{glibc} supporta alcune estensioni, queste devono essere sempre -indicate dopo aver specificato il \param{mode} con uno dei valori di -tab.~\ref{tab:file_fopen_mode}. L'uso del carattere \texttt{x} serve per -evitare di sovrascrivere un file già esistente (è analoga all'uso dell'opzione -\const{O\_EXCL} in \func{open}): se il file specificato già esiste e si -aggiunge questo carattere a \param{mode} la \func{fopen} fallisce. - -% Un'altra estensione serve a supportare la localizzazione, quando si -% aggiunge a \param{mode} una stringa della forma \verb|",ccs=STRING"| il -% valore \verb|STRING| è considerato il nome di una codifica dei caratteri -% e \func{fopen} marca il file per l'uso dei caratteri estesi e abilita le -% opportune funzioni di conversione in lettura e scrittura. +indicate dopo aver specificato il \param{mode} con uno dei valori della +seconda sezione di tab.~\ref{tab:file_fopen_mode}. Ad esempio l'uso del +carattere ``\texttt{e}'' serve ad impostare il \textit{close-on-exec} sul file +(è analoga all'uso del flag \const{O\_CLOEXEC} in \func{open}), ``\texttt{x}'' +serve per evitare di sovrascrivere un file già esistente (è analoga all'uso +del flag \const{O\_EXCL} in \func{open}): se il file specificato già esiste e +si aggiunge questo carattere a \param{mode} la \func{fopen} fallisce. + +Altri due valori hanno usi specialistici, con ``\texttt{m}'' si chiede di +usare il \textit{memory mapping} per l'accesso al file (tratteremo i file +mappati in memoria in sez.~\ref{sec:file_memory_map}), ma la funzionalità è al +momento disponibile solo per i file aperti in sola lettura. Con ``\texttt{c}'' +infine si richiede che l'apertura, e le successive operazioni di lettura e +scrittura, non diventino un \textit{cancellation point} per i \textit{thread} +(tratteremo l'argomento in sez.~\ref{sec:xxx_thread}). + +Un'altra estensione serve a supportare la localizzazione, quando si aggiunge a +\param{mode} una stringa della forma \verb|",ccs=STRING"| (che deve essere +sempre in coda a tutte le altre) il valore \verb|STRING| è considerato il nome +di una codifica dei caratteri e \func{fopen} marca il file per l'uso dei +caratteri estesi e abilita le opportune funzioni di conversione in lettura e +scrittura. Nel caso si usi \func{fdopen} i valori specificati da \param{mode} devono essere compatibili con quelli con cui il file descriptor è stato aperto. @@ -3837,8 +3854,7 @@ sez.~\ref{sec:proc_conclusion}). Una delle caratteristiche più utili dell'interfaccia degli \textit{stream} è la ricchezza delle funzioni disponibili per le operazioni di lettura e scrittura sui file. Sono infatti previste ben tre diverse modalità di -input/output non formattato, che tratteremo in -sez.~\ref{sec:file_unformatted_io}: +input/output non formattato: \begin{itemize*} \item\textsl{Input/Output binario}, una modalità in cui si leggono e scrivono blocchi di dati di dimensione arbitraria; è l'analogo della modalità @@ -3847,17 +3863,17 @@ sez.~\ref{sec:file_unformatted_io}: \item\textsl{Input/Output a caratteri}, una modalità in cui si legge e scrive un singolo carattere alla volta, anche in questo caso la bufferizzazione viene gestita automaticamente dalla libreria; -\item\textsl{input/output di linea}, una modalità in cui si legge e scrive una +\item\textsl{Input/Output di linea}, una modalità in cui si legge e scrive una linea di testo alla volta, in questa modalità si intende per linea una sequenza di caratteri terminata dal carattere di \textit{newline} (\verb|'\n'|); \end{itemize*} -A queste tre modalità si aggiunge poi la modalità di input/output formattato, +A queste tre modalità si aggiunge poi la modalità di input/output formattato che tratteremo in sez.~\ref{sec:file_unformatted_io}. Ognuna di queste modalità utilizza per l'I/O delle funzioni specifiche che vedremo più avanti, affronteremo qui invece gli argomenti e le funzioni che si applicano in -generale a tutte tutte queste diverse modalità di I/O. +generale a tutte queste diverse modalità di I/O. Una prima caratteristica specifica è che differenza di quanto avviene con l'interfaccia dei file descriptor, con gli \textit{stream} il raggiungimento @@ -4039,10 +4055,10 @@ i rispettivi prototipi sono: \begin{funcproto}{ \fhead{stdio.h} \fdecl{size\_t fread(void *ptr, size\_t size, size\_t nmemb, FILE *stream)} -\fdesc{Legge i dati da uno \textit{stream}.} +\fdesc{Legge i dati da uno \textit{stream} ad un buffer.} \fdecl{size\_t fwrite(const void *ptr, size\_t size, size\_t nmemb, FILE *stream)} -\fdesc{Scrive i dati su uno \textit{stream}.} +\fdesc{Scrive i dati da un buffer su uno \textit{stream}.} } {Le funzioni ritornano il numero di elementi letti o scritti, in caso di @@ -4104,29 +4120,6 @@ permetta di recuperare l'informazione completa, per assicurarsi che versioni diverse del programma siano in grado di rileggere i dati, tenendo conto delle eventuali differenze. -La \acr{glibc} definisce infine due ulteriori funzioni per l'I/O binario, -\funcd{fread\_unlocked} e \funcd{fwrite\_unlocked}, che evitano il lock -implicito dello \textit{stream} usato per dalla librerie per la gestione delle -applicazioni \textit{multi-thread} (si veda sez.~\ref{sec:file_stream_thread} -per i dettagli), i loro prototipi sono: - -\begin{funcproto}{ -\fhead{stdio.h} -\fdecl{size\_t fread\_unlocked(void *ptr, size\_t size, size\_t - nmemb, FILE *stream)} -\fdecl{size\_t fwrite\_unlocked(const void *ptr, size\_t size, - size\_t nmemb, FILE *stream)} -\fdesc{Leggono o scrivono dati su uno \textit{stream} senza acquisire il lock - implicito sullo stesso.} -} - -{Le funzioni ritornano gli stessi valori delle precedenti \func{fread} e - \func{fwrite}.} -\end{funcproto} - -% TODO: trattare in generale le varie *_unlocked - - La seconda modalità di input/output non formattato è quella a caratteri, in cui si trasferisce un carattere alla volta. Le funzioni per la lettura a caratteri sono tre, \funcd{fgetc}, \funcd{getc} e \funcd{getchar}, ed i @@ -4410,14 +4403,6 @@ quello di \func{fgets} e \func{fputs}, a parte il fatto che tutto (numero di caratteri massimo, terminatore della stringa, \textit{newline}) è espresso in termini di caratteri estesi anziché di normali caratteri ASCII. -Come per l'I/O binario e quello a caratteri, anche per l'I/O di linea la -\acr{glibc} supporta una serie di altre funzioni, estensioni di tutte quelle -illustrate finora (eccetto \func{gets} e \func{puts}), che eseguono -esattamente le stesse operazioni delle loro equivalenti, evitando però il lock -implicito dello \textit{stream} (vedi sez.~\ref{sec:file_stream_thread}). Come -per le altre forma di I/O, dette funzioni hanno lo stesso nome della loro -analoga normale, con l'aggiunta dell'estensione \code{\_unlocked}. - Come abbiamo visto, le funzioni di lettura per l'input/output di linea previste dallo standard ANSI C presentano svariati inconvenienti. Benché \func{fgets} non abbia i gravissimi problemi di \func{gets}, può comunque dare @@ -4455,10 +4440,10 @@ stringa da leggere. Essa prende come primo argomento l'indirizzo del puntatore al buffer su cui si vuole copiare la linea. Quest'ultimo \emph{deve} essere stato allocato in -precedenza con una \func{malloc}, non si può cioè passare come argomento primo +precedenza con una \func{malloc}: non si può cioè passare come argomento primo argomento l'indirizzo di un puntatore ad una variabile locale. Come secondo argomento la funzione vuole l'indirizzo della variabile contenente le -dimensioni del buffer suddetto. +dimensioni del suddetto buffer. Se il buffer di destinazione è sufficientemente ampio la stringa viene scritta subito, altrimenti il buffer viene allargato usando \func{realloc} e la nuova @@ -4660,9 +4645,9 @@ specificati in questo ordine: \label{tab:file_format_flag} \end{table} -Dettagli ulteriori sulle varie opzioni di stampa e su tutte le casistiche -dettagliate dei vari formati possono essere trovati nella pagina di manuale di -\func{printf} e nella documentazione della \acr{glibc}. +Dettagli ulteriori sulle varie opzioni di stampa e su tutte le casistiche dei +vari formati possono essere trovati nella pagina di manuale di \func{printf} e +nella documentazione della \acr{glibc}. \begin{table}[htb] \centering @@ -4718,13 +4703,13 @@ sez.~\ref{sec:proc_variadic}), sono \funcd{vprintf}, \funcd{vfprintf} e valore negativo per un errore.} \end{funcproto} -Con queste funzioni diventa possibile selezionare gli argomenti che si -vogliono passare ad una funzione di stampa, passando direttamente la lista -tramite l'argomento \param{ap}. Per poter far questo ovviamente la lista -variabile degli argomenti dovrà essere opportunamente trattata (l'argomento è -esaminato in sez.~\ref{sec:proc_variadic}), e dopo l'esecuzione della funzione -l'argomento \param{ap} non sarà più utilizzabile (in generale dovrebbe essere -eseguito un \code{va\_end(ap)} ma in Linux questo non è necessario). +Con queste funzioni è possibile selezionare gli argomenti da passare ad una +funzione di stampa indicando direttamente la lista tramite l'argomento +\param{ap}. Per poter far questo ovviamente la lista variabile degli argomenti +dovrà essere trattata come visto in sez.~\ref{sec:proc_variadic}, e dopo +l'esecuzione della funzione l'argomento \param{ap} non sarà più utilizzabile +(in generale dovrebbe essere eseguito un \code{va\_end(ap)} ma in Linux questo +non è necessario). Come per \func{sprintf} anche per \func{vsprintf} esiste una analoga \funcd{vsnprintf} che pone un limite sul numero di caratteri che vengono @@ -4798,8 +4783,8 @@ famiglia \func{scanf}; fra queste le tre più importanti sono \funcd{scanf}, \end{funcproto} Le funzioni eseguono una scansione della rispettiva fonte di input cercando -una corrispondenza di quanto letto con il formato dei dati specificato -da \param{format}, ed effettua le relative conversioni memorizzando il +una corrispondenza di quanto letto con il formato dei dati specificato da +\param{format}, ed effettuano le relative conversioni memorizzando il risultato negli argomenti seguenti, il cui numero è variabile e dipende dal valore di \param{format}. Come per le analoghe funzioni di scrittura esistono le relative \funcm{vscanf}, \funcm{vfscanf} e \funcm{vsscanf} che usano un @@ -5080,12 +5065,6 @@ scelta, si può forzare lo scarico dei dati sul file con la funzione \func{write}.} \end{funcproto} -\noindent anche di questa funzione esiste una analoga \func{fflush\_unlocked} -(accessibile definendo una fra \macro{\_BSD\_SOURCE}, \macro{\_SVID\_SOURCE} o -\macro{\_GNU\_SOURCE}) che non effettua il blocco dello \textit{stream}. - -% TODO aggiungere prototipo \func{fflush\_unlocked}? - Se \param{stream} è \val{NULL} lo scarico dei dati è forzato per tutti gli \textit{stream} aperti. Esistono però circostanze, ad esempio quando si vuole essere sicuri che sia stato eseguito tutto l'output su terminale, in cui serve @@ -5186,15 +5165,14 @@ indolori, e quando il locking dello \textit{stream} non è necessario (come in tutti i programmi che non usano i \textit{thread}), tutta la procedura può comportare dei costi pesanti in termini di prestazioni. -Per questo motivo abbiamo visto come alle usuali funzioni di I/O non -formattato siano associate delle versioni \code{\_unlocked} (alcune previste -dallo stesso standard POSIX, altre aggiunte come estensioni dalla \acr{glibc}) -che possono essere usate quando il locking non serve\footnote{in certi casi - dette funzioni possono essere usate, visto che sono molto più efficienti, - anche in caso di necessità di locking, una volta che questo sia stato - acquisito manualmente.} con prestazioni molto più elevate, dato che spesso -queste versioni (come accade per \func{getc} e \func{putc}) sono realizzate -come macro. +Per questo motivo alle usuali funzioni di I/O non formattato sono associate +delle ulteriori versioni, caratterizzate dall'aggiunta del suffisso +\code{\_unlocked}, che possono essere usate quando il locking non +serve\footnote{in certi casi dette funzioni possono essere usate, visto che + sono molto più efficienti, anche in caso di necessità di locking, una volta + che questo sia stato acquisito manualmente.} con prestazioni molto più +elevate, dato che spesso queste versioni (come accade per \func{getc} e +\func{putc}) sono realizzate come macro. La sostituzione di tutte le funzioni di I/O con le relative versioni \code{\_unlocked} in un programma che non usa i \textit{thread} è però un @@ -5249,6 +5227,18 @@ con uno dei valori \const{FSETLOCKING\_INTERNAL} o % TODO trattare \func{clearerr\_unlocked} +Per tutte le funzioni che abbiamo trattato in +sez.~\ref{sec:files_std_interface} che eseguono I/O sugli \textit{stream} +esiste una versione ``\texttt{\_unlocked}'',\footnote{non ne esistono per + funzioni di informazione come \func{ftell} dato che queste non hanno bisogno + di un blocco, l'elenco completo delle funzioni ``\texttt{\_unlocked}'' + comunque è disponibile nella pagina di manuale delle stesse, accessibile con + \texttt{man unlocked\_stdio}. } ma nello standard POSIX sono previste solo +\funcm{getc\_unlocked}, \funcm{getchar\_unlocked}, \funcm{putc\_unlocked} e +\funcm{putchar\_unlocked}, tutte le altre pur essendo state aggiunte come +estensioni dalla \acr{glibc}, non sono standard, anche se sono presenti anche +su altri sistemi unix; in generale comuqnue l'uso di queste funzioni è +sconsigliato e non le tratteremo esplicitamente. %%% Local Variables: @@ -5310,13 +5300,14 @@ con uno dei valori \const{FSETLOCKING\_INTERNAL} o % LocalWords: wrapper EMPTY olddirfd oldpath newdirfd newpath capability ino % LocalWords: SEARCH flink choot oldirfd NOREPLACE EXCHANGE WHITEOUT union % LocalWords: renamat syscall whiteout overlay filesytem Live nell' sull' -% LocalWords: statbuf statxbuf IFMT nlink atime mtime fexecve argv envp -% LocalWords: blocks STATS btime RESERVED ctime ATTR dev ENOSYS -% LocalWords: timestamp attributes COMPRESSED immutable NODUMP -% LocalWords: dump ENCRYPTED rdev all'I dell'I +% LocalWords: statbuf statxbuf IFMT nlink atime mtime fexecve argv envp GET +% LocalWords: blocks STATS btime RESERVED ctime ATTR dev ENOSYS locks SEALS +% LocalWords: timestamp attributes COMPRESSED immutable NODUMP HINT hints +% LocalWords: dump ENCRYPTED rdev all'I dell'I uint cancellation mmap %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil" %%% End: +% LocalWords: mapping diff --git a/procadv.tex b/procadv.tex index d32fc02..7602fe5 100644 --- a/procadv.tex +++ b/procadv.tex @@ -2194,7 +2194,7 @@ degli altri gruppi, che costituisce poi quello che viene chiamato un % informazioni su setns qui: http://lwn.net/Articles/532748/ % http://lwn.net/Articles/531498/ - +% TODO: se si applicano e ci stanno trattare gli argomenti di ioctl_ns \section{Funzionalità avanzate e specialistiche} \label{sec:process_special} diff --git a/system.tex b/system.tex index bd60d40..84dad32 100644 --- a/system.tex +++ b/system.tex @@ -32,14 +32,14 @@ l'implementazione del kernel e delle librerie, le opzioni di configurazione. Il kernel inoltre mette a disposizione l'accesso ad alcuni parametri che possono modificarne il comportamento. -La definizione di queste caratteristiche ed il tentativo di provvedere dei +La definizione di queste caratteristiche ed il tentativo di fornire dei meccanismi generali che i programmi possono usare per ricavarle è uno degli aspetti più complessi e controversi con cui le diverse standardizzazioni si -sono dovute confrontare, spesso con risultati spesso tutt'altro che chiari. -Daremo comunque una descrizione dei principali metodi previsti dai vari -standard per ricavare sia le caratteristiche specifiche del sistema, che -quelle della gestione dei file e prenderemo in esame le modalità con cui è -possibile intervenire sui parametri del kernel. +sono dovute confrontare, con risultati spesso tutt'altro che chiari. Daremo +comunque una descrizione dei principali metodi previsti dai vari standard per +ricavare sia le caratteristiche specifiche del sistema che quelle della +gestione dei file, e prenderemo in esame le modalità con cui è possibile +intervenire sui parametri del kernel. \subsection{Limiti e caratteristiche del sistema} \label{sec:sys_limits} @@ -58,16 +58,17 @@ sono necessari due tipi diversi di funzionalità: \item la possibilità di determinare limiti ed opzioni durante l'esecuzione. \end{itemize*} -La prima funzionalità si può ottenere includendo gli opportuni header file che -contengono le costanti necessarie definite come macro di preprocessore, per la -seconda invece sono ovviamente necessarie delle funzioni. La situazione è -complicata dal fatto che ci sono molti casi in cui alcuni di questi limiti -sono fissi in un'implementazione mentre possono variare in un altra: tutto -questo crea una ambiguità che non è sempre possibile risolvere in maniera -chiara. In generale quello che succede è che quando i limiti del sistema sono -fissi essi vengono definiti come macro di preprocessore nel file -\headfile{limits.h}, se invece possono variare, il loro valore sarà ottenibile -tramite la funzione \func{sysconf} (che esamineremo a breve). +La prima funzionalità si può ottenere includendo gli opportuni file di +intestazione che contengono le costanti necessarie definite come macro di +preprocessore, per la seconda invece sono ovviamente necessarie delle +funzioni. La situazione è complicata dal fatto che ci sono molti casi in cui +alcuni di questi limiti sono fissi in un'implementazione mentre possono +variare in un altra: tutto questo crea una ambiguità che non è sempre +possibile risolvere in maniera chiara. In generale quello che succede è che +quando i limiti del sistema sono fissi essi vengono definiti come macro di +preprocessore nel file \headfile{limits.h}, se invece possono variare, il loro +valore sarà ottenibile tramite la funzione \func{sysconf} (che esamineremo a +breve). \begin{table}[htb] \centering @@ -151,7 +152,7 @@ sez.~\ref{sec:sys_file_limits}. \begin{table}[htb] \centering \footnotesize - \begin{tabular}[c]{|l|r|p{8cm}|} + \begin{tabular}[c]{|l|r|p{9cm}|} \hline \textbf{Costante}&\textbf{Valore}&\textbf{Significato}\\ \hline @@ -187,7 +188,7 @@ file, riportate in tab.~\ref{tab:sys_file_macro}. \begin{table}[htb] \centering \footnotesize - \begin{tabular}[c]{|l|r|p{8cm}|} + \begin{tabular}[c]{|l|r|p{9cm}|} \hline \textbf{Costante}&\textbf{Valore}&\textbf{Significato}\\ \hline @@ -247,7 +248,7 @@ valori ottenuti da \func{sysconf}. \begin{table}[htb] \centering \footnotesize - \begin{tabular}[c]{|l|p{8cm}|} + \begin{tabular}[c]{|l|p{9cm}|} \hline \textbf{Macro}&\textbf{Significato}\\ \hline @@ -370,12 +371,12 @@ relative spiegazioni, si può trovare nel manuale della \acr{glibc}. \end{table} In generale ogni limite o caratteristica del sistema per cui è definita una -macro, sia dagli standard ANSI C e ISO C90, che da POSIX.1 e POSIX.2, può -essere ottenuto attraverso una chiamata a \func{sysconf}. Il nome della -costante da utilizzare come valore dell'argomento \param{name} si otterrà -aggiungendo \code{\_SC\_} ai nomi delle costanti definite dai primi due -standard (quelle di tab.~\ref{tab:sys_generic_macro}), o sostituendolo a -\code{\_POSIX\_} per le costanti definite dagli altri due standard (quelle di +macro, sia da ANSI C e ISO C90 che da POSIX.1 e POSIX.2, può essere ottenuto +attraverso una chiamata a \func{sysconf}. Il nome della costante da utilizzare +come valore dell'argomento \param{name} si otterrà aggiungendo \code{\_SC\_} +ai nomi delle costanti definite dai primi due standard (quelle di +tab.~\ref{tab:sys_generic_macro}), o sostituendolo a \code{\_POSIX\_} per le +costanti definite dagli altri due standard (quelle di tab.~\ref{tab:sys_posix1_general}). In linea teorica si dovrebbe fare uso di \func{sysconf} solo quando la @@ -516,8 +517,10 @@ BSD4.4 ed introdotta su Linux a partire dal kernel 1.3.57, ma oggi il suo uso esistere, ma non dispone più di una interfaccia nella \acr{glibc} ed il suo utilizzo può essere effettuato solo tramite \func{syscall}, ma di nuovo questo viene sconsigliato in quanto la funzionalità non è più mantenuta e molto -probabilmente sarà rimossa nel prossimo futuro. Per questo motivo eviteremo di -trattarne i particolari. +probabilmente sarà rimossa nel prossimo futuro.\footnote{a partire dal kernel + 2.6.34 la funzione viene inserita nella compilazione del kernel previa + esplicita richiesta, ed il suo uso produce avvertimenti nei log del kernel.} +Per questo motivo eviteremo di trattarne i particolari. Lo scopo di \funcm{sysctl} era quello di fornire ai programmi una modalità per modificare i parametri di sistema. Questi erano organizzati in maniera @@ -531,33 +534,36 @@ moduli che sono stati caricati nel sistema. Inoltre non essendo standardizzati i loro nomi possono variare da una versione di kernel all'altra, alcuni esempi di questi parametri sono: \begin{itemize*} -\item il nome di dominio -\item i parametri del meccanismo di \textit{paging}. -\item il filesystem montato come radice -\item la data di compilazione del kernel -\item i parametri dello stack TCP -\item il numero massimo di file aperti +\item il nome di dominio, +\item i parametri del meccanismo di \textit{paging}, +\item il filesystem montato come radice, +\item la data di compilazione del kernel, +\item i parametri dello stack TCP, +\item il numero massimo di file aperti, +\item il numero massimo di processi, +\item i parametri del \textit{SystemV IPC} (vedi sez.~\ref{sec:ipc_sysv}). \end{itemize*} - - +%\noindent e molti altri che abbiamo già incontrato \index{file!filesystem~\texttt {/proc}!definizione|(} Dato che fin dall'inizio i parametri erano organizzati in una struttura -albero, è parso naturale rimappare questa organizzazione utilizzando il -filesystem \file{/proc}. Questo è un filesystem completamente virtuale, il cui -contenuto è generato direttamente dal kernel, che non fa riferimento a nessun -dispositivo fisico, ma presenta in forma di file e directory i dati di alcune -delle strutture interne del kernel stesso. Il suo utilizzo principale, come -denuncia il nome stesso, è quello di fornire una interfaccia per ottenere i -dati relativi ai processi (venne introdotto a questo scopo su BSD), ma nel -corso del tempo il suo uso è stato ampliato. +albero, è parso naturale riportare questa organizzazione all'interno del +filesystem \file{/proc}. Questo è un filesystem virtuale il cui contenuto è +generato direttamente dal kernel, che non fa riferimento a nessun dispositivo +fisico, ma presenta in forma di file e directory i dati di alcune delle +strutture interne del kernel. Il suo utilizzo principale, come denuncia il +nome stesso, è quello di fornire una interfaccia per ottenere i dati relativi +ai processi (venne introdotto a questo scopo su BSD), ma nel corso del tempo +il suo uso è stato ampliato. All'interno di questo filesystem sono pertanto presenti una serie di file che riflettono il contenuto dei parametri del kernel (molti dei quali accessibili in sola lettura) e in altrettante directory, nominate secondo il relativo \ids{PID}, vengono mantenute le informazioni relative a ciascun processo -attivo nel sistema. +attivo nel sistema (abbiamo già incontrato questa caratteristica in +sez.~\ref{sec:file_openat} per accedere ai filedescriptor del processo +stesso). In particolare l'albero dei valori dei parametri di sistema impostabili con \func{sysctl} viene presentato in forma di una gerarchia di file e directory a @@ -579,8 +585,8 @@ l'accesso, con altrettante corrispondenze ai file presenti in ma vista la assoluta naturalità dell'interfaccia, e la sua maggiore efficienza, nelle versioni più recenti del kernel questa è diventata la modalità canonica per modificare i parametri del kernel, evitando di dover -ricorrere all'uso di una \textit{system call} specifica che pur essendo ancora -presente, prima o poi verrà eliminata. +ricorrere all'uso di una \textit{system call} specifica, che pur essendo +ancora presente prima o poi verrà eliminata. Nonostante la semplificazione nella gestione ottenuta con l'uso di \file{/proc/sys} resta il problema generale di conoscere il significato di @@ -661,8 +667,6 @@ trovano sotto la directory \file{/proc/sys/kernel/}. \index{file!filesystem~\texttt {/proc}!definizione|)} - - \section{La gestione del sistema} \label{sec:sys_management} @@ -681,11 +685,11 @@ Tradizionalmente le informazioni utilizzate nella gestione di utenti e gruppi directory, ecc.) venivano registrate all'interno dei due file di testo \conffiled{/etc/passwd} ed \conffiled{/etc/group}, il cui formato è descritto dalle relative pagine del manuale\footnote{nella quinta sezione, quella dei - file di configurazione (esistono comandi corrispondenti), una trattazione - sistemistica dell'intero argomento coperto in questa sezione si consulti - sez.~4.3 di \cite{AGL}.} e tutte le funzioni che richiedevano l'accesso a -queste informazione andavano a leggere direttamente il contenuto di questi -file. + file di configurazione, dato che esistono comandi corrispondenti; per una + trattazione sistemistica dell'intero argomento coperto in questa sezione si + consulti sez.~4.3 di \cite{AGL}.} e tutte le funzioni che richiedevano +l'accesso a queste informazione andavano a leggere direttamente il contenuto +di questi file. In realtà oltre a questi due file da molto tempo gran parte dei sistemi unix-like usano il cosiddetto sistema delle \textit{shadow password} che @@ -701,26 +705,29 @@ la maggior parte delle distribuzioni di GNU/Linux usa la libreria PAM (sigla che sta per \textit{Pluggable Authentication Method}) che fornisce una interfaccia comune per i processi di autenticazione, svincolando completamente le singole applicazioni dai dettagli del come questa viene eseguita e di dove -vengono mantenuti i dati relativi. Si tratta di un sistema modulare, in cui è -possibile utilizzare anche più meccanismi insieme, diventa così possibile -avere vari sistemi di riconoscimento (biometria, chiavi hardware, ecc.), -diversi formati per le password e diversi supporti per le informazioni. Il -tutto avviene in maniera trasparente per le applicazioni purché per ciascun -meccanismo si disponga della opportuna libreria che implementa l'interfaccia -di PAM. +vengono mantenuti i dati relativi. + +Si tratta di un sistema modulare, in cui è possibile utilizzare anche più +meccanismi insieme, diventa così possibile avere vari sistemi di +riconoscimento (biometria, chiavi hardware, ecc.), diversi formati per le +password e diversi supporti per le informazioni. Il tutto avviene in maniera +trasparente per le applicazioni purché per ciascun meccanismo si disponga +della opportuna libreria che implementa l'interfaccia di PAM. Dall'altra parte, il diffondersi delle reti e la necessità di centralizzare le informazioni degli utenti e dei gruppi per insiemi di macchine e servizi all'interno di una stessa organizzazione, in modo da mantenere coerenti i dati, ha portato anche alla necessità di poter recuperare e memorizzare dette informazioni su supporti diversi dai file citati, introducendo il sistema del -\textit{Name Service Switch} (che tratteremo brevemente in -sez.~\ref{sec:sock_resolver}) dato che la sua applicazione è cruciale nella +\textit{Name Service Switch}, che tratteremo brevemente in +sez.~\ref{sec:sock_resolver} dato che la sua applicazione è cruciale nella procedura di risoluzione di nomi di rete. In questo paragrafo ci limiteremo comunque a trattare le funzioni classiche per la lettura delle informazioni relative a utenti e gruppi tralasciando -completamente quelle relative all'autenticazione. +completamente quelle relative all'autenticazione.\footnote{la cui + programmazione ormai attiene all'uso dell'interfaccia di PAM, che va al di + la dello scopo di questo testo.} % Per questo non tratteremo % affatto l'interfaccia di PAM, ma approfondiremo invece il sistema del % \textit{Name Service Switch}, un meccanismo messo a disposizione dalla @@ -814,7 +821,7 @@ illustrato in sez.~\ref{sec:sys_errno}) per cui se lo si vuole utilizzare è opportuno inizializzarlo a zero prima di invocare le funzioni per essere sicuri di non avere un residuo di errore da una chiamata precedente. Il non aver trovato l'utente richiesto infatti può essere dovuto a diversi motivi (a -partire dal fatto che non esista) per cui si possono ottenere i valori di +partire dal fatto che non esista) per cui si possono ottenere i codici di errore più vari a seconda dei casi. Del tutto analoghe alle precedenti sono le funzioni \funcd{getgrnam} e @@ -970,15 +977,15 @@ informazioni sono descritte in dettaglio nel manuale della \acr{glibc}. Questi file non devono mai essere letti direttamente, ma le informazioni che contengono possono essere ricavate attraverso le opportune funzioni di -libreria. Queste sono analoghe alle precedenti funzioni (vedi -tab.~\ref{tab:sys_passwd_func}) usate per accedere al registro degli utenti, -solo che in questo caso la struttura del registro della \textsl{contabilità} è -molto più complessa, dato che contiene diversi tipi di informazione. +libreria. Queste sono analoghe alle precedenti funzioni usate per accedere al +registro degli utenti (vedi tab.~\ref{tab:sys_passwd_func}), solo che in +questo caso la struttura del registro della \textsl{contabilità} è molto più +complessa, dato che contiene diversi tipi di informazione. Le prime tre funzioni, \funcd{setutent}, \funcd{endutent} e \funcd{utmpname} servono rispettivamente a aprire e a chiudere il file che contiene il registro della \textsl{contabilità} degli, e a specificare su quale file esso viene -mantenuto. I loro prototipi sono: +mantenuto; i loro prototipi sono: \begin{funcproto}{ \fhead{utmp.h} @@ -3270,7 +3277,7 @@ che errori relativi alla stessa linea non vengano ripetuti. % LocalWords: memory mlockall MAP LOCKED shmctl MSGQUEUE attr NICE nice MADV % LocalWords: madvise WILLNEED RTPRIO sched setscheduler setparam scheduling % LocalWords: RTTIME execve kb prlimit pid new old ESRCH EUSERS refresh high -% LocalWords: resolution HRT jiffies strptime +% LocalWords: resolution HRT jiffies strptime pre l'I value argument %%% Local Variables: %%% mode: latex