From: Simone Piccardi Date: Wed, 15 Aug 2018 12:06:05 +0000 (+0200) Subject: Rilettura e correzioni prima parte. X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=b0f9e84fb388f894bf26c87ffa304847bddfa3b0;p=gapil.git Rilettura e correzioni prima parte. --- diff --git a/gapil.tex b/gapil.tex index b444891..cbd8ba2 100644 --- a/gapil.tex +++ b/gapil.tex @@ -182,6 +182,9 @@ hyperfootnotes=false]{hyperref} % less hspace for tables \setlength{\tabcolsep}{0.5em} +% comment following to have reference to incomplete section using \unavref +% command removed +%\def\incomplete{\relax} \part{Programmazione di sistema} \label{part:progr-di-sist} diff --git a/img/struct_sys.dia b/img/struct_sys.dia index 2fe4685..e8f823a 100644 Binary files a/img/struct_sys.dia and b/img/struct_sys.dia differ diff --git a/img/vfs.dia b/img/vfs.dia index 2e8cc8c..3fd5ca1 100644 Binary files a/img/vfs.dia and b/img/vfs.dia differ diff --git a/intro.tex b/intro.tex index b0aaf26..504093d 100644 --- a/intro.tex +++ b/intro.tex @@ -71,7 +71,7 @@ fig.~\ref{fig:intro_sys_struct}. \begin{figure}[htb] \centering - \includegraphics[width=10cm]{img/struct_sys} + \includegraphics[width=11cm]{img/struct_sys} % \begin{tikzpicture} % \filldraw[fill=black!20] (0,0) rectangle (7.5,1); % \draw (3.75,0.5) node {\textsl{System Call Interface}}; @@ -250,34 +250,33 @@ Normalmente ciascuna \textit{system call} fornita dal kernel viene associata ad una funzione con lo stesso nome definita all'interno della libreria fondamentale del sistema, quella che viene chiamata \textsl{Libreria Standard del C} (\textit{C Standard Library}) in ragione del fatto che il primo -kernel Unix e tutti i programmi eseguiti su di esso vennero scritti in C, -usando le librerie di questo linguaggio. In seguito faremo riferimento alle +kernel Unix e tutti i programmi eseguiti su di esso vennero scritti in questo +linguaggio, usando le sue librerie. In seguito faremo riferimento alle funzioni di questa libreria che si interfacciano alle \textit{system call} come ``\textsl{funzioni di sistema}''. -Questa libreria infatti, oltre alle interfacce delle \textit{system call}, +Questa libreria infatti, oltre alle chiamate alle \textit{system call}, contiene anche tutta una serie di ulteriori funzioni di utilità che vengono comunemente usate nella programmazione e sono definite nei vari standard che documentano le interfacce di programmazione di un sistema unix-like. Questo concetto è importante da tener presente perché programmare in Linux significa -anche essere in grado di usare le funzioni fornite dalla \textsl{Libreria - Standard del C}, in quanto né il kernel, né il linguaggio C implementano -direttamente operazioni ordinarie come l'allocazione dinamica della memoria, -l'input/output bufferizzato sui file o la manipolazione delle stringhe, la -matematica in virgola mobile, che sono comunemente usate da qualunque -programma. +anche essere in grado di usare le funzioni fornite dalla libreria Standard del +C, in quanto né il kernel né il linguaggio C implementano direttamente +operazioni ordinarie come l'allocazione dinamica della memoria, l'input/output +bufferizzato sui file, la manipolazione delle stringhe, la matematica in +virgola mobile, che sono comunemente usate da qualunque programma. Tutto ciò mette nuovamente in evidenza il fatto che nella stragrande maggioranza dei casi si dovrebbe usare il nome GNU/Linux in quanto una parte essenziale del sistema, senza la quale niente funzionerebbe, è appunto la \textit{GNU Standard C Library} (a cui faremo da qui in avanti riferimento -come \acr{glibc}), ovvero la Libreria Standard del C realizzata dalla Free -Software Foundation, nella quale sono state implementate tutte le funzioni -essenziali definite negli standard POSIX e ANSI C (e molte altre), che vengono -utilizzate da qualunque programma. +come \acr{glibc}), la libreria standard del C realizzata dalla Free Software +Foundation nella quale sono state implementate tutte le funzioni essenziali +definite negli standard POSIX e ANSI C (e molte altre), che vengono utilizzate +da qualunque programma. Si tenga comunque presente che questo non è sempre vero, dato che esistono -implementazioni alternative della Libreria Standard del C, come la +implementazioni alternative della libreria standard del C, come la \textit{libc5} o la \textit{uClib}, che non derivano dal progetto GNU. La \textit{libc5}, che era usata con le prime versioni del kernel Linux, è oggi ormai completamente soppiantata dalla \acr{glibc}. La \textit{uClib} invece, @@ -286,10 +285,10 @@ dei dispositivi \textit{embedded} per le sue dimensioni estremamente ridotte, e soprattutto per la possibilità di togliere le parti non necessarie. Pertanto costituisce un valido rimpiazzo della \acr{glibc} in tutti quei sistemi specializzati che richiedono una minima occupazione di memoria. Infine per lo -sviluppo del sistema Android è stata realizzata da Google un'altra Libreria -Standard del C, utilizzata principalmente per evitare l'uso della \acr{glibc}. +sviluppo del sistema Android è stata realizzata da Google un'altra libreria +standard del C, utilizzata principalmente per evitare l'uso della \acr{glibc}. -Tradizionalmente le funzioni specifiche della Libreria Standard del C sono +Tradizionalmente le funzioni specifiche della libreria standard del C sono riportate nella terza sezione del \textsl{Manuale di Programmazione di Unix} (cioè accessibili con il comando \cmd{man 3 }) e come accennato non sono direttamente associate ad una \textit{system call} anche se, ad esempio per la @@ -313,12 +312,12 @@ rispetto al modello tradizionale, ma per il momento ignoreremo queste estensioni. Il concetto base è quello di utente (\textit{user}) del sistema, le cui -capacità rispetto a quello che può fare sono sottoposte a ben precisi limiti. -Sono così previsti una serie di meccanismi per identificare i singoli utenti -ed una serie di permessi e protezioni per impedire che utenti diversi possano -danneggiarsi a vicenda o danneggiare il sistema. Questi meccanismi sono -realizzati dal kernel stesso ed attengono alle operazioni più varie, e -torneremo su di essi in dettaglio più avanti. +capacità sono sottoposte a limiti precisi. Sono così previsti una serie di +meccanismi per identificare i singoli utenti ed una serie di permessi e +protezioni per impedire che utenti diversi possano danneggiarsi a vicenda o +danneggiare il sistema. Questi meccanismi sono realizzati dal kernel stesso ed +attengono alle operazioni più varie, e torneremo su di essi in dettaglio più +avanti. Normalmente l'utente è identificato da un nome (il cosiddetto \textit{username}), che ad esempio è quello che viene richiesto all'ingresso @@ -327,14 +326,14 @@ sez.~\ref{sec:sess_login}). Questa procedura si incarica di verificare l'identità dell'utente, in genere attraverso la richiesta di una parola d'ordine (la \textit{password}), anche se sono possibili meccanismi diversi.\footnote{ad esempio usando la libreria PAM (\textit{Pluggable - Autentication Methods}) è possibile astrarre completamente dai meccanismi - di autenticazione e sostituire ad esempio l'uso delle password con - meccanismi di identificazione biometrica, per un approfondimento - dell'argomento si rimanda alla sez.~4.3 di \cite{AGL}.} Eseguita la -procedura di riconoscimento in genere il sistema manda in esecuzione un -programma di interfaccia (che può essere la \textit{shell} su terminale o -un'interfaccia grafica) che mette a disposizione dell'utente un meccanismo con -cui questo può impartire comandi o eseguire altri programmi. + Autentication Methods}) è possibile generalizzare i meccanismi di + autenticazione e sostituire ad esempio l'uso delle password con meccanismi + di identificazione biometrica; per un approfondimento dell'argomento si + rimanda alla sez.~4.3.7 di \cite{AGL}.} Eseguita la procedura di +riconoscimento in genere il sistema manda in esecuzione un programma di +interfaccia (che può essere la \textit{shell} su terminale o un'interfaccia +grafica) che mette a disposizione dell'utente un meccanismo con cui questo può +impartire comandi o eseguire altri programmi. Ogni utente appartiene anche ad almeno un gruppo (il cosiddetto \textit{default group}), ma può essere associato ad altri gruppi (i @@ -373,10 +372,6 @@ disattivati.\footnote{i controlli infatti vengono eseguiti da uno pseudo-codice del tipo: ``\code{if (uid) \{ \textellipsis\ \}}''.} -%Rimosse -% \section{L'architettura della gestione dei file} -% \label{sec:file_arch_func} - \section{L'architettura di file e directory} \label{sec:intro_file_dir} @@ -421,14 +416,12 @@ sarà accessibile nella forma ordinaria di file e directory. \itindbeg{Virtual~File~System~(VFS)} In Linux il concetto di \textit{everything is a file} è stato implementato -attraverso il \textit{Virtual File System} (che da qui in poi abbrevieremo in -VFS) che è uno strato intermedio che il kernel usa per accedere ai più -svariati filesystem mantenendo la stessa interfaccia per i programmi in -\textit{user space}. - -Il VFS fornisce cioè quel livello di astrazione che permette di collegare le -operazioni interne del kernel per la manipolazione sui file con le -\textit{system call} relative alle operazioni di I/O, e gestisce poi +attraverso il cosiddetto \textit{Virtual File System} (da qui in avanti VFS) +che è uno strato intermedio che il kernel usa per accedere ai più svariati +filesystem mantenendo la stessa interfaccia per i programmi in \textit{user + space}. Il VFS fornisce quel livello di astrazione che permette di +collegare le operazioni interne del kernel per la manipolazione sui file con +le \textit{system call} relative alle operazioni di I/O, e gestisce poi l'organizzazione di dette operazioni nei vari modi in cui i diversi filesystem le effettuano, permettendo la coesistenza di filesystem differenti all'interno dello stesso albero delle directory. Approfondiremo il funzionamento di @@ -437,15 +430,15 @@ interfaccia generica fornita dal VFS in sez.~\ref{sec:file_vfs_work}. In sostanza quello che accade è che quando un processo esegue una \textit{system call} che opera su un file, il kernel chiama sempre una funzione implementata nel VFS. La funzione eseguirà le manipolazioni sulle -strutture generiche e utilizzerà poi la chiamata alle opportune funzioni del -filesystem specifico a cui si fa riferimento. Saranno queste a chiamare le -funzioni di più basso livello che eseguono le operazioni di I/O sul -dispositivo fisico, secondo lo schema riportato in +strutture generiche e utilizzerà poi delle chiamate alle opportune funzioni +del filesystem specifico a cui si fa riferimento. Saranno queste infine a +chiamare le funzioni di più basso livello che eseguono le operazioni di I/O +sul dispositivo fisico, secondo lo schema riportato in fig.~\ref{fig:file_VFS_scheme}. \begin{figure}[!htb] \centering - \includegraphics[width=7cm]{img/vfs} + \includegraphics[width=8cm]{img/vfs} \caption{Schema delle operazioni del VFS.} \label{fig:file_VFS_scheme} \end{figure} @@ -470,18 +463,17 @@ Come accennato in sez.~\ref{sec:intro_kern_and_sys}) montare la radice è, insieme al lancio di \cmd{init},\footnote{l'operazione è ovviamente anche preliminare al lancio di \cmd{init}, dato il kernel deve poter accedere al file che contiene detto programma.} l'unica operazione che viene effettuata -direttamente dal kernel in fase di avvio quando, completata la fase di -inizializzazione, esso riceve dal bootloader l'indicazione di quale -dispositivo contiene il filesystem da usare come punto di partenza e questo -viene posto alla radice dell'albero dei file. +direttamente dal kernel in fase di avvio. Il kernel infatti, completata la +fase di inizializzazione, utilizza l'indicazione passatagli dal +\textit{bootloader} su quale sia il dispositivo che contiene il filesystem da +usare come punto di partenza, lo monta come radice dell'albero dei file. Tutti gli ulteriori filesystem che possono essere disponibili su altri -dispositivi dovranno a loro volta essere inseriti nell'albero, montandoli su +dispositivi dovranno a loro volta essere inseriti nell'albero, montandoli in altrettante directory del filesystem radice, su quelli che vengono chiamati -\textit{mount point}. Questo comunque avverrà sempre in un secondo tempo, in -genere a cura dei programmi eseguiti nella procedura di inizializzazione del -sistema, grazie alle funzioni che tratteremo in -sez.~\ref{sec:filesystem_mounting}. +\textit{mount point}. Questo comunque avverrà sempre in un secondo tempo, a +cura dei programmi eseguiti nella procedura di inizializzazione del sistema, +grazie alle funzioni che tratteremo in sez.~\ref{sec:filesystem_mounting}. \subsection{La risoluzione del nome di file e directory} @@ -489,17 +481,17 @@ sez.~\ref{sec:filesystem_mounting}. \itindbeg{pathname} -Come illustrato sez.~\ref{sec:file_arch_overview} una delle caratteristiche -distintive di un sistema unix-like è quella di avere un unico albero dei -file. Un file deve essere identificato dall'utente usando quello che viene -chiamato il suo \textit{pathname},\footnote{il manuale della \acr{glibc} - depreca questa nomenclatura, che genererebbe confusione poiché \textit{path} - indica anche un insieme di directory su cui effettuare una ricerca (come - quello in cui la shell cerca i comandi). Al suo posto viene proposto l'uso - di \textit{filename} e di componente per il nome del file all'interno della - directory. Non seguiremo questa scelta dato che l'uso della parola - \textit{pathname} è ormai così comune che mantenerne l'uso è senz'altro più - chiaro dell'alternativa proposta.} vale a dire tramite il +Come appena illustrato sez.~\ref{sec:file_arch_overview} una delle +caratteristiche distintive di un sistema unix-like è quella di avere un unico +albero dei file. Un file deve essere identificato dall'utente usando quello +che viene chiamato il suo \textit{pathname},\footnote{il manuale della + \acr{glibc} depreca questa nomenclatura, che genererebbe confusione poiché + \textit{path} indica anche un insieme di directory su cui effettuare una + ricerca (come quello in cui la shell cerca i comandi). Al suo posto viene + proposto l'uso di \textit{filename} e di componente per il nome del file + all'interno della directory. Non seguiremo questa scelta dato che l'uso + della parola \textit{pathname} è ormai così comune che mantenerne l'uso è + senz'altro più chiaro dell'alternativa proposta.} vale a dire tramite il ``\textsl{percorso}'' (nome che talvolta viene usato come traduzione di \textit{pathname}) che si deve fare per accedere al file a partire da una certa ``\textit{directory}''. @@ -523,7 +515,7 @@ La convenzione usata nei sistemi unix-like per indicare i \textit{pathname} dei file è quella di usare il carattere ``\texttt{/}'' come separatore fra i nomi che indicano le directory che lo compongono. Dato che la directory radice sta in cima all'albero, essa viene indicata semplicemente con il -\textit{pathname} \file{/}. +\textit{pathname} ``\file{/}''. \itindbeg{pathname~resolution} @@ -604,7 +596,7 @@ Come accennato in sez.~\ref{sec:file_arch_overview} su Linux l'uso del diversi fra loro. Oltre ai normali file di dati abbiamo già accennato ad altri due di questi oggetti, i file di dispositivo e le directory, ma ne esistono altri. In genere quando si parla di tipo di file su Linux si fa riferimento a -questi, di cui si riportato l'elenco completo in +questi diversi tipi, di cui si riportato l'elenco completo in tab.~\ref{tab:file_file_types}. \begin{table}[htb] @@ -631,11 +623,11 @@ tab.~\ref{tab:file_file_types}. \textit{block device}& \textsl{dispositivo a blocchi} & Un file \textsl{speciale} che identifica una periferica ad accesso a blocchi.\\ - \textit{fifo} & ``\textsl{coda}'' + \textit{fifo} & ``\textsl{coda}'' & Un file \textsl{speciale} che identifica una linea di comunicazione unidirezionale (vedi sez.~\ref{sec:ipc_named_pipe}).\\ - \textit{socket} & ``\textsl{presa}'' + \textit{socket} & ``\textsl{presa}'' & Un file \textsl{speciale} che identifica una linea di comunicazione bidirezionale (vedi cap.~\ref{cha:socket_intro}).\\ @@ -646,10 +638,10 @@ tab.~\ref{tab:file_file_types}. \end{table} Si tenga ben presente che questa classificazione non ha nulla a che fare con -una classificazione dei file in base al tipo loro del contenuto, dato che in -tal caso si avrebbe a che fare sempre e solo con dei file di dati. E non ha -niente a che fare neanche con le eventuali diverse modalità con cui si -potrebbe accedere al contenuto dei file di dati. La classificazione di +una classificazione dei file in base al loro contenuto, dato che in tal caso +si avrebbe a che fare sempre e solo con dei file di dati. E non ha niente a +che fare neanche con le eventuali diverse modalità con cui si possa accedere +al contenuto dei file di dati. La classificazione di tab.~\ref{tab:file_file_types} riguarda il tipo di oggetti gestiti dal \textit{Virtual File System}, ed è da notare la presenza dei cosiddetti file ``\textsl{speciali}''. @@ -661,7 +653,7 @@ alcune funzionalità di comunicazione fornite dal kernel. Gli altri sono proprio quei \textsl{file di dispositivo} che costituiscono una interfaccia diretta per leggere e scrivere sui dispositivi fisici. Anche se finora li abbiamo chiamati genericamente così, essi sono tradizionalmente suddivisi in -due grandi categorie, \textsl{a blocchi} e \textsl{a caratteri} a seconda +due grandi categorie, \textsl{a blocchi} e \textsl{a caratteri}, a seconda delle modalità in cui il dispositivo sottostante effettua le operazioni di I/O. @@ -682,8 +674,8 @@ VMS.\footnote{questo vale anche per i dispositivi a blocchi: la strutturazione dell'I/O in blocchi di dimensione fissa avviene solo all'interno del kernel, ed è completamente trasparente all'utente; inoltre talvolta si parla di \textsl{accesso diretto} riferendosi alla capacità, che non ha niente a che - fare con tutto ciò, di effettuare, attraverso degli appositi file di - dispositivo, operazioni di I/O direttamente sui dischi senza passare + fare con tutto ciò, di effettuare attraverso degli appositi file di + dispositivo delle operazioni di I/O direttamente sui dischi senza passare attraverso un filesystem, il cosiddetto \textit{raw access}, introdotto coi kernel della serie 2.4.x ma ormai in sostanziale disuso.} @@ -713,19 +705,20 @@ file) da parte del kernel,\footnote{non è così ad esempio nel filesystem HFS questo tipo avviene sempre in \textit{user-space}. Gli unici file di cui il kernel deve essere in grado di capire il contenuto sono i binari dei programmi, per i quali sono supportati solo alcuni formati, anche se oggi -viene usato quasi esclusivamente l'ELF.\footnote{il nome è l'acronimo di - \textit{Executable and Linkable Format}, un formato per eseguibili binari - molto flessibile ed estendibile definito nel 1995 dal \textit{Tool Interface - Standard} che per le sue caratteristiche di non essere legato a nessun - tipo di processore o architettura è stato adottato da molti sistemi - unix-like e non solo.} +viene usato quasi esclusivamente +\itindex{Executable~and~Linkable~Format~(ELF)} l'ELF.\footnote{il nome è + l'acronimo di \textit{Executable and Linkable Format}, un formato per + eseguibili binari molto flessibile ed estendibile definito nel 1995 dal + \textit{Tool Interface Standard} che per le sue caratteristiche di non + essere legato a nessun tipo di processore o architettura è stato adottato da + molti sistemi unix-like e non solo.} \itindbeg{magic~number} Nonostante l'assenza di supporto da parte del kernel per la classificazione del contenuto dei file di dati, molti programmi adottano comunque delle convenzioni per i nomi dei file, ad esempio il codice C normalmente si mette -in file con l'estensione \file{.c}. Inoltre una tecnica molto usata per +in file con l'estensione ``\file{.c}''. Inoltre una tecnica molto usata per classificare i contenuti da parte dei programmi è quella di utilizzare i primi byte del file per memorizzare un ``\textit{magic number}'' che ne classifichi il contenuto. Il concetto è quello di un numero intero, solitamente fra 2 e 10 @@ -770,13 +763,13 @@ La seconda interfaccia è quella che il manuale della \acr{glibc} chiama dei successo, non esiste, per cui facendo riferimento agli \textit{stream} useremo il significato adottato dal manuale delle \acr{glibc}.} Essa fornisce funzioni più evolute e un accesso bufferizzato, controllato dalla -implementazione fatta nella \acr{glibc}. Questa è l'interfaccia standard -specificata dall'ANSI C e perciò si trova anche su tutti i sistemi non -Unix. Gli \textit{stream} sono oggetti complessi e sono rappresentati da -puntatori ad un opportuna struttura definita dalle librerie del C, ad essi si -accede sempre in maniera indiretta utilizzando il tipo \code{FILE *}. -L'interfaccia è definita nell'\textit{header file} \headfile{stdio.h} e la -tratteremo in dettaglio in sez.~\ref{sec:files_std_interface}. +implementazione fatta nella \acr{glibc}. Questa è l'interfaccia specificata +dallo standard ANSI C e perciò si trova anche su tutti i sistemi non Unix. Gli +\textit{stream} sono oggetti complessi e sono rappresentati da puntatori ad un +opportuna struttura definita dalle librerie del C, a cui si accede sempre in +maniera indiretta utilizzando il tipo \code{FILE *}; l'interfaccia è definita +nell'\textit{header file} \headfile{stdio.h} e la tratteremo in dettaglio in +sez.~\ref{sec:files_std_interface}. Entrambe le interfacce possono essere usate per l'accesso ai file come agli altri oggetti del VFS, ma per poter accedere alle operazioni di controllo @@ -824,13 +817,14 @@ Ovviamente prenderemo in considerazione solo gli standard riguardanti interfacce di programmazione e le altre caratteristiche di un sistema unix-like (alcuni standardizzano pure i comandi base del sistema e la shell) ed in particolare ci concentreremo sul come ed in che modo essi sono -supportati sia per quanto riguarda il kernel che la Libreria Standard del C, +supportati sia per quanto riguarda il kernel che la libreria standard del C, con una particolare attenzione alla \acr{glibc}. \subsection{Lo standard ANSI C} \label{sec:intro_ansiC} +\itindbeg{ANSI~C} Lo standard ANSI C è stato definito nel 1989 dall'\textit{American National Standard Institute} come prima standardizzazione del linguaggio C e per questo si fa riferimento ad esso anche come C89. L'anno successivo è stato @@ -862,6 +856,7 @@ l'opzione \cmd{-ansi}. Questa opzione istruisce il compilatore a definire nei vari \textit{header file} soltanto le funzionalità previste dallo standard ANSI C e a non usare le varie estensioni al linguaggio e al preprocessore da esso supportate. +\itindend{ANSI~C} \subsection{I tipi di dati primitivi} @@ -941,13 +936,14 @@ versione supportata ufficialmente venne rilasciata al pubblico con il nome di Unix System V, e si fa rifermento a questa implementazione con la sigla SysV o SV. -Negli anni successivi l'AT\&T proseguì lo sviluppo rilasciando varie versioni -con aggiunte e integrazioni, ed in particolare la \textit{release 2} nel 1985, -a cui si fa riferimento con SVr2 e la \textit{release 3} nel 1986 (denominata -SVr3). Le interfacce di programmazione di queste due versioni vennero -descritte formalmente in due documenti denominati \textit{System V Interface - Definition} (o SVID), pertanto nel 1995 venne rilasciata la specifica SVID 1 -e nel 1986 la specifica SVID 2. +Negli anni successivi l'AT\&T proseguì lo sviluppo del sistema rilasciando +varie versioni con aggiunte e integrazioni, ed in particolare la +\textit{release 2} nel 1985, a cui si fa riferimento con il nome SVr2 e la +\textit{release 3} nel 1986 (denominata SVr3). Le interfacce di programmazione +di queste due versioni vennero descritte formalmente in due documenti +denominati \itindex{System~V~Interface~Definition~(SVID)} \textit{System V + Interface Definition} (o SVID), pertanto nel 1985 venne rilasciata la +specifica SVID 1 e nel 1986 la specifica SVID 2. Nel 1989 un accordo fra vari venditori (AT\&T, Sun, HP, ed altri) portò ad una versione di System V che provvedeva un'unificazione delle interfacce @@ -962,7 +958,7 @@ Nel 1992 venne rilasciata una seconda versione del sistema, la SVr4.2; l'anno successivo la divisione della AT\&T (già a suo tempo rinominata in Unix System Laboratories) venne acquistata dalla Novell, che poi trasferì il marchio Unix al consorzio X/Open. L'ultima versione di System V fu la SVr4.2MP rilasciata -nel Dicembre 93. Infine nel 1995 è stata rilasciata da SCO, che aveva +nel dicembre 1993. Infine nel 1995 è stata rilasciata da SCO, che aveva acquisito alcuni diritti sul codice di System V, una ulteriore versione delle \textit{System V Interface Description}, che va sotto la denominazione di SVID 4. @@ -1044,9 +1040,7 @@ come di POSIX.1b. Si tenga presente inoltre che nuove specifiche e proposte di standardizzazione si aggiungono continuamente, mentre le versioni precedenti vengono riviste; talvolta poi i riferimenti cambiano nome, per cui anche solo seguire le -denominazioni usate diventa particolarmente faticoso; una pagina dove si -possono recuperare varie (e di norma piuttosto intricate) informazioni è -\url{http://www.pasc.org/standing/sd11.html}. +denominazioni usate diventa particolarmente faticoso. \begin{table}[htb] \footnotesize @@ -1120,13 +1114,14 @@ sotto il nome di POSIX.1-2008 (e SUSv4), con l'incorporazione di alcune nuove interfacce, la obsolescenza di altre, la trasformazione da opzionali a richieste di alcune specifiche di base, oltre alle solite precisazioni ed aggiornamenti. Anche in questo caso è prevista la suddivisione in una -conformità di base, e delle interfacce aggiuntive. +conformità di base, e delle interfacce aggiuntive. Una ulteriore revisione è +stata pubblicata nel 2017 come POSIX.1-2017. Le procedure di aggiornamento dello standard POSIX prevedono comunque un percorso continuo, che prevede la possibilità di introduzione di nuove interfacce e la definizione di precisazioni ed aggiornamenti, per questo in futuro verranno rilasciate nuove versioni. Alla stesura di queste note -l'ultima revisione approvata resta POSIX.1-2008, uno stato della situazione +l'ultima revisione approvata resta POSIX.1-2017, uno stato della situazione corrente del supporto degli standard è allegato alla documentazione della \acr{glibc} e si può ottenere con il comando \texttt{man standards}. @@ -1146,8 +1141,8 @@ contenente una dettagliata standardizzazione dell'interfaccia di sistema di Unix, che venne presa come riferimento da vari produttori. Questo standard, detto anche XPG3 dal nome della suddetta guida, è sempre basato sullo standard POSIX.1, ma prevede una serie di funzionalità aggiuntive fra cui le specifiche -delle API\footnote{le \textit{Application Programmable Interface}, in sostanze - le interfacce di programmazione.} per l'interfaccia grafica (X11). +delle API (sigla che sta per \textit{Application Programmable Interface}, in +italiano interfaccia di programmazione) per l'interfaccia grafica (X11). Nel 1992 lo standard venne rivisto con una nuova versione della guida, la Issue 4, da cui la sigla XPG4, che aggiungeva l'interfaccia XTI (\textit{X @@ -1199,10 +1194,11 @@ dall'aggiornamento vada a definire la quarta versione delle \textit{Single \label{sec:intro_gcc_glibc_std} In Linux, se si usa la \acr{glibc}, la conformità agli standard appena -descritti può essere richiesta sia attraverso l'uso di opportune opzioni del -compilatore (il \texttt{gcc}) che definendo delle specifiche costanti prima -dell'inclusione dei file di intestazione (gli \textit{header file}, vedi -sez.~\ref{sec:proc_syscall}) che definiscono le funzioni di libreria. +descritti può essere richiesta sia attraverso l'uso di alcune opzioni del +compilatore (il \texttt{gcc}) che con la definizione di opportune costanti +prima dell'inclusione dei file di intestazione (gli \textit{header file}, vedi +sez.~\ref{sec:proc_syscall}) in cui le varie funzioni di libreria vengono +definite. Ad esempio se si vuole che i programmi seguano una stretta attinenza allo standard ANSI C si può usare l'opzione \texttt{-ansi} del compilatore, e non @@ -1211,11 +1207,13 @@ standard ISO per il C. Il \texttt{gcc} possiede inoltre una specifica opzione per richiedere la conformità ad uno standard, nella forma \texttt{-std=nome}, dove \texttt{nome} può essere \texttt{c89} per indicare lo standard ANSI C (vedi sez.~\ref{sec:intro_ansiC}) o \texttt{c99} per indicare la conformità -allo standard C99.\footnote{che non è al momento completa, esistono anche le - possibilità di usare i valori \texttt{gnu89}, l'attuale default, che indica - l'uso delle estensioni GNU al C89, riprese poi dal C99, o \texttt{gnu89} che - indica il dialetto GNU del C99, che diventerà il default quando la - conformità a quest'ultimo sarà completa.} +allo standard C99 o \texttt{c11} per indicare la conformità allo standard C11 +(revisione del 2011).\footnote{esistono anche le possibilità di usare i valori + \texttt{gnu89}, che indica l'uso delle estensioni GNU al C89, riprese poi + dal C99, \texttt{gnu99} che indica il dialetto GNU del C99, o \texttt{gnu11} + che indica le estensioni GNU al C11, lo standard adottato di default dipende + dalla versione del \texttt{gcc}, ed all'agosto 2018 con la versione 8.2 è + \texttt{gnu11}.} Per attivare le varie opzioni di controllo di aderenza agli standard è poi possibile definire delle macro di preprocessore che controllano le @@ -1306,7 +1304,7 @@ in essi definite, sono illustrate nel seguente elenco: \item[\macrod{\_DEFAULT\_SOURCE}] questa macro abilita le definizioni considerate il \textit{default}, comprese quelle richieste dallo standard - POSIX.1-2008, ed è sostanzialente equivalente all'insieme di + POSIX.1-2008, ed è sostanzialmente equivalente all'insieme di \macro{\_SVID\_SOURCE}, \macro{\_BSD\_SOURCE} e \macro{\_POSIX\_C\_SOURCE}. Essendo predefinita non è necessario usarla a meno di non aver richiesto delle definizioni più restrittive sia con altre @@ -1439,15 +1437,22 @@ una opportuna macro; queste estensioni sono illustrate nel seguente elenco: le estensioni delle funzioni di creazione, accesso e modifica di file e directory che risolvono i problemi di sicurezza insiti nell'uso di \textit{pathname} relativi con programmi \textit{multi-thread} illustrate in - sez.~\ref{sec:file_openat}. + sez.~\ref{sec:file_openat}. Dalle \acr{glibc} 2.10 questa macro viene + definita implicitamente se si definisce \macro{\_POSIX\_C\_SOURCE} ad un + valore maggiore o uguale di ``\texttt{200809L}''. \item[\macrod{\_REENTRANT}] definendo questa macro, o la equivalente - \macrod{\_THREAD\_SAFE} (fornita per compatibilità) si rendono disponibili le - versioni rientranti (vedi sez.~\ref{sec:proc_reentrant}) di alcune funzioni, - necessarie quando si usano i \textit{thread}. Alcune di queste funzioni - sono anche previste nello standard POSIX.1c, ma ve ne sono altre che sono - disponibili soltanto su alcuni sistemi, o specifiche della \acr{glibc}, e - possono essere utilizzate una volta definita la macro. + \macrod{\_THREAD\_SAFE} (fornita per compatibilità) si rendono disponibili + le versioni rientranti (vedi sez.~\ref{sec:proc_reentrant}) di alcune + funzioni, necessarie quando si usano i \textit{thread}. Alcune di queste + funzioni sono anche previste nello standard POSIX.1c, ma ve ne sono altre + che sono disponibili soltanto su alcuni sistemi, o specifiche della + \acr{glibc}, e possono essere utilizzate una volta definita la macro. Oggi + la macro è obsoleta, già dalle \acr{glibc} 2.3 le librerie erano già + completamente rientranti e dalle \acr{glibc} 2.25 la macro è equivalente ad + definire \macro{\_POSIX\_C\_SOURCE} con un valore di ``\texttt{199606L}'' + mentre se una qualunque delle altre macro che richiede un valore di + conformità più alto è definita, la sua definizione non ha alcun effetto. \item[\macrod{\_FORTIFY\_SOURCE}] definendo questa macro viene abilitata l'inserimento di alcuni controlli per alcune funzioni di allocazione e @@ -1519,7 +1524,7 @@ sempre definite prima dell'inclusione dei file di dichiarazione. % LocalWords: filename fifo name components resolution chroot parent symbolic % LocalWords: char block VMS raw access MacOS LF CR dos HFS Mac attributes % LocalWords: Executable Linkable Format Tool magic descriptor stream locking -% LocalWords: process +% LocalWords: process mount point ELF %%% Local Variables: %%% mode: latex diff --git a/macro.tex b/macro.tex index de2fa06..564d0b2 100644 --- a/macro.tex +++ b/macro.tex @@ -377,6 +377,7 @@ \par } +\newcommand{\unavref}[1]{\ifx\incomplete\undefined\relax\else #1\fi} %%% Local Variables: diff --git a/netlayer.tex b/netlayer.tex index ab007dc..45239b4 100644 --- a/netlayer.tex +++ b/netlayer.tex @@ -645,10 +645,11 @@ separatore; cioè qualcosa del tipo Visto che la notazione resta comunque piuttosto pesante esistono alcune abbreviazioni: si può evitare di scrivere gli zeri iniziali delle singole -cifre, abbreviando l'indirizzo precedente in \texttt{1080:0:0:8:800:ba98:2078:e3e3}; se -poi un intero è zero si può omettere del tutto, così come un insieme di zeri -(ma questo solo una volta per non generare ambiguità) per cui il precedente -indirizzo si può scrivere anche come \texttt{1080::8:800:ba98:2078:e3e3}. +cifre, abbreviando l'indirizzo precedente in +\texttt{1080:0:0:8:800:ba98:2078:e3e3}; se poi un intero è zero si può +omettere del tutto, così come un insieme di zeri (ma questo solo una volta per +non generare ambiguità) per cui il precedente indirizzo si può scrivere anche +come \texttt{1080::8:800:ba98:2078:e3e3}. Infine per scrivere un indirizzo IPv4 all'interno di un indirizzo IPv6 si può usare la vecchia notazione con i punti, per esempio diff --git a/process.tex b/process.tex index 8aba3c2..f14150a 100644 --- a/process.tex +++ b/process.tex @@ -36,7 +36,7 @@ tutte le parti uguali siano condivise), avrà un suo spazio di indirizzi, variabili proprie e sarà eseguito in maniera completamente indipendente da tutti gli altri. Questo non è del tutto vero nel caso di un programma \textit{multi-thread}, ma la gestione dei \textit{thread} in Linux sarà -trattata a parte in cap.~\ref{cha:threads}. +trattata a parte\unavref{in cap.~\ref{cha:threads}}. \subsection{L'avvio e l'esecuzione di un programma} @@ -44,9 +44,9 @@ trattata a parte in cap.~\ref{cha:threads}. \itindbeg{link-loader} \itindbeg{shared~objects} -Quando un programma viene messo in esecuzione cosa che può essere fatta solo -con una funzione della famiglia \func{exec} (vedi sez.~\ref{sec:proc_exec}) il -kernel esegue un opportuno codice di avvio, il cosiddetto +Quando un programma viene messo in esecuzione, cosa che può essere fatta solo +con una funzione della famiglia \func{exec} (vedi sez.~\ref{sec:proc_exec}), +il kernel esegue un opportuno codice di avvio, il cosiddetto \textit{link-loader}, costituito dal programma \cmd{ld-linux.so}. Questo programma è una parte fondamentale del sistema il cui compito è quello della gestione delle cosiddette \textsl{librerie condivise}, quelle che nel mondo @@ -64,15 +64,15 @@ una sola volta per tutti i programmi che lo usano. Questo significa però che normalmente il codice di un programma è incompleto, contenendo solo i riferimenti alle funzioni di libreria che vuole utilizzare e non il relativo codice. Per questo motivo all'avvio del programma è necessario -l'intervento del \textit{link-loader} il cui compito è -caricare in memoria le librerie condivise eventualmente assenti, ed effettuare -poi il collegamento dinamico del codice del programma alle funzioni di -libreria da esso utilizzate prima di metterlo in esecuzione. +l'intervento del \textit{link-loader} il cui compito è caricare in memoria le +librerie condivise eventualmente assenti, ed effettuare poi il collegamento +dinamico del codice del programma alle funzioni di libreria da esso utilizzate +prima di metterlo in esecuzione. Il funzionamento di \cmd{ld-linux.so} è controllato da alcune variabili di -ambiente e dal contenuto del file \conffile{/etc/ld.so.conf}, che consentono -di elencare le directory un cui cercare le librerie e determinare quali -verranno utilizzate. In particolare con la variabile di ambiente +ambiente e dal contenuto del file \conffile{/etc/ld.so.conf} che consentono di +elencare le directory un cui cercare le librerie e determinare quali verranno +utilizzate. In particolare con la variabile di ambiente \envvar{LD\_LIBRARY\_PATH} si possono indicare ulteriori directory rispetto a quelle di sistema in cui inserire versioni personali delle librerie che hanno la precedenza su quelle di sistema, mentre con la variabile di ambiente @@ -292,18 +292,28 @@ una qualunque funzione ordinaria, la situazione è totalmente diversa nell'esecuzione del programma. Una funzione ordinaria infatti viene eseguita, esattamente come il codice che si è scritto nel corpo del programma, in \textit{user space}. Quando invece si esegue una \textit{system call} -l'esecuzione ordinaria del programma viene interrotta, i dati forniti (come -argomenti della chiamata) vengono trasferiti al kernel che esegue il codice -della \textit{system call} (che è codice del kernel) in \textit{kernel space}. +l'esecuzione ordinaria del programma viene interrotta con quello che viene +usualmente chiamato un \itindex{context~switch} \textit{context + switch};\footnote{in realtà si parla più comunemente di \textit{context + switch} quando l'esecuzione di un processo viene interrotta dal kernel + (tramite lo \textit{scheduler}) per metterne in esecuzione un altro, ma il + concetto generale resta lo stesso: l'esecuzione del proprio codice in + \textit{user space} viene interrotta e lo stato del processo deve essere + salvato per poterne riprendere l'esecuzione in un secondo tempo.} il +contesto di esecuzione del processo viene salvato in modo da poterne +riprendere in seguito l'esecuzione ed i dati forniti (come argomenti della +chiamata) vengono trasferiti al kernel che esegue il codice della +\textit{system call} (che è codice del kernel) in \textit{kernel space}; al +completamento della \textit{system call} i dati salvati nel \textit{context + switch} saranno usati per riprendere l'esecuzione ordinaria del programma. Dato che il passaggio dei dati ed il salvataggio del contesto di esecuzione -del programma che consentirà di riprenderne l'esecuzione ordinaria al -completamento della \textit{system call} sono operazioni critiche per le -prestazioni del sistema, per rendere il più veloce possibile questa -operazione, usualmente chiamata \textit{context switch} sono state sviluppate -una serie di ottimizzazioni che richiedono alcune preparazioni abbastanza -complesse dei dati, che in genere dipendono dall'architettura del processore -sono scritte direttamente in \textit{assembler}. +sono operazioni critiche per le prestazioni del sistema, per rendere il più +veloce possibile questa operazione sono state sviluppate una serie di +ottimizzazioni che richiedono alcune preparazioni abbastanza complesse dei +dati, che in genere dipendono dall'architettura del processore e sono scritte +direttamente in \textit{assembler}. + % % TODO:trattare qui, quando sarà il momento vsyscall e vDSO, vedi: @@ -325,14 +335,19 @@ associazione, e lavorare a basso livello con una specifica versione, oppure si può voler utilizzare una \textit{system call} che non è stata ancora associata ad una funzione di libreria. In tal caso, per evitare di dover effettuare esplicitamente le operazioni di preparazione citate, all'interno della -\textsl{glibc} è fornita una specifica funzione, \funcd{syscall}, che consente -eseguire direttamente una \textit{system call}; il suo prototipo, accessibile -se si è definita la macro \macro{\_GNU\_SOURCE}, è: +\textsl{glibc} è fornita una specifica funzione, +\funcd{syscall},\footnote{fino a prima del kernel 2.6.18 per l'esecuzione + diretta delle \textit{system call} erano disponibili anche una serie di + macro \texttt{\_syscall\textsl{N}} (con $N$ pari al numero di argomenti + della \textit{system call}); queste sono deprecate e pertanto non ne + parleremo ulteriormente.} che consente eseguire direttamente una +\textit{system call}; il suo prototipo, accessibile se si è definita la macro +\macro{\_GNU\_SOURCE}, è: \begin{funcproto}{ \fhead{unistd.h} \fhead{sys/syscall.h} - \fdecl{int syscall(int number, ...)} + \fdecl{long syscall(int number, ...)} \fdesc{Esegue la \textit{system call} indicata da \param{number}.} } {La funzione ritorna un intero dipendente dalla \textit{system call} invocata, @@ -366,7 +381,7 @@ linguaggio C all'interno della stessa, o se si richiede esplicitamente la chiusura invocando direttamente la funzione \func{exit}. Queste due modalità sono assolutamente equivalenti, dato che \func{exit} viene chiamata in maniera trasparente anche quando \code{main} ritorna, passandogli come argomento il -valore di ritorno (che essendo . +valore di ritorno. La funzione \funcd{exit}, che è completamente generale, essendo definita dallo standard ANSI C, è quella che deve essere invocata per una terminazione @@ -437,8 +452,12 @@ i valori 0 e 1. Una forma alternativa per effettuare una terminazione esplicita di un programma è quella di chiamare direttamente la \textit{system call} \funcd{\_exit},\footnote{la stessa è definita anche come \funcd{\_Exit} in - \headfile{stdlib.h}.} che restituisce il controllo direttamente al kernel, -concludendo immediatamente il processo, il suo prototipo è: + \headfile{stdlib.h}, inoltre a partire dalle \acr{glibc} 2.3 usando questa + funzione viene invocata \func{exit\_group} che termina tutti i + \textit{thread} del processo e non solo quello corrente (fintanto che non si + usano i \textit{thread}\unavref{, vedi sez.~\ref{cha:threads},} questo non + fa nessuna differenza).} che restituisce il controllo direttamente al +kernel, concludendo immediatamente il processo, il suo prototipo è: \begin{funcproto}{ \fhead{unistd.h} \fdecl{void \_exit(int status)} \fdesc{Causa la conclusione immediata del programma.} } {La funzione non diff --git a/prochand.tex b/prochand.tex index a43fdf8..fc5e477 100644 --- a/prochand.tex +++ b/prochand.tex @@ -3065,7 +3065,7 @@ una risorsa contesa con altri processi, e si vuole dare agli altri una possibilità di approfittarne mettendoli in esecuzione, ma chiamarla senza necessità, specie se questo avviene ripetutamente all'interno di un qualche ciclo, può avere invece un forte impatto negativo per la generazione di -\itindex{contest~switch} \textit{contest switch} inutili. +\textit{context switch} inutili. \subsection{Il controllo dello \textit{scheduler} per i sistemi diff --git a/thread.tex b/thread.tex index a6c6dd7..827fea6 100644 --- a/thread.tex +++ b/thread.tex @@ -116,6 +116,9 @@ delle \acr{glibc}. \label{sec:pthread_management} + + + \subsection{I \textit{mutex}} \label{sec:pthread_mutex}