From: Simone Piccardi Date: Mon, 15 Jun 2015 07:19:00 +0000 (+0000) Subject: Aggiunte in treno X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=265547995607b3ec2c04f9b8b035b416e892920b;p=gapil.git Aggiunte in treno --- diff --git a/fileadv.tex b/fileadv.tex index e531364..ab82f62 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -3850,7 +3850,7 @@ ognuna di esse dovrà essere specificato il tipo di operazione con il campo \begin{basedescript}{\desclabelwidth{2.0cm}} \item[\const{LIO\_READ}] si richiede una operazione di lettura. \item[\const{LIO\_WRITE}] si richiede una operazione di scrittura. -\item[\const{LIO\_NOP}] non si effettua nessuna operazione. +na operazione. \end{basedescript} dove \const{LIO\_NOP} viene usato quando si ha a che fare con un vettore di dimensione fissa, per poter specificare solo alcune operazioni, o quando si @@ -3942,7 +3942,7 @@ ad eseguire la mappatura in memoria di un file, è \funcd{mmap}; il suo prototipo è: \begin{funcproto}{ -\fhead{unistd.h} +%\fhead{unistd.h} \fhead{sys/mman.h} \fdecl{void * mmap(void * start, size\_t length, int prot, int flags, int fd, off\_t offset)} @@ -4019,23 +4019,16 @@ Il valore dell'argomento \param{prot} indica la protezione\footnote{come accennato in sez.~\ref{sec:proc_memory} 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 \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 una \itindex{segment~violation} - \textit{segment violation}, e la relativa emissione del segnale - \signal{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_prot}; il valore specificato deve essere -compatibile con la modalità di accesso con cui si è aperto il file. - -L'argomento \param{flags} specifica infine qual è il tipo di oggetto mappato, -le opzioni relative alle modalità con cui è effettuata la mappatura e alle -modalità con cui le modifiche alla memoria mappata vengono condivise o -mantenute private al processo che le ha effettuate. Deve essere specificato -come maschera binaria ottenuta dall'OR di uno o più dei valori riportati in -tab.~\ref{tab:file_mmap_flag}. - -\begin{table}[htb] + 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 una \textit{segment violation}, e la relativa + emissione del segnale \signal{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_prot}; il valore specificato +deve essere compatibile con la modalità di accesso con cui si è aperto il +file. + +\begin{table}[!htb] \centering \footnotesize \begin{tabular}[c]{|l|p{11cm}|} @@ -4047,13 +4040,15 @@ tab.~\ref{tab:file_mmap_flag}. 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} (dal 2.4.20).\\ + richiesto \const{MAP\_FIXED} (dal kernel 2.4.20).\\ \const{MAP\_ANON} & Sinonimo di \const{MAP\_ANONYMOUS}, deprecato.\\ \const{MAP\_ANONYMOUS} & La mappatura non è associata a nessun file. Gli argomenti \param{fd} e \param{offset} sono - ignorati.\\ + ignorati. L'uso di questo flag con + \const{MAP\_SHARED} è stato implementato in Linux + a partire dai kernel della serie 2.4.x.\\ \const{MAP\_DENYWRITE} & In Linux viene ignorato per evitare - \textit{DoS} \itindex{Denial~of~Service~(DoS)} + \textit{DoS} (veniva usato per segnalare che tentativi di scrittura sul file dovevano fallire con \errcode{ETXTBSY}).\\ @@ -4064,44 +4059,54 @@ tab.~\ref{tab:file_mmap_flag}. \func{mmap} fallisce. Se si imposta questo flag il valore di \param{start} deve essere allineato alle dimensioni di una pagina.\\ - \const{MAP\_GROWSDOWN} & Usato per gli \itindex{stack} \textit{stack}. + \const{MAP\_GROWSDOWN} & Usato per gli \textit{stack}. Indica che la mappatura deve essere effettuata con gli indirizzi crescenti verso il basso.\\ \const{MAP\_HUGETLB} & Esegue la mappatura usando le cosiddette - ``\textit{huge pages}'' (dal 2.6.32).\\ + ``\textit{huge pages}'' (dal kernel 2.6.32).\\ \const{MAP\_LOCKED} & Se impostato impedisce lo \textit{swapping} delle - pagine mappate (dal 2.5.37).\\ + pagine mappate (dal kernel 2.5.37).\\ \const{MAP\_NONBLOCK} & Esegue un \textit{prefaulting} più limitato che - non causa I/O (dal 2.5.46).\\ + non causa I/O (dal kernel 2.5.46).\\ \const{MAP\_NORESERVE} & Si usa con \const{MAP\_PRIVATE}. Non riserva delle pagine di \textit{swap} ad uso del meccanismo - del \textit{copy on write} \itindex{copy~on~write} + del \textit{copy on write} per mantenere le modifiche fatte alla regione mappata, in questo caso dopo una scrittura, se non c'è più memoria disponibile, si ha l'emissione di un \signal{SIGSEGV}.\\ + \const{MAP\_POPULATE} & Esegue il \textit{prefaulting} delle pagine di + memoria necessarie alla mappatura (dal kernel + 2.5.46).\\ \const{MAP\_PRIVATE} & I cambiamenti sulla memoria mappata non vengono riportati sul file. Ne viene fatta una copia privata cui solo il processo chiamante ha - accesso. Le modifiche sono mantenute attraverso - il meccanismo del \textit{copy on write} e - salvate su \textit{swap} in caso di necessità. Non è - specificato se i cambiamenti sul file originale - vengano riportati sulla regione - mappata. Incompatibile con \const{MAP\_SHARED}.\\ - \const{MAP\_POPULATE} & Esegue il \itindex{prefaulting} - \textit{prefaulting} delle pagine di memoria - necessarie alla mappatura (dal 2.5.46).\\ + accesso. Incompatibile con \const{MAP\_SHARED}.\\ \const{MAP\_SHARED} & I cambiamenti sulla memoria mappata vengono riportati sul file e saranno immediatamente visibili agli altri processi che mappano lo stesso - file.\footnotemark Il file su disco però non sarà - aggiornato fino alla chiamata di \func{msync} o - \func{munmap}), e solo allora le modifiche saranno - visibili per l'I/O convenzionale. Incompatibile + file. Incompatibile con \const{MAP\_PRIVATE}.\\ - \const{MAP\_STACK} & da trattare (dal 2.6.27).\\ - \const{MAP\_UNINITIALIZED}& da trattare (dal 2.6.33).\\ + \const{MAP\_STACK} & Al momento è ignorato, è stato fornito (dal kernel + 2.6.27) a supporto della implementazione dei + thread nelle \acr{glibc}, per allocare memoria in + uno spazio utilizzabile come \textit{stack} per le + architetture hardware che richiedono un + trattamento speciale di quest'ultimo.\\ + \const{MAP\_UNINITIALIZED}& Specifico per i sistemi embedded ed + utilizzabile dal kernel 2.6.33 solo se è stata + abilitata in fase di compilazione dello stesso + l'opzione + \texttt{CONFIG\_MMAP\_ALLOW\_UNINITIALIZED}. Se + usato le pagine di memoria usate nella mappatura + anonima non vengono cancellate; questo migliora + le prestazioni sui sistemi con risorse minime, ma + comporta la possibilità di rileggere i dati di + altri processi che han chiuso una mappatura, per + cui viene usato solo quando (come si suppone sia + per i sistemi embedded) si ha il completo + controllo dell'uso della memoria da parte degli + utenti.\\ % \const{MAP\_DONTEXPAND}& Non consente una successiva espansione dell'area % mappata con \func{mremap}, proposto ma pare non % implementato.\\ @@ -4111,31 +4116,59 @@ tab.~\ref{tab:file_mmap_flag}. \label{tab:file_mmap_flag} \end{table} -\footnotetext{l'uso di questo flag con \const{MAP\_SHARED} è stato - implementato in Linux a partire dai kernel della serie 2.4.x; esso consente - di creare segmenti di memoria condivisa e torneremo sul suo utilizzo in - sez.~\ref{sec:ipc_mmap_anonymous}.} - % TODO trattare MAP_HUGETLB introdotto con il kernel 2.6.32, e modifiche % introdotte con il 3.8 per le dimensioni variabili delle huge pages +L'argomento \param{flags} specifica infine qual è il tipo di oggetto mappato, +le opzioni relative alle modalità con cui è effettuata la mappatura e alle +modalità con cui le modifiche alla memoria mappata vengono condivise o +mantenute private al processo che le ha effettuate. Deve essere specificato +come maschera binaria ottenuta dall'OR di uno o più dei valori riportati in +tab.~\ref{tab:file_mmap_flag}. Fra questi comunque deve sempre essere +specificato o \const{MAP\_PRIVATE} o \const{MAP\_SHARED} per indicare la +modalità con cui viene effettuata la mappatura. + +Esistono infatti due modalità alternative di eseguire la mappatura di un file; +la più comune è \const{MAP\_SHARED} in cui la memoria è condivisa e le +modifiche effettuate su di essa sono visibili a tutti i processi che hanno +mappato lo stesso file. In questo caso le modifiche vengono anche riportate su +disco, anche se questo può non essere immediato a causa della bufferizzazione: +si potrà essere sicuri dell'aggiornamento solo in seguito alla chiamata di +\func{msync} o \func{munmap}, e solo allora le modifiche saranno visibili sul +file con l'I/O convenzionale. + +Con \const{MAP\_PRIVATE} invece viene creata una copia privata del file, +questo non viene mai modificato e solo il processo chiamante ha accesso alla +mappatura. Le modifiche eseguite dal processo sulla mappatura vengono +effettuate utilizzando il meccanismo del \textit{copy on write}, mentenute in +memoria e salvate su \textit{swap} in caso di necessità. Non è specificato se +i cambiamenti sul file originale vengano riportati sulla regione mappata. + +Gli altri valori di \func{flag} modificano le caratteristiche della +mappatura. Fra questi il più rilevante è probabilmente \const{MAP\_ANONYMOUS} +che consente di creare segmenti di memoria condivisa fra processi diversi +senza appoggiarsi a nessun file (torneremo sul suo utilizzo in +sez.~\ref{sec:ipc_mmap_anonymous}). In tal caso gli argomenti \param{fd} +e \param{offset} vangono ignorati, anche se alcune implementazioni richiedono +che invece \param{fd} sia $-1$, convenzione che è opportuno seguire se si ha a +cuore la portabilità dei programmi. + Gli effetti dell'accesso ad una zona di memoria mappata su file possono essere piuttosto complessi, essi si possono comprendere solo tenendo presente che -tutto quanto è comunque basato sul meccanismo della \index{memoria~virtuale} -memoria virtuale. Questo comporta allora una serie di conseguenze. La più -ovvia è che se si cerca di scrivere su una zona mappata in sola lettura si -avrà l'emissione di un segnale di violazione di accesso (\signal{SIGSEGV}), -dato che i permessi sul segmento di memoria relativo non consentono questo -tipo di accesso. +tutto quanto è comunque basato sul meccanismo della memoria virtuale. Questo +comporta allora una serie di conseguenze. La più ovvia è che se si cerca di +scrivere su una zona mappata in sola lettura si avrà l'emissione di un segnale +di violazione di accesso (\signal{SIGSEGV}), dato che i permessi sul segmento +di memoria relativo non consentono questo tipo di accesso. È 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; questo però non tiene conto del fatto che, essendo basata sul meccanismo della -\index{paginazione} 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. +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. \begin{figure}[!htb] \centering @@ -4147,7 +4180,7 @@ 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 +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{length}, senza ottenere un \signal{SIGSEGV} poiché essa è presente nello spazio di indirizzi @@ -4206,50 +4239,54 @@ consentita la scrittura sul file (cioè per un file mappato con o in corrispondenza di una eventuale \func{msync}. Dato per i file mappati in memoria le operazioni di I/O sono gestite -direttamente dalla \index{memoria~virtuale} memoria virtuale, occorre essere -consapevoli delle interazioni che possono esserci con operazioni effettuate -con l'interfaccia dei file di sez.~\ref{sec:file_unix_interface}. Il problema -è che una volta che si è mappato un file, le operazioni di lettura e scrittura -saranno eseguite sulla memoria, e riportate su disco in maniera autonoma dal -sistema della memoria virtuale. - -Pertanto se si modifica un file con l'interfaccia standard queste modifiche +direttamente dalla memoria virtuale, occorre essere consapevoli delle +interazioni che possono esserci con operazioni effettuate con l'interfaccia +dei file ordinaria illustrata in sez.~\ref{sec:file_unix_interface}. Il +problema è che una volta che si è mappato un file, le operazioni di lettura e +scrittura saranno eseguite sulla memoria, e riportate su disco in maniera +autonoma dal sistema della memoria virtuale. + +Pertanto se si modifica un file con l'interfaccia ordinaria queste modifiche potranno essere visibili o meno a seconda del momento in cui la memoria virtuale trasporterà dal disco in memoria quella sezione del file, perciò è del tutto imprevedibile il risultato della modifica di un file nei confronti del contenuto della memoria su cui è mappato. -Per questo, è sempre sconsigliabile eseguire scritture su file attraverso -l'interfaccia standard quando lo si è mappato in memoria, è invece possibile -usare l'interfaccia standard per leggere un file mappato in memoria, purché si -abbia una certa cura; infatti l'interfaccia dell'I/O mappato in memoria mette -a disposizione la funzione \funcd{msync} per sincronizzare il contenuto della -memoria mappata con il file su disco; il suo prototipo è: -\begin{functions} - \headdecl{unistd.h} - \headdecl{sys/mman.h} +Per questo è sempre sconsigliabile eseguire scritture su un file attraverso +l'interfaccia ordinaria quando lo si è mappato in memoria, è invece possibile +usare l'interfaccia ordinaria per leggere un file mappato in memoria, purché +si abbia una certa cura; infatti l'interfaccia dell'I/O mappato in memoria +mette a disposizione la funzione \funcd{msync} per sincronizzare il contenuto +della memoria mappata con il file su disco; il suo prototipo è: - \funcdecl{int msync(const void *start, size\_t length, int flags)} - - Sincronizza i contenuti di una sezione di un file mappato in memoria. - - \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} +\begin{funcproto}{ +%\fhead{unistd.h} +\fhead{sys/mman.h} +\fdecl{int msync(const void *start, size\_t length, int flags)} +\fdesc{Sincronizza i contenuti di una sezione di un file mappato in memoria.} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EBUSY}] si è indicato \const{MS\_INVALIDATE} ma + nell'intervallo di memoria specificato è presente un \textit{memory lock}. + \item[\errcode{EFAULT}] l'intervallo indicato, o parte di esso, non + risulta mappato (prima del kernel 2.4.19). \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} - } -\end{functions} + \item[\errcode{ENOMEM}] l'intervallo indicato, o parte di esso, non + risulta mappato (dal kernel 2.4.19). + \end{errlist} +} +\end{funcproto} La funzione esegue la sincronizzazione di quanto scritto nella sezione di memoria indicata da \param{start} e \param{offset}, scrivendo le modifiche sul file (qualora questo non sia già stato fatto). Provvede anche ad aggiornare i relativi tempi di modifica. In questo modo si è sicuri che dopo l'esecuzione -di \func{msync} le funzioni dell'interfaccia standard troveranno un contenuto +di \func{msync} le funzioni dell'interfaccia ordinaria troveranno un contenuto del file aggiornato. @@ -4280,28 +4317,28 @@ dei valori riportati in tab.~\ref{tab:file_mmap_msync}, di questi però infatti la funzione si limita ad inoltrare la richiesta di sincronizzazione al meccanismo della memoria virtuale, ritornando subito, mentre con il secondo attende che la sincronizzazione sia stata effettivamente eseguita. Il terzo -flag fa sì che vengano invalidate, per tutte le mappature dello stesso file, +valore fa sì che vengano invalidate, per tutte le mappature dello stesso file, le pagine di cui si è richiesta la sincronizzazione, così che esse possano essere immediatamente aggiornate con i nuovi valori. Una volta che si sono completate le operazioni di I/O si può eliminare la mappatura della memoria usando la funzione \funcd{munmap}, il suo prototipo è: -\begin{functions} - \headdecl{unistd.h} - \headdecl{sys/mman.h} - \funcdecl{int munmap(void *start, size\_t length)} - - Rilascia la mappatura sulla sezione di memoria specificata. +\begin{funcproto}{ +%\fhead{unistd.h} +\fhead{sys/mman.h} +\fdecl{int munmap(void *start, size\_t length)} +\fdesc{Rilascia la mappatura sulla sezione di memoria specificata.} +} - \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} +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: + \begin{errlist} \item[\errcode{EINVAL}] l'intervallo specificato non ricade in una zona precedentemente mappata. - \end{errlist} - } -\end{functions} + \end{errlist} +} +\end{funcproto} La funzione cancella la mappatura per l'intervallo specificato con \param{start} e \param{length}; ogni successivo accesso a tale regione causerÃ