From: Simone Piccardi Date: Fri, 22 Jun 2001 20:49:50 +0000 (+0000) Subject: Ristrutturazione della introduzione. X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=55bb7b212e8a450f8c9c0f840d5cf0de4c428380 Ristrutturazione della introduzione. --- diff --git a/fileintro.tex b/fileintro.tex index fde0747..c03e360 100644 --- a/fileintro.tex +++ b/fileintro.tex @@ -70,10 +70,7 @@ convenzione, sono inseriti nella directory \texttt{/dev}). \label{sec:fileintr_vfs} Esamineremo adesso come viene implementato l'accesso ai files in Linux. Questa -sezione riporta informazioni sui dettagli di come il kernel gestisce i files, -ed è basata sul documento di Richard Goochs distribuito coi sorgenti del -kernel (nella directory \texttt{linux/Documentation/vfs.txt}). - +sezione riporta informazioni sui dettagli di come il kernel gestisce i files. L'argomento è abbastanza ``esoterico'' e questa sezione può essere saltata ad una prima lettura; è bene però tenere presente che vengono introdotti qui alcuni termini che potranno comparire in seguito, come \textit{inode}, @@ -81,10 +78,26 @@ alcuni termini che potranno comparire in seguito, come \textit{inode}, In Linux il concetto di \textit{everything is a file} è stato implementato attraverso il \textit{virtual filesystem} (da qui in avanti VFS) che è -l'interfaccia astratta che il kernel rende disponibile ai programmi in user -space attraverso la quale vengono manipolati i files; esso provvede anche -un'astrazione delle operazioni di manipolazione sui files che permette la -coesistenza di diversi filesystem all'interno dello stesso albero. +l'interfaccia che il kernel rende disponibile ai programmi in user space +attraverso la quale vengono manipolati i files; esso provvede un livello di +indirezione che permette di collegare le operazioni di manipolazione sui files +alle operazioni di I/O e gestisce l'organizzazione di questi ultimi nei vari +modi in cui diversi filesystem la effettuano, permettendo la coesistenza +di filesystem differenti all'interno dello stesso albero delle directory + +Quando un processo esegue una 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 ridirigendo la chiamata alla +opportune routine del filesystem specifico a cui si fa riferimento, saranno +queste a chiamare le funzioni di piu basso livello che eseguono le operazioni +di I/O sul dispositivo fisico, secondo lo schema riportato in \nfig. + +\begin{figure}[htb] + \centering + + \caption{Schema delle operazioni del VFS} + \label{fig:fileintro_VFS_scheme} +\end{figure} La funzione più importante implementata dal VFS è la system call \texttt{open} che permette di aprire un file. Dato un pathname viene eseguita una ricerca diff --git a/intro.tex b/intro.tex index 4e8dd69..4e97e31 100644 --- a/intro.tex +++ b/intro.tex @@ -1,18 +1,24 @@ -\chapter{Introduzione} +\chapter{L'architettura di GNU/Linux} \label{cha:intro_unix} In questo primo capitolo sarà fatta un'introduzione ai concetti generali su -cui è basato un sistema di tipo unix, per fornire una base di comprensione -mirata a sottolineare le peculiarità che saranno poi importanti per quello -che riguarda la programmazione; in particolare faremo una panoramica sulla -struttura di un sistema \textit{unix-like} come Linux. +cui è basato un sistema di tipo unix come GNU/Linux, per fornire una base di +comprensione mirata a sottolineare le peculiarità che saranno poi importanti +per quello che riguarda la programmazione. -Chi avesse già una conoscenza di questa materia può tranquillamente saltare -il capitolo. +Dopo un introduzione sulle caratteristiche principali di un sistema di tipo +unix passeremo ad illustrare alcuni dei concetti basi dell'architettura di +Linux (che sono comunque comuni a tutti i sistemi \textit{unix-like}) ed +introdurremo alcunoi degli standard princincipali a cui si fa riferimento. -\section{La struttura di un sistema Unix} + +\section{Una panoramica sulla struttura} \label{sec:intro_unix_struct} +In questa prima sezione faremo una panoramica sulla struttura di un sistema +\textit{unix-like} come Linux. Chi avesse già una conoscenza di questa +materia può tranquillamente saltare questa sezione. + Il concetto base di un sistema unix-like é quello di un nucleo del sistema (il cosiddetto \textit{kernel}) a cui si demanda la gestione delle risorse essenziali (la CPU, la memoria, le periferiche) mentre tutto il resto, quindi @@ -44,12 +50,11 @@ o alle porte di input/output). Una parte del kernel, lo \textit{scheduler}, si occupa di stabilire, ad intervalli fissi e sulla base di un opportuno calcolo delle priorità, quale -``processo'' (vedi \capref{cha:process}) deve essere posto in esecuzione (il -cosiddetto \textit{prehemptive scheduling}). Questo verrà comunque eseguito -in modalità protetta; quando necessario il processo potrà accedere alle -risorse hardware soltanto attraverso delle opportune chiamate al sistema -(\textit{system call}) con un'interfaccia ben definita e standardizzata che -restituiranno il controllo al kernel. +``processo'' deve essere posto in esecuzione (il cosiddetto +\textit{prehemptive scheduling}). Questo verrà comunque eseguito in modalità +protetta; quando necessario il processo potrà accedere alle risorse hardware +soltanto attraverso delle opportune chiamate al sistema che restituiranno il +controllo al kernel. La memoria viene sempre gestita del kernel attraverso il meccanismo della memoria virtuale, che consente di assegnare a ciascun processo uno spazio di @@ -68,16 +73,16 @@ livello \section{User space e kernel space} -\label{sec:intro_userkernel} +\label{sec:intro_user_kernel_space} -L'architettura appena descritta fa sì che nei sistemi unix esista una -distinzione essenziale fra il cosiddetto \textit{user space}, che +Uno dei concetti fondamentale su cui si basa l'architettura dei sistemi unix è +quello della distinzione fra il cosiddetto \textit{user space}, che contraddistingue l'ambiente in cui vengono eseguiti i programmi, e il \textit{kernel space} che é l'ambiente in cui viene eseguito il kernel. Ogni -programma vede se stesso come se avesse la piena disponibilità della CPU -e della memoria ed è, salvo i meccanismi di comunicazione previsti -dall'architettura (che esamineremo nel \capref{cha:IPC}) completamente ignaro -del fatto che altri programmi possono essere messi in esecuzione dal kernel. +programma vede se stesso come se avesse la piena disponibilità della CPU e +della memoria ed è, salvo i meccanismi di comunicazione previsti +dall'architettura completamente ignaro del fatto che altri programmi possono +essere messi in esecuzione dal kernel. Per questa separazione non è possibile ad un singolo programma disturbare l'azione di un altro programma o del sistema e questo è il principale motivo @@ -90,21 +95,9 @@ all'hardware non pu kernel il programmatore deve usare le opportune interfacce che quest'ultimo fornisce allo user space. -In genere queste vanno sotto il nome di chiamate al sistema (le cosiddette -\textit{system call}), cioè un insieme di routine che un programma può -chiamare per le quali viene generata una interruzione del medesimo e il -controllo è passato dal programma al kernel, il quale (oltre a fare una serie -di altre cose come controllare a quale processo tocca essere messo in -esecuzione) eseguirà la funzione richiesta in kernel space passando indietro i -risultati. - -È da chiarire poi che di solito i programmi non chiamano direttamente le -singole system call, ma usano un insieme di funzioni standard (definite dallo -standard internazionale POSIX1003.a(?)) che sono comuni a tutti gli unix. - -\section{Il kernel e il resto} -\label{sec:intro_kernandlib} +\subsection{Il kernel e il resto} +\label{sec:intro_kern_and_sys} Per capire meglio la distinzione fra kernel space e user space si può prendere in esame la procedura di avvio di un sistema unix; all'avvio il BIOS (o in @@ -138,20 +131,52 @@ operativo utilizzabile programmi di utilità che permettono di eseguire le normali operazioni che ci si aspetta da un sistema operativo. -Questo è importante anche dal punto di vista della programmazione, infatti -programmare in Linux significa anzitutto essere in grado di usare la Libreria -Standard del C, in quanto né il kernel né il linguaggio C implementano -direttamente operazioni comuni come la gestione della memoria, l'input/output -o la manipolazione delle stringhe presenti in qualunque programma. -Per questo in GNU/Linux una parte essenziale del sistema (senza la quale nulla -funziona) è la realizzazione fatta dalla FSF della suddetta libreria (la -\textit{glibc}), in cui sono state implementate tutte le funzioni essenziali -definite negli standard POSIX e ANSI C, che viene utilizzata da qualunque -programma. - - -\section{Utenti e gruppi, permessi e protezioni} +\subsection{Chiamate al sistema e librerie di funzioni} +\label{sec:intro_syscall} + +Come accennato le interfacce con cui i programmi possono accedere all'hardware +vanno sotto il nome di chiamate al sistema (le cosiddette \textit{system + call}), si tratta di un insieme di routine che un programma può chiamare per +le quali viene generata una interruzione e il controllo è passato dal +programma al kernel. Sarà poi quest'ultimo che (oltre a compiere una serie di +operazioni interne come la gestione del multitaskin e il l'allocazione della +memoria) eseguirà la funzione richiesta in kernel space restituendo i +risultati al chiamante. + +Ogni versione unix ha storicamente sempre avuto un certo numero di queste +chiamate, che sono riportate nella seconda sezione del \textsl{Manuale della + programmazione di unix} (quella che si accede con il comando \texttt{man 2}) +e linux non fa eccezione. Queste sono poi state codificate da vari standard, +che esamineremo brevemente in \secref{sec:intro_standard}. + +Normalmente ciascuna di queste chiamate al sistema viene rimappata in +opportune funzioni con lo stesso nome definite dentro la Libreria Standard del +C, che oltre alle interfacce alle system call contiene anche tutta una serie +di ulteriori funzioni usate comunemente nella programmazione. + +Questo è importante da capire perché programmare in Linux significa anzitutto +essere in grado di usare la Libreria Standard del C, in quanto né il kernel né +il linguaggio C implementano direttamente operazioni comuni come la +allocazione dinamica della memoria, l'input/output bufferizzato o la +manipolazione delle stringhe presenti in qualunque programma. + +Per questo in Linux è in effetti GNU/Linux, in quanto una parte essenziale del +sistema (senza la quale niente può funzionare) è la realizzazione fatta dalla +Free Software Foundation della suddetta libreria (la GNU Standard C Library, +in breve \textit{glibc}), in cui sono state implementate tutte le funzioni +essenziali definite negli standard POSIX e ANSI C, e che viene utilizzata da +qualunque programma. + +Le funzioni di questa libreria sono quelle riportate dalla terza sezione del +Manuale di Programmazione di Unix, e sono costruite sulla base delle chiamate +al sistema del kernel; è importante avere presente questa distinzione, +fondamentale dal punto di vista dell'implementazione, anche se poi nella +relizzazione di normali programmi non si hanno differenze pratiche fra l'uso +di una funzione di libreria e quello di una chiamata al sistema. + + +\subsection{Utenti e gruppi, permessi e protezioni} \label{sec:intro_usergroup} Unix nasce fin dall'inizio come sistema multiutente, cioè in grado di fare @@ -201,5 +226,21 @@ qualunque operazione; pertanto per l'utente root i meccanismi di controllo descritti in precedenza sono disattivati. +\section{Gli standard di unix e Linux} +\label{sec:intro_standard} + + + +\subsection{Lo standard ANSI C} +\label{sec:intro_ansiC} + + + +\subsection{Lo standard POSIX} +\label{sec:intro_ansiC} + + + + diff --git a/simpltcp.tex b/simpltcp.tex index a888781..b024478 100644 --- a/simpltcp.tex +++ b/simpltcp.tex @@ -387,6 +387,10 @@ casi seguenti: \item \end{enumerate} + +\subsection{La gestione dei procesi figli} +\label{sec:TCPsimpl_child_hand} + Tutto questo riguarda la connessione, c'è però un'altro effetto del procedimento di chiusura del processo figlio nel server, e cioè l'invio del segnale \texttt{SIGCHILD} al padre. Dato che non si è installato un @@ -398,3 +402,10 @@ una volta che ripetiamo il comando \texttt{ps}: 2356 pts/0 S 0:00 ./echod 2359 pts/0 Z 0:00 [echod ] \end{verbatim} + +Poiché non è possibile lasciare processi zombie (che pur inattivi occupano +spazio nella tabella dei processi e a lungo andare saturerebbero le risorse +del kernel occorrerà gestire il segnale, per questo installeremo un +manipolatore usando la funzione \texttt{Signal} (trattata in dettaglio in +\secref{sec:sig_xxx}). +