\item \errcode{EMULTIHOP} \textit{Multihop attempted}.
\item \errcode{ENODATA} \textit{No data available}.
\item \errcode{ENOLINK} \textit{Link has been severed}.
-\item \errcode{ENOMSG} \textit{No message of desired type}.
+\item \errcode{ENOMSG} \textit{No message of desired type}. Indica che una
+ coda di messaggi del \textit{SysV IPC} non è presente nessun messaggio del
+ tipo desiderato.
\item \errcode{ENOSR} \textit{Out of streams resources}.
\item \errcode{ENOSTR} \textit{Device not a stream}.
-\item \errcode{EOVERFLOW} \textit{Value too large for defined data type}.
-\item \errcode{EPROTO} \textit{Protocol error}.
+\item \errcode{EOVERFLOW} \textit{Value too large for defined data type}. Si è
+ chiesta la lettura di un dato dal \textit{SysV IPC} con \const{IPC\_STAT} ma
+ il valore eccede la dimensione usata nel buffer di lettura.
+\item \errcode{EPROTO} \textit{Protocol error}. C'è stato un errore nel
+ protocollo di rete usato dal socket.
\item \errcode{ETIME} \textit{Timer expired}.
\end{description}
-\section{Errori del kernel}
-\label{sec:err_kernel_err}
+% \section{Errori del kernel}
+% \label{sec:err_kernel_err}
-In questa sezione sono raccolti i codici di errore interni del kernel. Non
-sono usati dalle funzioni di libreria, ma vengono riportati da alcune system
-call (TODO verificare i dettagli, eventualmente cassare).
+% In questa sezione sono raccolti i codici di errore interni del kernel. Non
+% sono usati dalle funzioni di libreria, ma vengono riportati da alcune system
+% call (TODO verificare i dettagli, eventualmente cassare).
-\begin{description}
-\item \errcode{ERESTART} \textit{Interrupted system call should be restarted}.
-\item \errcode{ECHRNG} \textit{Channel number out of range}.
-\item \errcode{EL2NSYNC} \textit{Level 2 not synchronized}.
-\item \errcode{EL3HLT} \textit{Level 3 halted}.
-\item \errcode{EL3RST} \textit{Level 3 reset}.
-\item \errcode{ELNRNG} \textit{Link number out of range}.
-\item \errcode{EUNATCH} \textit{Protocol driver not attached}.
-\item \errcode{ENOCSI} \textit{No CSI structure available}.
-\item \errcode{EL2HLT} \textit{Level 2 halted}.
-\item \errcode{EBADE} \textit{Invalid exchange}.
-\item \errcode{EBADR} \textit{Invalid request descriptor}.
-\item \errcode{EXFULL} \textit{Exchange full}.
-\item \errcode{ENOANO} \textit{No anode}.
-\item \errcode{EBADRQC} \textit{Invalid request code}.
-\item \errcode{EBADSLT} \textit{Invalid slot}.
-\item \errcode{EDEADLOCK} Identico a \errcode{EDEADLK}.
-\item \errcode{EBFONT} \textit{Bad font file format}.
-\item \errcode{ENONET} \textit{Machine is not on the network}.
-\item \errcode{ENOPKG} \textit{Package not installed}.
-\item \errcode{EADV} \textit{Advertise error}.
-\item \errcode{ESRMNT} \textit{Srmount error}.
-\item \errcode{ECOMM} \textit{Communication error on send}.
-\item \errcode{EDOTDOT} \textit{RFS specific error}.
-\item \errcode{ENOTUNIQ} \textit{Name not unique on network}.
-\item \errcode{EBADFD} \textit{File descriptor in bad state}.
-\item \errcode{EREMCHG} \textit{Remote address changed}.
-\item \errcode{ELIBACC} \textit{Can not access a needed shared library}.
-\item \errcode{ELIBBAD} \textit{Accessing a corrupted shared library}.
-\item \errcode{ELIBSCN} \textit{.lib section in a.out corrupted}.
-\item \errcode{ELIBMAX} \textit{Attempting to link in too many shared
- libraries}.
-\item \errcode{ELIBEXEC} \textit{Cannot exec a shared library directly}.
-\item \errcode{ESTRPIPE} \textit{Streams pipe error}.
-\item \errcode{EUCLEAN} \textit{Structure needs cleaning}.
-\item \errcode{ENAVAIL} \textit{No XENIX semaphores available}.
-\item \errcode{EISNAM} \textit{Is a named type file}.
-\item \errcode{EREMOTEIO} \textit{Remote I/O error}.
-\item \errcode{ENOMEDIUM} \textit{No medium found}.
-\item \errcode{EMEDIUMTYPE} \textit{Wrong medium type}.
-\end{description}
+% \begin{description}
+% \item \errcode{ERESTART} \textit{Interrupted system call should be restarted}.
+% \item \errcode{ECHRNG} \textit{Channel number out of range}.
+% \item \errcode{EL2NSYNC} \textit{Level 2 not synchronized}.
+% \item \errcode{EL3HLT} \textit{Level 3 halted}.
+% \item \errcode{EL3RST} \textit{Level 3 reset}.
+% \item \errcode{ELNRNG} \textit{Link number out of range}.
+% \item \errcode{EUNATCH} \textit{Protocol driver not attached}.
+% \item \errcode{ENOCSI} \textit{No CSI structure available}.
+% \item \errcode{EL2HLT} \textit{Level 2 halted}.
+% \item \errcode{EBADE} \textit{Invalid exchange}.
+% \item \errcode{EBADR} \textit{Invalid request descriptor}.
+% \item \errcode{EXFULL} \textit{Exchange full}.
+% \item \errcode{ENOANO} \textit{No anode}.
+% \item \errcode{EBADRQC} \textit{Invalid request code}.
+% \item \errcode{EBADSLT} \textit{Invalid slot}.
+% \item \errcode{EDEADLOCK} Identico a \errcode{EDEADLK}.
+% \item \errcode{EBFONT} \textit{Bad font file format}.
+% \item \errcode{ENONET} \textit{Machine is not on the network}.
+% \item \errcode{ENOPKG} \textit{Package not installed}.
+% \item \errcode{EADV} \textit{Advertise error}.
+% \item \errcode{ESRMNT} \textit{Srmount error}.
+% \item \errcode{ECOMM} \textit{Communication error on send}.
+% \item \errcode{EDOTDOT} \textit{RFS specific error}.
+% \item \errcode{ENOTUNIQ} \textit{Name not unique on network}.
+% \item \errcode{EBADFD} \textit{File descriptor in bad state}.
+% \item \errcode{EREMCHG} \textit{Remote address changed}.
+% \item \errcode{ELIBACC} \textit{Can not access a needed shared library}.
+% \item \errcode{ELIBBAD} \textit{Accessing a corrupted shared library}.
+% \item \errcode{ELIBSCN} \textit{.lib section in a.out corrupted}.
+% \item \errcode{ELIBMAX} \textit{Attempting to link in too many shared
+% libraries}.
+% \item \errcode{ELIBEXEC} \textit{Cannot exec a shared library directly}.
+% \item \errcode{ESTRPIPE} \textit{Streams pipe error}.
+% \item \errcode{EUCLEAN} \textit{Structure needs cleaning}.
+% \item \errcode{ENAVAIL} \textit{No XENIX semaphores available}.
+% \item \errcode{EISNAM} \textit{Is a named type file}.
+% \item \errcode{EREMOTEIO} \textit{Remote I/O error}.
+% \item \errcode{ENOMEDIUM} \textit{No medium found}.
+% \item \errcode{EMEDIUMTYPE} \textit{Wrong medium type}.
+% \end{description}
\begin{figure}[htb]
\centering
- \includegraphics[width=14cm]{img/mmap_layout}
+ \includegraphics[width=13cm]{img/mmap_layout}
\caption{Disposizione della memoria di un processo quando si esegue la
mappatura in memoria di un file.}
\label{fig:file_mmap_layout}
Il valore dell'argomento \param{prot} indica la protezione\footnote{in Linux
la memoria reale è divisa in pagine: ogni processo vede la sua memoria
attraverso uno o più segmenti lineari di memoria virtuale. Per ciascuno di
- questi segmenti il kernel mantiene nella \textit{page table} la mappatura
- sulle pagine di memoria reale, ed le modalità di accesso (lettura,
- esecuzione, scrittura); una loro violazione causa quella che si chiama una
- \textit{segment violation}, e la relativa emissione del segnale
- \const{SIGSEGV}.} da applicare al segmento di memoria e deve essere
+ questi segmenti il kernel mantiene nella \itindex{page~table}\textit{page
+ table} la mappatura sulle pagine di memoria reale, ed le modalità di
+ accesso (lettura, esecuzione, scrittura); una loro violazione causa quella
+ che si chiama una \textit{segment violation}, e la relativa emissione del
+ segnale \const{SIGSEGV}.} da applicare al segmento di memoria e deve essere
specificato come maschera binaria ottenuta dall'OR di uno o più dei valori
riportati in tab.~\ref{tab:file_mmap_flag}; il valore specificato deve essere
compatibile con la modalità di accesso con cui si è aperto il file.
memoria disponibile, si ha l'emissione di
un \const{SIGSEGV}. \\
\const{MAP\_LOCKED} & Se impostato impedisce lo swapping delle pagine
- mappate. \\
+ mappate.\\
\const{MAP\_GROWSDOWN} & Usato per gli stack. Indica
che la mappatura deve essere effettuata con gli
indirizzi crescenti verso il basso.\\
argomenti \param{fd} e \param{offset} sono
ignorati.\footnotemark\\
\const{MAP\_ANON} & Sinonimo di \const{MAP\_ANONYMOUS}, deprecato.\\
- \const{MAP\_FILE} & Valore di compatibilità, deprecato.\\
+ \const{MAP\_FILE} & Valore di compatibilità, ignorato.\\
+ \const{MAP\_32BIT} & Esegue la mappatura sui primi 2GiB dello spazio
+ degli indirizzi, viene supportato solo sulle
+ piattaforme \texttt{x86-64} per compatibilità con
+ le applicazioni a 32 bit. Viene ignorato se si è
+ richiesto \const{MAP\_FIXED}.\\
+ \const{MAP\_POPULATE} & Esegue il \itindex{prefaulting}
+ \textit{prefaulting} delle pagine di memoria
+ necessarie alla mappatura. \\
+ \const{MAP\_NONBLOCK} & Esegue un \textit{prefaulting} più limitato che
+ non causa I/O.\footnotemark \\
+% \const{MAP\_DONTEXPAND}& Non consente una successiva espansione dell'area
+% mappata con \func{mremap}, proposto ma pare non
+% implementato.\\
\hline
\end{tabular}
\caption{Valori possibili dell'argomento \param{flag} di \func{mmap}.}
\label{tab:file_mmap_flag}
\end{table}
-\footnotetext{Dato che tutti faranno riferimento alle stesse pagine di
- memoria.}
-\footnotetext{L'uso di questo flag con \const{MAP\_SHARED} è
- stato implementato in Linux a partire dai kernel della serie 2.4.x.}
Gli effetti dell'accesso ad una zona di memoria mappata su file possono essere
piuttosto complessi, essi si possono comprendere solo tenendo presente che
(\const{SIGSEGV}), dato che i permessi sul segmento di memoria relativo non
consentono questo tipo di accesso.
-\begin{figure}[!htb]
- \centering
- \includegraphics[width=10cm]{img/mmap_boundary}
- \caption{Schema della mappatura in memoria di una sezione di file di
- dimensioni non corrispondenti al bordo di una pagina.}
- \label{fig:file_mmap_boundary}
-\end{figure}
-
È invece assai diversa la questione relativa agli accessi al di fuori della
regione di cui si è richiesta la mappatura. A prima vista infatti si potrebbe
ritenere che anch'essi debbano generare un segnale di violazione di accesso;
paginazione\index{paginazione}, la mappatura in memoria non può che essere
eseguita su un segmento di dimensioni rigorosamente multiple di quelle di una
pagina, ed in generale queste potranno non corrispondere alle dimensioni
-effettive del file o della sezione che si vuole mappare. Il caso più comune è
-quello illustrato in fig.~\ref{fig:file_mmap_boundary}, in cui la sezione di
-file non rientra nei confini di una pagina: in tal caso verrà il file sarà
-mappato su un segmento di memoria che si estende fino al bordo della pagina
-successiva.
+effettive del file o della sezione che si vuole mappare.
+
+\footnotetext[20]{Dato che tutti faranno riferimento alle stesse pagine di
+ memoria.}
+\footnotetext[21]{L'uso di questo flag con \const{MAP\_SHARED} è
+ stato implementato in Linux a partire dai kernel della serie 2.4.x.}
+
+\footnotetext{questo flag ed il precedente \const{MAP\_POPULATE} sono stati
+ introdotti nel kernel 2.5.46 insieme alla mappatura non lineare di cui
+ parleremo più avanti.}
+
+\begin{figure}[!htb]
+ \centering
+ \includegraphics[width=10cm]{img/mmap_boundary}
+ \caption{Schema della mappatura in memoria di una sezione di file di
+ dimensioni non corrispondenti al bordo di una pagina.}
+ \label{fig:file_mmap_boundary}
+\end{figure}
+
+
+Il caso più comune è quello illustrato in fig.~\ref{fig:file_mmap_boundary},
+in cui la sezione di file non rientra nei confini di una pagina: in tal caso
+verrà il file sarà mappato su un segmento di memoria che si estende fino al
+bordo della pagina successiva.
In questo caso è possibile accedere a quella zona di memoria che eccede le
dimensioni specificate da \param{lenght}, senza ottenere un \const{SIGSEGV}
file è stato troncato, dopo che è stato mappato, ad una dimensione inferiore a
quella della mappatura in memoria.
-\begin{figure}[htb]
- \centering
- \includegraphics[width=10cm]{img/mmap_exceed}
- \caption{Schema della mappatura in memoria di file di dimensioni inferiori
- alla lunghezza richiesta.}
- \label{fig:file_mmap_exceed}
-\end{figure}
-
In questa situazione, per la sezione di pagina parzialmente coperta dal
contenuto del file, vale esattamente quanto visto in precedenza; invece per la
parte che eccede, fino alle dimensioni date da \param{length}, l'accesso non
di dispositivi (un esempio è l'interfaccia al ponte PCI-VME del chip Universe)
che sono utilizzabili solo con questa interfaccia.
+\begin{figure}[htb]
+ \centering
+ \includegraphics[width=10cm]{img/mmap_exceed}
+ \caption{Schema della mappatura in memoria di file di dimensioni inferiori
+ alla lunghezza richiesta.}
+ \label{fig:file_mmap_exceed}
+\end{figure}
+
Dato che passando attraverso una \func{fork} lo spazio di indirizzi viene
copiato integralmente, i file mappati in memoria verranno ereditati in maniera
trasparente dal processo figlio, mantenendo gli stessi attributi avuti nel
\bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
errore nel qual caso \var{errno} assumerà uno dei valori:
\begin{errlist}
- \item[\errcode{EINVAL}] O \param{start} non è multiplo di \const{PAGESIZE},
- o si è specificato un valore non valido per \param{flags}.
+ \item[\errcode{EINVAL}] O \param{start} non è multiplo di
+ \const{PAGE\_SIZE}, o si è specificato un valore non valido per
+ \param{flags}.
\item[\errcode{EFAULT}] L'intervallo specificato non ricade in una zona
precedentemente mappata.
\end{errlist}
Alla conclusione del processo, ogni pagina mappata verrà automaticamente
rilasciata, mentre la chiusura del file descriptor usato per effettuare la
mappatura in memoria non ha alcun effetto sulla stessa.
+
+Infine Linux supporta alcune operazioni specifiche non disponibili su altri
+kernel unix-like. La prima di queste operazioni è la possibilità di modificare
+una mappatura precedente, ad esempio per espanderla o restringerla. Questo è
+realizzato dalla funzione \funcd{mremap}, il cui prototipo è:
+\begin{functions}
+ \headdecl{unistd.h}
+ \headdecl{sys/mman.h}
+
+ \funcdecl{void * mremap(void *old\_address, size\_t old\_size , size\_t
+ new\_size, unsigned long flags);}
+
+ Restringe o allarga una mappatura in memoria di un file.
+
+ \bodydesc{La funzione restituisce l'indirizzo alla nuova area di memoria in
+ caso di successo od il valore \const{MAP\_FAILED} (pari a \texttt{(void *)
+ -1}) in caso di errore, nel qual caso \var{errno} assumerà uno dei
+ valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] Uno dei puntatori non è validi, in genere si è
+ usato un valore di \param{old\_address} non allineato ad una pagina di
+ memoria.
+ \item[\errcode{EFAULT}] Ci sono degli indirizzi non validi nell'intervallo
+ di memoria specificato dagli argomenti \param{old\_address} e
+ \param{old\_size}, o ci sono altre mappatura di un tipo non
+ corrispondente a quella richiesta.
+ \item[\errcode{ENOMEM}] Non c'è memoria sufficiente oppure l'area di
+ memoria non può essere espansa all'indirizzo virtuale corrente, e non si
+ è specificato \const{MREMAP\_MAYMOVE} nei flag.
+ \item[\errcode{EAGAIN}] Il segmento di memoria scelto è bloccato e non può
+ essere rimappato.
+ \end{errlist}
+ }
+\end{functions}
+
+La funzione richiede come argomenti \param{old\_address} che specifica il
+precedente indirizzo per la mappatura in memoria e \param{old\_size}, che ne
+indica la dimensione, con \param{new\_size} si specifica invece la nuova
+dimensione che si vuole ottenere. Questa funzione usa il meccanismo della
+\index{memoria~virtuale}memoria virtuale per modificare l'associazione fra gli
+indirizzi virtuali del processo e le pagine di memoria, modificando una
+precedente mappatura.
+
+Infine l'argomento \param{flags} è una maschera binaria per i flag che
+controllano il comportamento della funzione. Il solo valore utilizzato è
+\const{MREMAP\_MAYMOVE}\footnote{per poter utilizzare questa costante occorre
+ aver definito \macro{\_GNU\_SOURCE} prima di includere \file{sys/mman.h}.}
+che consente di eseguire l'espansione anche quando non è possibile utilizzare
+il predente indirizzo. Per questo motivo la funzione restituisce sempre
+l'indirizzo della nuova zona di memoria, che, se si è usato questo flag, non è
+detto coincida con \param{old\_address}.
+
+La mappatura in memoria di un file viene normalmente eseguita in maniera
+lineare, cioè parti successive di un file vengono mappate linearmente su
+indirizzi successivi in memoria (la prima pagina di un file viene mappata
+sulla prima pagina di memoria). Esistono però delle applicazioni\footnote{in
+ particolare la tecnica è usata dai database o dai programmi che realizzano
+ macchine virtuali.} in cui è utile poter mappare parti diverse di un file su
+diverse zone di memoria.
+
+Questo è ovviamente sempre possibile eseguendo più volte \func{mmap} per
+ciascuna delle diverse aree, ma questo approccio ha delle conseguenze molto
+pesanti in termini di prestazioni. Si ricordi infatti che il \textit{memory
+ mapping} in memoria funziona facendo ricorso al meccaniso della
+\index{memoria~virtuale} memoria virtuale per trascrivere su un file le
+operazioni effettuate sugli indirizzi di memoria sui cui esso è mappato.
+
+Per questo motivo con il kernel 2.5.46 è stato introdotto ad opera di Ingo
+Molnar un meccanismo che consente la mappatura non lineare, ed i due nuovi
+flag \const{MAP\_POPULATE} e \const{MAP\_NONBLOCK} per \func{mmap}.
+
+
\itindend{memory~mapping}
+
\section{Il file locking}
\label{sec:file_locking}