%%
%% Dispense amministrazione base
%%
%% Copyright (C) 2000-2018 Simone Piccardi and Truelite Srl
%%
%% This work is licensed under the Creative Commons Attribution-ShareAlike 4.0
%% International License. To view a copy of this license, visit
%% \url{http://creativecommons.org/licenses/by-sa/4.0/} or send a letter to
%% Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
%%
%% S. Piccardi Oct. 2000
%% 
%% struttura.tex: la struttura del sistema
%%

\chapter{L'architettura di un sistema GNU/Linux}
\label{cha:system_architecture}


\section{L'architettura del sistema}
\label{sec:struct_architecture}

Prima di addentrarci nei dettagli dell'amministrazione di un sistema
GNU/Linux, conviene fornire un quadro generale per introdurre i vari concetti
su cui si fonda l'architettura di questo sistema, che nasce da quella,
consolidatasi in 30 anni di impiego, dei sistemi di tipo Unix.

Il fatto che questa architettura abbia una certa età fa sì che spesso i
detrattori di GNU/Linux ne denuncino la presunta mancanza di
\textsl{innovatività}, ma anche le case hanno da secoli le stesse basi
architetturali (porte, muri e tetti), ma non per questo non esiste
innovazione.  Il vantaggio dell'architettura di Unix infatti è quello di aver
fornito una solida base per la costruzione di sistemi affidabili ed
efficienti, consolidata e corretta in decenni di utilizzo, tanto che, per
citare Henry Spencer: ``\textit{those who don't understand UNIX are doomed to
  reinvent it, poorly}''.


\subsection{L'architettura di base}
\label{sec:struct_base}

Contrariamente ad altri sistemi operativi, GNU/Linux nasce, come tutti gli
Unix, come sistema multitasking e multiutente.  Questo significa che GNU/Linux
ha un'architettura di sistema che è stata pensata fin dall'inizio per l'uso
contemporaneo da parte di più utenti. Questo comporta conseguenze non del
tutto intuitive nel caso in cui, come oggi accade sempre più spesso, esso
venga usato come stazione di lavoro da un utente singolo.

Il concetto base dell'architettura di ogni sistema Unix come GNU/Linux è
quello di una rigida separazione fra il \textit{kernel} (il \textsl{nucleo}
del sistema), cui si demanda la gestione delle risorse hardware (come la CPU,
la memoria, le periferiche) ed i \textsl{processi}, (le unità di esecuzione dei
programmi), che nel caso vanno dai comandi base di sistema, agli applicativi,
alle interfacce per l'interazione con gli utenti.

Lo scopo del kernel infatti è solo quello di essere in grado di eseguire
contemporaneamente molti processi in maniera efficiente, garantendo una
corretta distribuzione fra gli stessi della memoria e del tempo di CPU, e
quello di fornire le adeguate interfacce software per l'accesso alle
periferiche della macchina e le infrastrutture di base necessarie per
costruire i servizi.  Tutto il resto, dall'autenticazione all'interfaccia
utente, viene realizzato usando processi che eseguono gli opportuni programmi.

Questo si traduce in una delle caratteristiche essenziali su cui si basa
l'architettura dei sistemi Unix: la distinzione fra il cosiddetto \textit{user
  space}, che è l'ambiente a disposizione degli utenti, in cui vengono
eseguiti i processi, e il \textit{kernel space}, che è l'ambiente in cui viene
eseguito il kernel. I due ambienti comunicano attraverso un insieme di
interfacce ben definite e standardizzate; secondo una struttura come quella
mostrata in fig.~\ref{fig:kernel}.

\begin{figure}[htb]
  \centering
  \includegraphics[width=12cm]{images/struct_sys}
  \caption{Schema della struttura del sistema operativo GNU/Linux.}
  \label{fig:kernel}
\end{figure}

Questa architettura comporta che solo il kernel viene eseguito in modalità
privilegiata, ed è l'unico a poter accedere direttamente alle risorse
dell'hardware. I normali programmi invece vengono eseguiti in modalità
protetta, in un ambiente virtuale, l'\textit{user space}, in cui essi vedono
se stessi come se avessero piena disponibilità della CPU e della memoria, ma
in cui possono accedere alle periferiche e alle altre funzionalità messe a
disposizione del kernel solo attraverso una serie di \textsl{funzioni di
  sistema} standardizzate, dette \itindex{system~call} \textit{system call}.
Lo standard in questo caso si chiama POSIX.1; ma oltre a quelle dello standard
Linux supporta ulteriori \textit{system call}, relative a sue estensioni
specifiche.

Le \itindex{system~call} \textit{system call} e tutta una serie di ulteriori
funzioni di base sono tradizionalmente raccolte in un'unica libreria che
pertanto diventa essenziale per il funzionamento di qualunque programma
(tratteremo le librerie, e come vengono gestite nel sistema, in
sez.~\ref{sec:cfg_dyn_lib}). Nel caso di Linux questa libreria, illustrata
nello schema in fig.~\ref{fig:kernel}, è la \textit{GNU C library} (chiamata
in breve \textsl{glibc}), che costituisce una delle parti fondamentali del
sistema.

In sostanza quello che succede è che da un certo punto di vista l'unico
``\textsl{vero}'' programma che viene eseguito è il kernel, che si incarica di
costruire questo ambiente virtuale in cui far girare gli altri programmi. Una
parte del kernel, quella indicata in fig.~\ref{fig:kernel} come
\textsf{scheduler}, è deputata della gestione del tempo di processore, e
provvederà a decidere volta per volta qual è il processo che deve essere
eseguito in un determinato momento (realizzando così il multitasking).

\index{memoria~virtuale|(} Una seconda parte, quella indicata in
fig.~\ref{fig:kernel} come \textsf{VM} (sigla che sta per \textit{Virtual
  Memory}), si occupa invece di gestire l'uso della memoria disponibile. La
\textsl{memoria virtuale} è uno dei sottosistemi più importanti del kernel,
oggetto di continui miglioramenti in quanto critico per tutte le prestazioni
del sistema, perché è quella che fa in modo che ogni processo veda uno spazio
di indirizzi proprio che poi viene rimappato nella memoria fisica
effettivamente presente,\footnote{questo viene in genere realizzato con
  l'ausilio delle MMU (\textit{Memory Management Unit}) dei microprocessori;
  una descrizione più dettagliata del funzionamento della \textsl{memoria
    virtuale} può essere trovata nella sezione 2.2 di \cite{GaPiL}.} così che
sia impossibile che un processo possa accedere alla memoria di un altro
processo.  La \textsl{memoria virtuale} si incarica anche di gestire, in caso
di esaurimento della RAM, l'eventuale spostamento delle pagine di memoria meno
usate su uno opportuno spazio disco (lo \textit{swap}, che tratteremo in
sez.~\ref{sec:swap_CDROM_management}) evitando di fermare l'esecuzione di un
processo per una temporanea mancanza di memoria.  Torneremo brevemente
sull'argomento in sez.~\ref{sec:struct_proc_property}.
\index{memoria~virtuale|)}

Infine c'è un'ultima parte del kernel, indicata in fig.~\ref{fig:kernel} con
l'indicazione generica \textsf{driver} anche se in realtà non è un unico
sottosistema come le precedenti ma, come vedremo in
sez.~\ref{sec:kernel_modules}, un insieme di ``\textsl{moduli}'' che
consentono la gestione delle varie periferiche, fornendo un accesso alle
stesse per conto dei programmi. Questa parte, come vedremo meglio in
sez.~\ref{sec:struct_files}, permette di definire una interfaccia di accesso
generica per i dispositivi, cui spesso si fa riferimento dicendo che in un
sistema unix-like ``\textsl{tutto è un file}''.

La conseguenza più importante di questa separazione fra \textit{user space} e
\textit{kernel space} è che in questo modo non è possibile che un singolo
programma possa disturbare l'azione di un altro programma o del kernel stesso,
e questo è il principale motivo della stabilità di un sistema Unix nei
confronti di altri sistemi in cui i processi non hanno di questi limiti, o
vengono, per vari motivi, eseguiti all'interno del kernel.


\subsection{Il funzionamento del sistema}
\label{sec:struct_sys_arch}

Per illustrare meglio la distinzione fra \textit{kernel space} e \textit{user
  space} prendiamo brevemente in esame la procedura di avvio del sistema, su
cui torneremo in dettaglio in sez.~\ref{sec:struct_boot}. All'accensione del
computer viene eseguito il programma del BIOS; questo dopo aver fatto i suoi
controlli interni esegue la procedura di avvio del sistema. Nei PC tutto ciò
viene effettuato caricando dal dispositivo indicato nelle impostazioni del
BIOS un apposito programma, il \itindex{bootloader}
\textit{bootloader},\footnote{questo è un programma speciale, il cui solo
  compito è quello di far partire un sistema operativo, in genere ogni sistema
  ha il suo, nel caso di Linux per l'architettura PC tratteremo i più comuni in
  sez.~\ref{sec:struct_boot}.} che a sua volta recupera (in genere dal disco)
una immagine del kernel che viene caricata in memoria ed eseguita.

Una volta che il controllo è passato al kernel questo, terminata la fase di
inizializzazione in cui ad esempio si esegue una scansione delle periferiche
disponibili, e si leggono le tabelle delle partizioni dei vari dischi (vedi
sez.~\ref{sec:partitioning}) si incaricherà di montare (vedi
sez.~\ref{sec:struct_filesystem_arch}) il filesystem su cui è situata la
\textsl{directory radice} (vedi sez.~\ref{sec:file_FHS}), e farà partire il
primo processo.  Tradizionalmente questo processo si chiama \texttt{init}, ed
è il programma di inizializzazione che a sua volta si cura di far partire
tutti gli altri processi che permettono di usare il sistema.

Fra questi processi ci saranno ad esempio quelli che forniscono i vari servizi
di rete, quelli che eseguono vari compiti di amministrazione, così come quelli
che si occupano di chiedere nome e password dell'utente che si vuole
collegare,\footnote{in realtà se la cosa è fatta da \textit{console} i
  programmi sono due, il primo chiede l'utente e poi chiama il secondo che
  chiede la password, torneremo su questo in sez.~\ref{sec:cfg_login} e
  sez.~\ref{sec:struct_sysv_init}.} e che una volta completato l'ingresso nel
sistema (procedura che viene chiamata \textit{login}) lanciano altri programmi
per mettere a disposizione dell'utente l'interfaccia da cui inviare i comandi,
che potrebbe essere sia una shell a riga di comando (argomento che tratteremo
in dettaglio in cap.~\ref{cha:shell_commands}) che una delle tante interfacce
grafiche disponibili (argomento che riprenderemo in
sez.~\ref{sec:cfg_Xwindow}).

È da rimarcare poi come anche tutti i programmi che un utente di un sistema
GNU/Linux può utilizzare una volta che si è collegato non hanno niente di
diverso da quelli appena citati.  Tutti i programmi funzionano allo stesso
modo: vengono eseguiti dal kernel come processi ed eseguono le loro operazioni
attraverso le opportune \textit{system call} che esso mette a disposizione. 

Da questo punto di vista eseguire sulla shell un programma per vedere la lista
dei file non ha niente di diverso dall'eseguire in ambiente grafico un
programma di scrittura o un programma di foto-ritocco, o dal lanciare un
server web che viene eseguito anche quando nessuno è collegato al sistema.
Questo significa ad esempio che il kernel di per sé non dispone di primitive
per tutta una serie di operazioni, come la copia di un file,\footnote{questa
  infatti viene eseguita usando semplicemente le funzioni che permettono di
  leggere e scrivere il contenuto di un file, leggendo l'originale e scrivendo
  sulla copia.} che altri sistemi operativi (come Windows) hanno al loro
interno: tutte le operazioni di normale amministrazione di un sistema
GNU/Linux sono sempre realizzate tramite degli opportuni programmi.

Tutto ciò ci dice anche che benché esso costituisca il cuore del sistema, il
kernel da solo sarebbe assolutamente inutile, così come sarebbe inutile da
solo il motore di una automobile, senza avere le ruote, lo sterzo, la
carrozzeria, e tutto il resto.  Per avere un sistema funzionante dal punto di
vista di un utente normale infatti occorre avere, oltre al kernel, anche tutti
i programmi che gli permettano di eseguire le varie operazioni con i dischi, i
file, le periferiche.

Per questo al kernel vengono sempre uniti degli opportuni programmi di
gestione per il sistema e tutta una serie di programmi applicativi, ed è
l'insieme di questi e del kernel che costituisce un sistema funzionante. Di
solito i rivenditori, o anche gruppi di volontari, come nel caso di Debian, si
preoccupano di raccogliere in forma coerente i programmi necessari, per andare
a costruire quella che viene chiamata una \textsl{distribuzione}. Sono in
genere queste distribuzioni (come Debian, RedHat, Slackware, SuSE, 
Ubuntu\footnote{in rigoroso ordine alfabetico!}), quelle che si trovano sui CD
con i quali si installa quello che, con una semplificazione molto brutale,
viene chiamato solo ``Linux''.

Il gruppo principale di questi programmi, e le librerie di base che essi e
tutti gli altri programmi usano, derivano dal progetto GNU della Free Software
Foundation: è su di essi che ogni altro programma è basato, ed è per questo
che è più corretto riferirsi all'intero sistema come a GNU/Linux, dato che
Linux indica solo una parte, il kernel, che benché fondamentale non
costituisce da sola un sistema operativo.

Si tenga presente infine che anche se il kernel tratta tutti i programmi allo
stesso modo, non tutti hanno la stessa importanza. Nella precedente
descrizione dell'avvio del sistema abbiamo accennato ad un programma
particolare, \texttt{init}, che ha un ruolo privilegiato in quanto è quello
che si occupa dell'inizializzazione del sistema. La sua peculiarità è quella
di essere lanciato per primo direttamente dal kernel e dover gestire il lancio
di tutti gli altri programmi, per cui non può essere mai terminato. Ma anche
\texttt{init} alla fine non è che un programma che usa le \textit{system call}
e viene eseguito dal kernel, come un qualunque altro programma, ed infatti
esistono alternative rispetto alla implementazione classica, come
\texttt{systemd} (o \texttt{upstart}) su cui torneremo in
sez.~\ref{sec:struct_boot}.

Questo ci porta ad un'altra caratteristica fondamentale dell'architettura dei
sistemi unix-like (ci torneremo in dettaglio in sez.~\ref{sec:struct_process})
che è quella per cui qualunque processo può a sua volta lanciarne di nuovi,
per cui si dice che il primo processo è il \textsl{padre} degli altri, che a
loro volta sono chiamati \textsl{figli}.  È questo che permette l'avvio del
sistema eseguendo un unico programma di inizializzazione (come \texttt{init} o
alternative), dato che quest'ultimo potrà poi lanciare altri programmi, che a
loro volta ne potranno lanciare degli altri ancora, fino a fornire tutte le
funzionalità richieste per il funzionamento del sistema.

Benché sia possibile per usi particolari (ad esempio in sistemi
\textit{embedded}\footnote{si chiamano così i sistemi destinati all'esecuzione
  di compiti specifici, come quelli dei telefonini, dei videoregistratori,
  ecc.} che devono svolgere un solo compito) far partire un programma
applicativo al posto di \texttt{init}, ed anche se, come vedremo in
sez.~\ref{sec:struct_boot}, in casi di emergenza si può lanciare al suo posto
una shell, in pratica tutti i sistemi Unix usano un programma dedicato per
gestire l'avvio del sistema, ed è a seconda degli ulteriori programmi che
questo mette in esecuzione che alla fine della procedura di avvio ci si
troverà davanti ad un terminale a caratteri o ad una interfaccia grafica, e si
avrà, a seconda di quanto deciso (ed installato) dall'amministratore, un
server di posta, un server web, una workstation, ecc.


\subsection{Alcune caratteristiche specifiche di Linux}
\label{sec:struct_linux_char}

Benché Linux stia diventando il più diffuso, esistono parecchi altri kernel
unix-like, sia liberi che proprietari, nati nella tumultuosa e complessa
evoluzione che dallo Unix originario della AT/T ha portato alla nascita di una
miriade di sistemi derivati (BSD, Solaris, AIX, HP-UX, Digital Unix, IRIX,
solo per citare i più noti) che si innestano tutti in due rami principali,
quelli derivati dal sistema sviluppato dalla AT/T, detto SysV (da
\textit{System V}, l'ultima versione ufficiale) e quelli derivati dal codice
sviluppato all'università di Berkeley, detto BSD (da \textit{Berkeley Software
  Distribution}).  La prima caratteristica distintiva di Linux è che esso è
stato riscritto da zero, per cui non è classificabile in nessuno di questi due
rami e prende invece, a seconda dei casi, quelle che sono state ritenute le
migliori caratteristiche di ciascuno di essi.

Un'altra delle caratteristiche peculiari di Linux rispetto agli altri kernel
unix-like è quella di essere \textsl{modulare}; Linux cioè può essere esteso
(torneremo su questo in sez.~\ref{sec:kernel_modules}) inserendo a sistema
attivo degli ulteriori ``pezzi'', i \textsl{moduli}, che permettono di
ampliare le capacità del sistema (ad esempio fargli riconoscere una nuova
periferica).  Questi possono poi essere tolti dal sistema quando non sono più
necessari: un caso tipico può essere quello del modulo che permette di vedere
il CDROM, viene caricato solo quando c'è necessità di leggere un CD e può
essere rimosso una volta che questo non sia più in uso.

In realtà è sempre possibile costruire un kernel Linux comprensivo di tutti i
moduli che servono, ottenendo quello che viene chiamato un kernel
\textsl{monolitico} (come sono i kernel tradizionali degli altri Unix). Questo
permette di evitare il ritardo nel caricamento dei moduli al momento della
richiesta, ma comporta un maggiore consumo di memoria, dovendo tenere dentro
il kernel anche codice non utilizzato, ed una flessibilità nettamente
inferiore, in quanto si perde la capacità di poter specificare eventuali
opzioni al momento del caricamento, costringendo al riavvio in caso di
necessità di cambiamenti.

Per contro in certi casi l'uso dei moduli può degradare leggermente le
prestazioni, quasi sempre in maniera non avvertibile, e può dar luogo a
conflitti inaspettati che con un kernel monolitico avrebbero bloccato il
sistema all'avvio, ma questi problemi oggi sono sempre più rari.  In ogni caso
non è possibile utilizzare i moduli nel caso in cui le funzionalità da essi
fornite siano necessarie ad avviare il sistema.

Una terza peculiarità di Linux è quella del \textit{Virtual File System} (o
VFS). Un concetto generale presente in tutti i sistemi Unix (e non solo) è che
lo spazio su disco su cui vengono tenuti i file di dati è organizzato in
quello che viene chiamato un \textit{filesystem} (tratteremo l'amministrazione
dei \textit{filesystem} in sez.~\ref{sec:disk_filesystem_admin}). Lo spazio
disco grezzo è normalmente suddiviso in settori contigui di dimensione
fissa,\footnote{nel senso che le interfacce hardware per i dischi consentono
  l'accesso diretto al contenuto di questi settori.}  ma all'interno del
sistema questo viene organizzato in maniera tale da permettere il rapido
reperimento delle informazioni memorizzate su questi settori, anche quando
queste sono sparse qua e là sul disco; si ha così quello che l'utente vede
come un singolo file.

Quello che contraddistingue Linux è che l'interfaccia per la lettura del
contenuto di un filesystem è stata resa completamente generica, per cui
inserendo gli opportuni moduli nel sistema diventa possibile accedere con la
stessa interfaccia e, salvo limitazioni della realizzazione, in maniera
completamente trasparente all'utente, ai più svariati tipi di filesystem, a
partire da quelli usati da Windows e dal DOS, dal MacOS, e da tutte le altre
versioni di Unix.

Dato che essa gioca un ruolo centrale nel sistema, torneremo in dettaglio
sull'interfaccia dei file, e di come possa essere usata anche per altro che i
file di dati, in sez.~\ref{sec:struct_files}. Quello che è importante tenere
presente da subito è che la disponibilità di una astrazione delle operazioni
sui file rende Linux estremamente flessibile, dato che attraverso di essa è
stato in grado, fin dalle prime versioni, di supportare con relativa facilità
ed in maniera nativa una quantità di filesystem superiore a quella di
qualunque altro sistema operativo.



\section{L'architettura dei file}
\label{sec:struct_files}

Un aspetto fondamentale dell'architettura di GNU/Linux è quello della gestione
dei file. Esso deriva direttamente da uno dei criteri base della progettazione
di tutti i sistemi Unix, quello espresso dalla frase ``\textit{everything is a
  file}'' (cioè \textsl{tutto è un file}), per cui l'accesso ai file e alle
periferiche è gestito attraverso una interfaccia identica.

Inoltre, essendo in presenza di un sistema multiutente e multitasking, il
kernel deve anche essere in grado di gestire l'accesso contemporaneo allo
stesso file da parte di più processi, e questo viene fatto usando un disegno
specifico nella struttura delle interfacce di accesso, che è uno dei punti di
maggior forza dell'architettura di un sistema Unix.


\subsection{Il \textit{Virtual File System} e le caratteristiche dei file}
\label{sec:struct_file_vfs}

Come accennato in sez.~\ref{sec:struct_linux_char} i file sono organizzati sui
dischi all'interno di filesystem. Perché i file diventino accessibili al
sistema un filesystem deve essere \textsl{montato} in modo che essi siano resi
visibili all'interno di una certa directory. Questa è una operazione
privilegiata che normalmente può fare solo l'amministratore (ne tratteremo i
dettagli più avanti, in sez.~\ref{sec:file_disk_management}), che provvede a
rendere disponibili le interfacce, in genere attraverso il caricamento di
opportuni moduli del kernel, che permettono l'accesso ai file contenuti nel
filesystem.

Come esempio consideriamo il caso in cui si voglia leggere il contenuto di un
CD. Il kernel dovrà poter disporre sia delle interfacce per poter parlare al
dispositivo fisico (ad esempio il supporto SCSI, se il CDROM è SCSI), che di
quelle per la lettura dal dispositivo specifico (il modulo che si interfaccia
ai CDROM, che è lo stesso che questi siano su SCSI, IDE o USB), sia di quelle
che permettono di interpretare il filesystem ISO9660 (che è quello che di
solito viene usato per i dati registrati su un CDROM) per estrarne il
contenuto dei file.

Come accennato nell'introduzione a questa sezione, uno dei criteri
fondamentali dell'architettura di un sistema Unix è quello per cui
\textsl{tutto è un file} e per cui si può accedere a tutte le periferiche,
con la sola eccezione delle interfacce ai dispositivi di rete, che non
rientrano bene nell'astrazione e sono gestite in maniera diversa, con una
interfaccia identica a quella con cui si accede al contenuto dei file.  Questo
comporta però una serie di differenze nella gestione dei file rispetto ad
altri sistemi.

Anzitutto in un sistema Unix tutti i file di dati sono uguali: non esiste cioè
la differenza fra file di testo o binari che c'è in Windows, né fra file
sequenziali e ad accesso diretto che c'era nel VMS. Inoltre le estensioni sono
solo convenzioni, e non significano nulla per il kernel, che legge tutti i
file di dati alla stessa maniera, indipendentemente dal nome e dal contenuto.

\index{file~di~dispositivo|(}

In realtà il sistema prevede tipi diversi di file, ma in un altro senso; ad
esempio il sistema può accedere alle periferiche, attraverso dei file speciali
detti \textit{device file} o \textsl{file di dispositivo}. Così si può suonare
una canzone scrivendo su \texttt{/dev/dsp},\footnote{questo avveniva con il
  vecchio supporto audio, con ALSA (la nuova infrastruttura del kernel per i
  dispositivi audio) i nomi dei dispositivi sono diversi ed in genere oggi la
  gestione dell'audio viene comunque delegata ad un programma che faccia da
  interfaccia fra i dispositivi, che possono essere i più vari, ed i programmi
  che vogliono poter suonare qualcosa.} leggere l'output di una seriale direttamente
da \texttt{/dev/ttyS0}, leggere direttamente dai settori fisici del disco
rigido accedendo a \texttt{/dev/hda}, o fare animazioni sullo schermo
scrivendo su \texttt{/dev/fb0} (questo è molto più difficile da fare a
mano). Un elenco dei vari oggetti visti come file dal kernel è riportato in
tab.~\ref{tab:file_file_types}; ognuno di questi fornisce una funzionalità
specifica, sempre descritta nella medesima tabella.

\index{file~di~dispositivo|)}


\begin{table}[htb]
  \footnotesize
  \centering
    \begin{tabular}[c]{|l|p{1.8cm}|c|p{6cm}|}
    \hline
    \multicolumn{3}{|c|}{\textbf{Tipo di file}} &\textbf{Descrizione} \\
    \hline
    \hline
      \textit{regular file} & \textsl{file regolare}          & \texttt{-} &
              un file che contiene dei dati (ciò che si intende normalmente
              per file). \\ 
      \textit{directory}    & \textsl{cartella o direttorio}  & \texttt{d}&
              un file che contiene una lista di nomi associati a degli
              \textit{inode}.  \\
      \textit{symbolic link}& \textsl{collegamento simbolico} & \texttt{l}&
              un file che contiene un riferimento ad un altro file o
              directory.\\
      \textit{char device}  & \textsl{dispositivo a caratteri}& \texttt{c}&
              un file che identifica una periferica ad accesso a caratteri.\\
      \textit{block device} & \textsl{dispositivo a blocchi}  & \texttt{b}&
              un file che identifica una periferica ad accesso a blocchi. \\
      \textit{fifo} o \textit{pipe}&
                        ``\textsl{coda}'' o ``\textsl{tubo}'' & \texttt{p}&
             un file speciale che identifica una linea di comunicazione 
             unidirezionale.\\
      \textit{socket}      & ``\textsl{presa}''       & \texttt{s}&
              un file speciale che identifica una linea di comunicazione 
              bidirezionale.\\
    \hline
    \end{tabular}
    \caption{I vari tipi di file riconosciuti da Linux}
    \label{tab:file_file_types}
\end{table}

\itindbeg{fifo}

Altri due tipi di file speciali riportati in tab.~\ref{tab:file_file_types}
sono le \textit{fifo} ed i \textit{socket}, che altro non sono che dei canali
di comunicazione messi a disposizione dal kernel ai processi, perché questi
possano parlarsi fra di loro. Dato che, come accennato in
sez~\ref{sec:struct_architecture}, i processi sono completamente separati fra
loro, può essere soltanto il kernel a fornire le funzionalità che permettano
la comunicazione.

Questi file speciali sono due modalità diverse per realizzare una
comunicazione fra processi diversi; aprendo una \textit{fifo} un processo può
scrivervi sopra ed un altro processo che ha aperto la \textit{fifo} leggerà
dall'altro capo quanto il primo ha scritto,\footnote{l'uso delle \textit{fifo}
  su disco è in realtà abbastanza complesso e benché quasi sempre coinvolga
  due soli processi (uno che scrive e uno che legge) si possono avere
  situazioni più complicate; la trattazione dell'argomento va oltre gli scopi
  di questo testo, chi fosse interessato può trovare delle spiegazioni
  dettagliate sull'argomento nella sezione 9.1 di \cite{GaPiL}.} niente verrà
salvato su disco, ma passerà tutto attraverso il kernel che consente questa
comunicazione come attraverso un \textsl{tubo} (da questo deriva il nome
\textit{pipe}). I \textit{socket} fanno la stessa cosa ma consentono una
comunicazione bidirezionale, in cui il secondo processo può scrivere indietro,
ed il primo leggere, quando invece per le \textit{fifo} il flusso dei dati è
unidirezionale.

\itindend{fifo}


La possibilità di avere tutti questi tipi di file speciali è dovuta al fatto
che, come accennavamo in sez.~\ref{sec:struct_linux_char}, in Linux l'accesso
ai file viene eseguito attraverso una interfaccia unificata, il
\textit{Virtual File System}, che definisce una serie di operazioni generiche
che sono le stesse per tutti gli oggetti che essa gestisce; è questo che
implementa la filosofia progettuale del \textsl{tutto è un file}.  Le
principali operazioni sono riportate in tab.~\ref{tab:file_file_operations};
ogni oggetto del sistema visto attraverso il \textit{Virtual File System}
definisce la sua versione di queste operazioni.

Come si può notare sono definite sia operazioni generiche come la
lettura e la scrittura, che più specialistiche, come lo spostamento
all'interno di un file.\footnote{ce ne sono altre ancora più complesse, che
  non sono state riportate in tab.~\ref{tab:file_file_operations}, per una
  trattazione dettagliata dell'argomento si consulti sez.~4.1.1 di
  \cite{GaPiL}.}  Quando si utilizzano le \textit{system call} per accedere ad
un file sarà compito del kernel chiamare l'operazione relativa ad esso
associata (che sarà ovviamente diversa a seconda del tipo di file), o
riportare un errore quando quest'ultima non sia definita: ad esempio sul file
di dispositivo associato alla seriale non si potrà mai utilizzare l'operazione
di spostamento \textsl{\texttt{llseek}}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|l|}
    \hline
    \textbf{Funzione} & \textbf{Operazione} \\
    \hline
    \hline
    \textsl{\texttt{open}}   & apre il file. \\
    \textsl{\texttt{read}}   & legge dal file.\\
    \textsl{\texttt{write}}  & scrive sul file.\\ 
    \textsl{\texttt{llseek}} & si sposta all'interno del file. \\
    \textsl{\texttt{ioctl}}  & accede alle operazioni di controllo.\\
    \textsl{\texttt{readdir}}& legge il contenuto di una directory. \\
    \hline
  \end{tabular}
  \caption{Principali operazioni sui file definite nel VFS.}
  \label{tab:file_file_operations}
\end{table}

Il \textit{Virtual File System} è anche il meccanismo che permette al kernel
di gestire tanti filesystem diversi; quando uno di questi viene montato è
compito del kernel utilizzare per le varie \textit{system call} le opportune
operazioni in grado di accedere al contenuto di quel particolare filesystem;
questa è la ragione principale della grande flessibilità di Linux nel
supportare i filesystem più diversi, basta definire queste operazioni per un
filesystem per poterne permettere l'accesso da parte delle varie
\textit{system call} secondo la stessa interfaccia.

Uno dei programmi fondamentali per la gestione dei file attraverso
l'interfaccia a riga di comando è \index{comando!\texttt{ls}} \texttt{ls} (il
cui nome, non proprio intuitivo, deriva da \textit{\textbf{l}i\textbf{s}t
  file}) che mostra, se invocato senza nessun argomento, l'elenco dei file
nella directory corrente.  Usando l'opzione \texttt{-l} è invece possibile
ottenere una lista estesa, in cui compaiono varie proprietà dei file. Ad
esempio, avendo creato una directory con i vari tipi di file citati in
tab.~\ref{tab:file_file_types},\footnote{con l'eccezione dei \textit{socket},
  questi ultimi infatti non sono di norma utilizzati dai comandi di shell, ma
  vengono creati direttamente dai programmi che li usano (il caso più comune è
  X Window), non esiste pertanto un comando di uso comune che permetta di
  crearne uno in maniera esplicita.} si potrà andare in detta directory ed
ottenere:
\begin{Console}
piccardi@oppish:~/filetypes$ \textbf{ls -l}
total 1
brw-r--r--    1 root     root       1,   2 Jul  8 14:48 block
crw-r--r--    1 root     root       1,   2 Jul  8 14:48 char
drwxr-xr-x    2 piccardi piccardi       48 Jul  8 14:24 dir
prw-r--r--    1 piccardi piccardi        0 Jul  8 14:24 fifo
-rw-r--r--    1 piccardi piccardi        0 Jul  8 14:24 file
lrwxrwxrwx    1 piccardi piccardi        4 Jul  8 14:25 link -> file
\end{Console}
%$
e si noti come la prima lettera in ciascuna riga indichi il tipo di file,
anche questo secondo la notazione riportata nella terza colonna di
tab.~\ref{tab:file_file_types}.

Il comando \texttt{ls} è dotato di innumerevoli opzioni, che gli consentono di
visualizzare le varie caratteristiche dei file, delle quali il tipo è solo
una.  Altre caratteristiche sono: i tempi di ultimo accesso, modifica e
cambiamento (su cui torneremo fra poco), le informazioni relative a permessi
di accesso e proprietari del file (che vedremo in dettaglio in
sez.~\ref{sec:struct_file_perm}), la dimensione, il numero di \textit{hard
  link} (che vedremo in sez.~\ref{sec:struct_filesystem_arch}).

Il comando prende come argomento una lista di file o directory; senza opzioni
viene mostrato solo il nome del file (se esiste) o il contenuto della
directory specificata. Le opzioni sono moltissime, e le principali sono
riportate in tab.~\ref{tab:file_ls_options}, l'elenco completo è riportato
nella pagina di manuale accessibile con il comando \texttt{man ls}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-l} & scrive la lista in formato esteso.\\
    \texttt{-a} & mostra i file \textsl{invisibili}.\\
    \texttt{-i} & scrive il numero di \textit{inode} 
                  (vedi sez.~\ref{sec:struct_filesystem_arch}).\\ 
    \texttt{-R} & esegue la lista ricorsivamente per tutte le
                  sottodirectory.\\ 
    \texttt{-c} & usa il tempo di ultimo cambiamento del file.\\
    \texttt{-u} & usa il tempo di ultimo accesso al file.\\
    \texttt{-d} & mostra solo il nome e non il contenuto quando riferito ad
                  una directory, e non segue i link simbolici.\\ 
    \hline
  \end{tabular}
  \caption{Principali opzioni del comando \texttt{ls}.}
  \label{tab:file_ls_options}
\end{table}

Una convenzione vuole che i file il cui nome inizia con un punto
(``\texttt{.}'')  non vengano riportati nell'output di \texttt{ls}, a meno di
non richiederlo esplicitamente con l'uso dell'opzione \texttt{-a}; per questo
tali file sono detti \textsl{invisibili}. Si tenga presente comunque che
questa \textsl{non} è una proprietà dei file e non ha nulla a che fare con le
modalità con cui il kernel li tratta (che sono sempre le stesse), ma solo una
convenzione usata e rispettata dai vari programmi in \textit{user space}.

L'opzione \texttt{-l} permette di mostrare una lista in formato esteso in cui
vengono riportate molte informazioni concernenti il file. Abbiamo visto in
precedenza un esempio di questa lista, e come il primo carattere della prima
colonna indichi il tipo di file, mentre il resto della colonna indica i
\textsl{permessi} del file, secondo una notazione su cui torneremo in
sez.~\ref{sec:struct_file_perm}. Il secondo campo indica il numero di
\textit{hard link} al file (su questo torneremo in
sez.~\ref{sec:struct_filesystem_arch}), mentre il terzo ed il quarto campo
indicano rispettivamente utente e gruppo proprietari del file (anche questo
sarà trattato in sez.~\ref{sec:struct_file_perm}). Il quinto campo indica la
dimensione, usualmente riportata in byte.  Il sesto campo è il tempo di
\textsl{ultima modifica} del file e l'ultimo campo il nome del file.

In un sistema unix-like i tempi associati ai file (mantenuti automaticamente
dal kernel quando opera su di essi) sono tre ed hanno un significato diverso
rispetto a quanto si trova in altri sistemi operativi.\footnote{per una
  trattazione dettagliata di questo argomento si può consultare il capitolo
  4.3.4 di \cite{GaPiL}.} Il tempo mostrato di default da \texttt{ls} è il
cosiddetto \textsl{tempo di ultima modifica} (o \textit{modification time})
che corrisponde all'ultima volta che è stato modificato il contenuto di un
file.  

Si badi bene che questo tempo riguarda solo il \textsl{contenuto} del file, se
invece si operano delle modifiche sulle proprietà del file (ad esempio si
cambiano i permessi) varia quello che viene chiamato \textsl{tempo di ultimo
  cambiamento} (il \textit{change time} o \textit{status change time} ) che
viene visualizzato da \texttt{ls} con l'opzione \texttt{-c}.  Infine tutte le
volte che si accede al contenuto del file viene cambiato\footnote{a meno che
  questa funzionalità non sia stata disabilitata, vedremo come farlo per un
  filesystem in sez.~\ref{sec:file_disk_management} e per un singolo file in
  sez.~\ref{sec:struct_privileged_operations}; per alcuni kernel recenti
  inoltre, per migliorare le prestazioni, questo tempo può essere cambiato
  solo se necessario ed anche solo una volta al giorno.} il \textsl{tempo di
  ultimo accesso} (o \textit{access time}) che può essere visualizzato da
\texttt{ls} con l'opzione \texttt{-u}.

Si noti infine come fra i precedenti tempi non ci sia un tempo di creazione
del file, che in un sistema unix-like \textsl{non} esiste come informazione a
parte. Quando un file viene creato infatti vengono impostati i tre tempi
precedenti al tempo corrente, ma questa informazione verrà sovrascritta nelle
operazioni successive; fintanto che non si modificano i contenuti comunque si
potrà considerare il tempo di ultima modifica come coincidente con il tempo di
creazione.

Per operare sui tempi associati ad un file esiste un apposito comando,
\index{comando!\texttt{touch}} \texttt{touch}. In genere questo comando viene
usato in quasi tutti gli esempi per creare un file vuoto, ma in realtà il suo
scopo non è questo (dato che lo stesso compito si potrebbe eseguire in molti
altri modi) quanto piuttosto, come dice il nome, quello di \textsl{toccare} un
file, anche già esistente, cambiandone i tempi.

Il comando prende come argomenti uno o più nomi di file. Se uno di questi non
esiste il risultato del comando è quello di crearlo vuoto, ma se invece esiste
l'effetto del comando è quello di modificare al tempo corrente i tempi di
ultimo accesso e ultima modifica.\footnote{il tempo di ultimo cambiamento di
  stato viene modificato solo dal kernel, e non esiste una modalità immediata
  (che non sia quella di andare a sovrascrivere l'informazione con un accesso
  diretto al dispositivo del disco) per cambiarlo manualmente.} Il comando
prende varie opzioni e permette di modificare solo il tempo di ultimo accesso
se usato con l'opzione \texttt{-a} o solo quello di ultima modifica, se usato
con l'opzione \texttt{-m}, si può specificare una data con \texttt{-d} (per il
formato si veda sez.~\ref{sec:cmd_time}) o prendere i valori da un altro file
con l'opzione \texttt{-r}. I dettagli e l'elenco completo delle opzioni sono
al solito sulla pagina di manuale, accessibile con \texttt{man touch}



\subsection{L'architettura di un filesystem e le proprietà dei file}
\label{sec:struct_filesystem_arch}

Come già accennato Linux (ed ogni sistema unix-like) organizza i dati che
tiene su disco attraverso l'uso di un filesystem. Una delle caratteristiche di
Linux rispetto agli altri Unix è quella di poter supportare, grazie al VFS,
una enorme quantità di filesystem diversi, ognuno dei quali ha una sua
particolare struttura e funzionalità proprie.\footnote{riprenderemo
  l'argomento della gestione di dischi e filesystem in
  sez.~\ref{sec:disk_filesystem_admin}.} Per questo non entreremo nei dettagli
di un filesystem specifico, ma daremo una descrizione a grandi linee che si
adatta alle caratteristiche comuni di un filesystem generico usato su un
sistema unix-like.

\begin{figure}[htb]
  \centering
  \includegraphics[width=13cm]{images/filesys_struct}
  \caption{Strutturazione dei dati all'interno di un filesystem.}
  \label{fig:file_filesys_detail}
\end{figure}

Se si va ad esaminare con maggiore dettaglio come è strutturata l'informazione
all'interno di un singolo filesystem, possiamo esemplificare la situazione con
uno schema come quello esposto in fig.~\ref{fig:file_filesys_detail}, da cui
si evidenziano alcune delle caratteristiche di base di un filesystem, sulle
quali è bene porre attenzione visto che sono fondamentali per capire il
funzionamento dei comandi che manipolano i file e le directory.

\index{inode|(} 

La struttura che identifica univocamente un singolo file all'interno di un
filesystem è il cosiddetto \textit{inode}: ciascun file è associato ad un
\textit{inode} in cui sono mantenute tutte le informazioni che lo riguardano,
come il tipo (fra quelli di tab.~\ref{tab:file_file_types}), i permessi di
accesso (vedi sez.~\ref{sec:struct_file_perm}), utente e gruppo proprietario,
le dimensioni, i tempi, ed anche tutti i riferimenti ai settori del disco (i
\textsl{blocchi fisici}) che contengono i dati; le informazioni che fornisce
il comando \texttt{ls} provengono dall'\textit{inode}.

L'unica informazione relativa al file non contenuta nell'\textit{inode} è il
suo nome; infatti il nome di un file non è una proprietà del file, ma
semplicemente una etichetta associata ad un \textit{inode}. Le directory
infatti non \textsl{contengono} i file, ma sono dei file speciali (di tipo
\textit{directory}, così che il kernel possa trattarle in maniera diversa) il
cui contenuto è semplicemente una lista di nomi a ciascuno dei quali viene
associato un numero di \textit{inode} che identifica il file cui il nome fa
riferimento.

\itindbeg{hard~link}

Come mostrato in fig.~\ref{fig:file_filesys_detail} si possono avere più voci
in directory diverse che puntano allo stesso \textit{inode}.  Questo introduce
il concetto di \textit{hard link} (detto anche \textsl{collegamento diretto}):
due file che puntano allo stesso \textit{inode} sono fisicamente lo stesso
file, nessuna proprietà specifica, come permessi, tempi di accesso o contenuto
permette di distinguerli, in quanto l'accesso avviene per entrambi attraverso
lo stesso \textit{inode}.

Siccome uno stesso \textit{inode} può essere referenziato in più directory, un
file può avere più nomi, anche completamente scorrelati fra loro. Per questo
ogni \textit{inode} mantiene un contatore che indica il numero di riferimenti
che gli sono stati fatti, il cosiddetto \textit{link count}. Questo numero
viene mostrato, nell'esempio del precedente risultato di \texttt{ls -l}, dal
valore riportato nella seconda colonna della stampa dei risultati, e ci
permette di dire se un file ha degli \textit{hard link}, anche se non indica
dove sono.

Il comando generico che permette di creare dei \textit{link} è
\index{comando!\texttt{ln}} \texttt{ln} che prende come argomenti il file
originale ed il nome del nuovo link. La differenza rispetto a Windows o MacOS
è che in un sistema unix-like i collegamenti per i file sono di due tipi,
oltre agli \textit{hard link} appena illustrati infatti esistono anche i
cosiddetti \textsl{collegamenti simbolici}, o \textit{symbolic link}, che sono
quelli effettivamente più simili ai collegamenti di Windows o agli alias del
MacOS, come il file \texttt{link} mostrato in precedenza.

Per creare un \textit{hard link} basta usare direttamente il comando
\texttt{ln}, (il cui nome deriva da \textit{\textbf{l}i\textbf{n}k file}) che
di default crea questo tipo di collegamento.  Così possiamo creare un nuovo
file \texttt{hardlink} per il file \texttt{file} visto in precedenza usando il
comando:
\begin{Console}
piccardi@oppish:~/filetypes$ \textbf{ln file hardlink}
\end{Console}
%$
e se riesaminiamo la lista dei file otterremo che:
\begin{Console}
piccardi@oppish:~/filetypes$ \textbf{ls -l}
total 1
brw-r--r--    1 root     root       1,   2 Jul  8 14:48 block
crw-r--r--    1 root     root       1,   2 Jul  8 14:48 char
drwxr-xr-x    2 piccardi piccardi       48 Jul  8 14:24 dir
prw-r--r--    1 piccardi piccardi        0 Jul  8 14:24 fifo
-rw-r--r--    2 piccardi piccardi        0 Jul  8 14:24 file
-rw-r--r--    2 piccardi piccardi        0 Jul  8 14:24 hardlink
lrwxrwxrwx    1 piccardi piccardi        4 Jul  8 14:25 link -> file
\end{Console}
%$

Si noti come adesso la seconda colonna dell'output del comando mostri sia per
\texttt{file} che per \texttt{hardlink} un valore pari a due, come ci si
aspetta dato che entrambi fanno riferimento allo stesso \textit{inode} che
pertanto ha due collegamenti. Usando l'opzione \texttt{-i} di \texttt{ls}
possiamo anche stampare per ciascun file il rispettivo numero di
\textit{inode}, ottenendo:
\begin{Console}
piccardi@oppish:~/filetypes$ \textbf{ls -li}
total 1
   2118 brw-r--r--    1 root     root       1,   2 Jul  8 14:48 block
   2120 crw-r--r--    1 root     root       1,   2 Jul  8 14:48 char
     15 drwxr-xr-x    2 piccardi piccardi       48 Jul  8 14:24 dir
   2115 prw-r--r--    1 piccardi piccardi        0 Jul  8 14:24 fifo
   2117 -rw-r--r--    2 piccardi piccardi        0 Jul  8 14:24 file
   2117 -rw-r--r--    2 piccardi piccardi        0 Jul  8 14:24 hardlink
   2116 lrwxrwxrwx    1 piccardi piccardi        4 Jul  8 14:25 link -> file
\end{Console}
%$
e si può verificare come effettivamente \texttt{file} e \texttt{hardlink}
abbiano lo stesso numero di \textit{inode}, che nel caso è 2117.

Un limite che si ha con gli \textit{hard link} è dovuto al fatto che si può
fare riferimento solo ad un \textit{inode} presente nello stesso filesystem
della directory. Questo avviene perché le directory contengono semplicemente
l'associazione fra un nome ed un numero di \textit{inode} ed ogni filesystem
numera progressivamente ed in maniera indipendente i propri \textit{inode},
per cui su un altro filesystem lo stesso numero di \textit{inode}
identificherà un file diverso.  Questo limita l'uso degli \textit{hard link}
solo a file residenti sul filesystem corrente, ed infatti il comando
\texttt{ln} darà un errore se si cerca di creare un \textit{hard link} ad un
file posto in un altro filesystem.

\itindend{hard~link}

Per superare questa limitazione sono stati introdotti i cosiddetti
\textsl{collegamenti simbolici} o \textit{symbolic link}, che vengono creati
usando l'opzione \texttt{-s} del comando \texttt{ln}; ad esempio si è creato
il collegamento simbolico \texttt{link} mostrato nell'esempio precedente con
il comando:
\begin{Console}
piccardi@oppish:~/filetypes$ \textbf{ln -s file link}
\end{Console}
%$

In questo caso viene creato un nuovo file, di tipo \textit{symbolic link}, che
avrà un suo diverso \textit{inode} (come risulta nell'output di \texttt{ls
  -li} appena mostrato) ed il cui contenuto è il percorso (torneremo sulla
notazione che esprime i \textit{pathname} dei file fra poco) da fare per
arrivare al file a cui esso fa riferimento, che a questo punto può essere in
qualsiasi altro filesystem. È compito del kernel far sì che quando si usa un
link simbolico si vada poi ad operare sul file che questo ci
indica,\footnote{una trattazione dettagliata su come vengono gestite dal
  kernel le operazioni sui link simbolici si può trovare in sez.~4.2.1 di
  \cite{GaPiL}.} ed è questo il motivo per cui per i link simbolici esiste un
apposito tipo di file, come riportato in tab.~\ref{tab:file_file_types}.

Oltre a \texttt{-s} il comando \texttt{ln} prevede una serie di altre opzioni,
le principali delle quali sono riportate in tab.~\ref{tab:file_ln_options}. La
lista completa delle opzioni, e la relativa documentazione, è disponibile
nella pagina di manuale, accessibile attraverso il comando \texttt{man ln}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-s} & crea un collegamento simbolico.\\
    \texttt{-f} & forza la sovrascrittura del nuovo file se esso esiste
                  già.\\
    \texttt{-i} & richiede conferma in caso di sovrascrittura.\\ 
    \texttt{-d} & crea un \textit{hard link} ad una
                  directory (in Linux questa non è usabile).\\ 
    \texttt{-b} & esegue un backup della destinazione se questa esiste già.\\
    \hline
  \end{tabular}
  \caption{Principali opzioni del comando \texttt{ln}.}
  \label{tab:file_ln_options}
\end{table}

Una seconda caratteristica dei link simbolici è la possibilità di creare dei
collegamenti anche per delle directory. Questa capacità infatti, sebbene
teoricamente possibile anche per gli \textit{hard link}, in Linux non è
supportata per la sua pericolosità, è possibile infatti creare dei
\textit{link loop} se si commette l'errore di creare un collegamento alla
directory che contiene il collegamento stesso; con un collegamento simbolico
questo errore può essere corretto in quanto la cancellazione del link
simbolico rimuove quest'ultimo, e non il file referenziato, ma con un
\textit{hard link} non è più possibile fare questa distinzione e la rimozione
diventa impossibile.

La possibilità di creare dei collegamenti alle directory tuttavia è
estremamente utile, infatti qualora si voglia accedere ai file in una
directory attraverso un percorso diverso, ad esempio a causa di un programma
che cerca dei file di configurazione in una locazione diversa da quella
usuale, piuttosto che dover spostare tutti i file basterà creare un
collegamento simbolico e si sarà risolto il problema.

Oltre agli \textit{hard link} la struttura di un filesystem unix-like ha
ulteriori conseguenze non immediate da capire per chi proviene da sistemi
operativi diversi. La presenza degli \textit{hard link} e l'uso degli
\textit{inode} nelle directory infatti comporta anche una modalità diversa
nella cancellazione dei file e nello spostamento degli stessi.

Il comando per la cancellazione di un file è \index{comando!\texttt{rm}}
\texttt{rm} (il cui nome deriva da \textit{\textbf{r}e\textbf{m}ove file}), ma
la funzione usata dal sistema per effettuare questo compito si chiama in
realtà \textsl{\texttt{unlink}} ed essa, come ci dice il nome, non cancella
affatto i dati del file, ma si limita ad eliminare la relativa voce da una
directory e decrementare il numero di riferimenti presenti
nell'\textit{inode}.

Solo quando il numero di riferimenti ad un \textit{inode} si annulla, i dati
del file vengono effettivamente rimossi dal disco dal kernel.  In realtà oltre
ai riferimenti mostrati da \texttt{ls} il kernel mantiene anche un'altra lista
di riferimenti, per ciascun processo che sta accedendo al file, per cui anche
se si cancella un file da una directory e non restano altri \textit{hard link}
al relativo \textit{inode}, ma resta attivo un processo che lo utilizza, lo
spazio disco non verrà rilasciato, e fintanto che il processo non avrà finito
i dati resteranno, anche se solo per lui, disponibili.\footnote{per
  approfondire questo aspetto dell'architettura dei file per un sistema
  operativo unix-like, si può consultare il capitolo 4 di \cite{GaPiL}.}

In realtà anche questo è vero solo parzialmente, con la sua cancellazione i
dati di un file in realtà non vengono toccati, viene solo dichiarato come
disponibile lo spazio da loro occupato, che così può essere riutilizzato.
Questo comporta che è possibile, se nessuno ha usato tale spazio, trovare
ancora sul disco i suddetti dati con degli appositi programmi di recupero.
Per questo quando si vuole essere davvero sicuri che i dati siano cancellati
si deve utilizzare al posto di \texttt{rm} un comando come
\index{comando!\texttt{shred}} \texttt{shred} che provvede anche ad una
opportuna sovrascrittura che renda sostanzialmente impossibile recuperare il
precedente contenuto del file (per i dettagli si consulti la pagina di
manuale con \texttt{man shred}).

Il comando \texttt{rm} prende come argomenti una lista di file da cancellare;
se si usa l'opzione \texttt{-i} il comando chiede di confermare la
cancellazione, mentre con l'opzione \texttt{-f} si annulla ogni precedente
\texttt{-i} ed inoltre non vengono stampati errori per file non esistenti.
Infine l'opzione \texttt{-R} (o \texttt{-r}) permette la cancellazione
ricorsiva di una directory e di tutto il suo contenuto, ed è pertanto da usare
con estrema attenzione, specie se abbinata con \texttt{-f}.\footnote{uno dei
  sistemi più efficaci per distruggere una installazione è un \texttt{rm -fR}
  eseguito come amministratore nel posto sbagliato, e anche se come utente non
  si può danneggiare il sistema, è comunque molto semplice spazzare via tutti
  i propri dati.}  La lista completa delle opzioni è riportata nella pagina di
manuale, accessibile con il comando \texttt{man rm}.

Come accennato la struttura di un filesystem unix-like comporta anche una
diversa concezione dell'operazione di spostamento dei file, che nel caso più
semplice è semplicemente equivalente a quella di cambiare il nome del file.
Il comando per compiere questa operazione infatti è unico e si chiama
\index{comando!\texttt{mv}} \texttt{mv}, il cui nome deriva da
\textit{\textbf{m}o\textbf{v}e file}.

Infatti fintanto che si ``\textsl{sposta}'' un file da una directory ad un
altra senza cambiare filesystem, non c'è nessuna necessità di spostare il
contenuto del file e basta semplicemente che sia creata una nuova voce per
l'\textit{inode} in questione rimuovendo al contempo la vecchia: esattamente
la stessa cosa che avviene quando gli si cambia nome (nel qual caso
l'operazione viene effettuata all'interno della stessa directory).  Qualora
invece si debba effettuare lo spostamento ad una directory su un filesystem
diverso diventa necessario prima copiare il contenuto e poi cancellare
l'originale (si ricordi infatti che in questo caso si avrà a che fare con un
\textit{inode} diverso, situato in un filesystem diverso).

Il comando \texttt{mv} ha due forme, può prendere cioè come argomenti o due
nomi di file o una lista di file seguita da una directory. Nel primo caso
rinomina il primo file nel secondo, cancellando quest'ultimo qualora esista
già, nel secondo caso sposta tutti i file della lista nella directory passata
come ultimo argomento, sempre cancellando eventuali file con lo stesso nome in
essa presenti. 

Dato che anche le directory sono file, il comando opera anche su queste usando
la stessa sintassi ma con qualche piccola differenza; se ad esempio si cerca
di rinominare una directory col nome di un file già presente si avrà un
errore, e se si cerca di rinominare una directory col nome di un'altra si
otterrà invece uno spostamento dentro quest'ultima. Le principali opzioni del
comando sono riportate in tab.~\ref{tab:file_mv_options}, l'elenco completo è
riportato nella pagina di manuale, accessibile con il comando \texttt{man mv}.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-i} & richiede conferma in caso di sovrascrittura.\\ 
    \texttt{-f} & forza la sovrascrittura del nuovo file se esso esiste
                  già.\\ 
    \texttt{-u} & esegue lo spostamento solo se la destinazione è più vecchia
                  della sorgente (o non esiste).\\
    \texttt{-b} & esegue un backup della destinazione se questa esiste già.\\
    \hline
  \end{tabular}
  \caption{Principali opzioni del comando \texttt{mv}.}
  \label{tab:file_mv_options}
\end{table}

Dato che il comando si limita a cambiare una voce associata ad un numero di
\textit{inode} all'interno di una directory, fintanto che lo spostamento
avviene all'interno dello stesso filesystem, i tempi dei file non vengono
modificati dall'uso di \texttt{mv}. Quando però lo spostamento avviene fra
filesystem diversi viene copiato il contenuto e cancellato il file originario,
pertanto in teoria dovrebbero risultare modificati anche i tempi di ultimo
accesso e modifica. In realtà il comando provvede a ripristinare questi tempi
(come le altre caratteristiche del file) al valore del file originario, ma non
può fare nulla per ripristinare il tempo di ultimo cambiamento.\footnote{il
  kernel fornisce delle \textit{system call} che permettono di cambiare i
  tempi di ultimo accesso e modifica di un file, che il comando \texttt{mv}
  può usare per ripristinare i tempi precedenti, ma non ne esistono per
  cambiare il tempo di ultimo cambiamento, che corrisponderà pertanto al
  momento in cui il nuovo file è stato creato; questa è una misura di
  sicurezza che permette sempre di verificare se un file è stato modificato,
  anche se si cerca di nascondere le modifiche.} Pertanto in quel caso si
potrà notare, usando \texttt{ls -lc}, che questo è cambiato e corrisponde al
momento dello spostamento.

\index{inode|)}

Qualora invece si voglia duplicare un file il comando da usare è
\index{comando!\texttt{cp}} \texttt{cp}, il cui nome deriva da
\textit{\textbf{c}o\textbf{p}y file}. Come per \texttt{mv} il comando può
prendere come argomenti o due nomi di file o una lista di file seguita da una
directory; nel primo caso effettua una copia del primo file sul secondo, nel
secondo copia tutti file della lista nella directory specificata.

Dato che il comando funziona copiando il contenuto di un file su un nuovo file
creato per l'occasione, i tempi di ultima modifica, accesso e cambiamento di
quest'ultimo corrisponderanno al momento in cui si è eseguita l'operazione.
Inoltre il file sarà creato con i permessi standard dell'utente che ha
lanciato il comando, che risulterà essere anche il suo proprietario. Se si
vogliono preservare invece le caratteristiche del file originale occorrerà
usare l'opzione \texttt{-p}.\footnote{però per poterlo fare in maniera
  completa, conservando il proprietario originale, per le ragioni che vedremo
  in sez.~\ref{sec:struct_file_perm_comm} occorre eseguire il comando come
  amministratore.}

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-f} & forza la sovrascrittura della destinazione se essa esiste
                  già.\\ 
    \texttt{-i} & richiede conferma in caso di sovrascrittura.\\ 
    \texttt{-p} & preserva tempi, permessi e proprietari del file.\\
    \texttt{-l} & crea degli \textit{hard link} al posto delle copie.\\ 
    \texttt{-s} & crea dei collegamenti simbolici al posto delle copie.\\
    \texttt{-d} & copia il link simbolico invece del file da esso indicato.\\
    \texttt{-r} & copia ricorsivamente tutto il contenuto di una directory.\\
    \texttt{-R} & identico a \texttt{-r}.\\
    \texttt{-a} & combina le opzioni \texttt{-dpR}.\\
    \texttt{-L} & segue sempre i collegamenti simbolici.\\
    \texttt{-b} & esegue un backup della destinazione se questa esiste già.\\
    \texttt{-u} & esegue la copia solo se la destinazione è più vecchia
                  della sorgente (o non esiste).\\
    \hline
  \end{tabular}
  \caption{Principali opzioni del comando \texttt{cp}.}
  \label{tab:file_cp_options}
\end{table}

Si tenga presente poi che nel caso di collegamenti simbolici il comando copia
il file indicato tramite il link,\footnote{questo comportamento non viene
  seguito in caso di copia ricorsiva, se lo si vuole abilitare occorre usare
  l'opzione \texttt{-L}.} se invece si vuole copiare il link stesso occorrerà
usare l'opzione \texttt{-d}. Il comando permette inoltre di creare degli
\textit{hard link} invece che delle copie usando l'opzione \texttt{-l}, e dei
collegamenti simbolici usando l'opzione \texttt{-s}. Una lista delle
principali opzioni è riportata in tab.~\ref{tab:file_cp_options}, l'elenco
completo è riportato nella pagina di manuale, accessibile attraverso il
comando \texttt{man cp}.

\itindbeg{pathname}

Fino ad ora nel descrivere gli argomenti da dare ai vari comandi che abbiamo
trattato, si è parlato dei nomi dei file o delle directory senza entrare
troppo nei dettagli su quale fosse il formato in cui questi vengono espressi.
Negli esempi infatti si sono specificati dei semplici nomi, ma questo dava per
scontati alcuni concetti che in realtà non lo sono affatto.

\index{directory~di~lavoro|(} 

La convenzione usata in tutti i sistemi unix-like è che i nomi dei file sono
indicati con un \textit{pathname} o \textsl{percorso}, che descrive il cammino
che occorre fare nell'albero dei file per raggiungere il file passando
attraverso le varie directory, dove i nomi delle directory sono separati fra
loro da delle barre (il carattere ``\texttt{/}'').

Il percorso può essere indicato (vedi tab.~\ref{tab:pathnames}) in maniera
assoluta, cioè partendo dalla directory radice (torneremo sulla struttura
dell'albero dei file e sul concetto di radice in sez.~\ref{sec:file_FHS}) ed
indicando tutte le directory che si devono attraversare, o in maniera
relativa, partendo dalla cosiddetta \textsl{directory di lavoro corrente}. Nel
primo caso il \textit{pathname} inizierà con una ``\texttt{/}'', mentre nel
secondo no.

\begin{table}[htb]
  \footnotesize
  \centering
  \begin{tabular}{|l|l|}
    \hline
    \multicolumn{1}{|c|}{\textbf{Esempio}}&\textbf{Formato}\\
    \hline
    \hline
    \texttt{/home/piccardi/GaPiL/GaPiL.tex} & assoluto \\
    \texttt{GaPiL/GaPiL.tex} & relativo \\
    \hline
  \end{tabular}
  \caption{Formato dei \textit{pathname} assoluti e relativi.}
  \label{tab:pathnames}
\end{table}

Finora, specificando solo dei nomi semplici, abbiamo sempre fatto l'assunto di
operare appunto nella \textsl{directory di lavoro corrente}.  Questa directory
è una proprietà specifica di ogni processo, che viene ereditata dal padre alla
sua creazione (questo argomento è trattato in
sez.~\ref{sec:struct_proc_property}) ed indica appunto la directory a partire
dalla quale vengono risolti, per quel processo, i \textit{pathname}
relativi. Questo vuol dire che si possono indicare i file presenti in quella
directory direttamente, senza doverne specificare il \textit{pathname}
completo a partire dalla radice.

Quando si entra nel sistema la directory di lavoro corrisponde alla cosiddetta
\textit{home} dell'utente. Tradizionalmente infatti ogni utente del sistema ha
una sua directory personale nella quale può tenere i propri file, che viene
chiamata appunto ``\textsl{casa}'' e quando entra nel sistema viene
posizionato in tale directory; ritorneremo sull'argomento più avanti in
sez.~\ref{sec:file_FHS}.

La directory di lavoro può essere cambiata con il comando
\index{comando!built-in!\texttt{cd}} \texttt{cd} (il cui nome deriva
\textit{\textbf{c}hange \textbf{d}irectory}) seguito dal \textit{pathname}
della directory in cui ci si vuole spostare. Per sapere quale è la si può
stampare a video con il comando \index{comando!\texttt{pwd}} \texttt{pwd}, il
cui nome deriva da \textit{\textbf{p}rint \textbf{w}ork \textbf{d}irectory}.

Si tenga presente poi che ciascuna directory contiene sempre almeno due voci:
la directory ``\texttt{.}'' che fa riferimento a se stessa, e che usata
all'inizio di un \textit{pathname} indica la directory di lavoro corrente, e
la directory ``\texttt{..}'', che fa riferimento alla directory in cui
l'attuale è contenuta, e che all'inizio di un \textit{pathname} indica la
directory sovrastante quella corrente. In questo modo, anche con dei
\textit{pathname} relativi, si possono fare riferimenti a directory poste in
sezioni diverse dell'albero dei file, risalendo lo stesso con l'uso della
directory ``\texttt{..}'' che permette di arrivare fino alla radice
dell'albero dei file.\footnote{per la quale la directory ``\texttt{..}'' fa
  riferimento a se stessa, non essendovi niente al di sopra.} Si noti anche
come entrambe queste due voci, dato che iniziano per ``\texttt{.}''  siano
``\textsl{invisibili}''.

Inoltre, come vedremo meglio in sez.~\ref{sec:shell_sintax}, la shell quando
deve passare dei \textit{pathname} ai comandi che operano su file e directory
(come \texttt{cd}, \texttt{cp}, ecc.) riconosce alcuni caratteri speciali, ad
esempio il carattere ``\texttt{\tild}'' viene usato per indicare la home
dell'utente corrente, mentre con \texttt{\tild username} si indica la home
dell'utente \texttt{username}; \texttt{cd} riconosce inoltre come argomento il
carattere ``\texttt{-}'' che viene utilizzato per richiedere il ritorno alla
precedente directory di lavoro.

\index{directory~di~lavoro|)} 
\itindend{pathname}

Come accennato nella sezione precedente anche le directory sono dei file,
anche se vengono trattate dal kernel come file speciali il cui compito è
quello di contenere elenchi di nomi di altri file.  Per la creazione di una
directory è previsto un comando apposito, \index{comando!\texttt{mkdir}}
\texttt{mkdir}. Questo è necessario perché alla creazione della directory
devono essere create al suo interno anche le directory ``\texttt{.}'' e
``\texttt{..}'', che sono sempre presenti.\footnote{è compito della omonima
  \textit{system call} che effettua la creazione di una nuova directory far sì
  che esse siano sempre presenti.}

Il comando \texttt{mkdir} crea la o le directory passate come argomento;
queste dovranno essere specificate con quello che sarà il loro
\textit{pathname}, sia in forma assoluta o relativa.  Perché il comando abbia
successo ovviamente la parte di percorso che deve contenere la directory che
si vuole creare deve esistere, se non è così si può forzare la creazione di
tutte le directory indicate nel percorso specificato con l'opzione
\texttt{-p}, se ne possono anche impostare i permessi iniziali (torneremo su
questo argomento in sez.~\ref{sec:struct_file_perm_comm}) con l'opzione
\texttt{-m}.

Come per la creazione, è necessario un apposito comando,
\index{comando!\texttt{rmdir}} \texttt{rmdir}, anche per la rimozione di una
directory, dato che \texttt{rm}, a meno di non usare l'opzione \texttt{-R} che
però cancella anche tutto il contenuto, rimuove solo i file. Di nuovo il
comando prende il nome di una o più directory vuote da cancellare. Se le
directory non sono vuote, dove vuote significa che non ci deve essere niente a
parte le due directory ``\texttt{.}'' e ``\texttt{..}'' il comando fallisce.
Anche in questo caso si può usare l'opzione \texttt{-p} che cancella tutto un
percorso di directory (che comunque devono essere tutte vuote).


\subsection{L'albero dei file ed il \textit{Filesystem
    Hierarchy Standard}}
\label{sec:file_FHS}

\index{directory~radice|(} 

Una delle caratteristiche peculiari di un sistema unix-like è che l'albero
delle directory è unico; non esistono cioè i vari dischi (o volumi) che si
possono trovare in altri sistemi, come su Windows, sul MacOS o sul VMS.
All'avvio il kernel \textsl{monta}\footnote{come accennato l'operazione che
  rende visibili ai processi i file contenuti all'interno di un filesystem
  facendoli comparire all'interno nell'albero dei file viene chiamata
  \textsl{montaggio} del filesystem, torneremo sull'argomento in
  sez.~\ref{sec:file_disk_management}.} quella che si chiama la
\textsl{directory radice} (o \textit{root directory}) dell'albero, che viene
indicata con ``\texttt{/}'', tutti i restanti dischi, il CDROM e qualunque
altro dispositivo contenente file, verranno poi \textsl{montati} (vedi
sez.~\ref{sec:file_disk_management}) successivamente in opportune
sotto-directory della radice.

Come per il processo iniziale \texttt{init}, che non è figlio di nessun altro
processo e viene lanciato direttamente dal kernel, anche la directory radice
non è contenuta in nessuna altra directory e, come accennato in
sez.~\ref{sec:struct_base}, viene montata direttamente dal kernel in fase di
avvio. Per questo motivo la directory radice viene ad assumere un ruolo
particolare, ed il filesystem che la supporta deve contenere tutti i programmi
di sistema necessari all'avvio, compreso \texttt{init} o eventuali sostituti.

Un esempio di questa struttura ad albero, che al contempo ci mostra anche i
contenuti delle directory principali, può essere ottenuto con il comando
\index{comando!\texttt{tree}} \texttt{tree}. Se chiamato senza parametri
questo comando mostra l'albero completo a partire dalla directory corrente,
scendendo in tutte le directory sottostanti; usando l'opzione \texttt{-L} si
può specificare il numero massimo di livelli a cui scendere, per cui andando
su \texttt{/} avremo qualcosa del tipo:
\begin{Console}
piccardi@hain:~$ \textbf{tree --charset=ASCII -L 2 /}
/
|-- bin
|   |-- bash
...
|-- boot
|   |-- config-3.2.0-1-amd64
...
|-- dev
|   |-- autofs
...
|-- etc
|   |-- acpi
...
|-- home
|   `-- piccardi
|-- lib
|   |-- discover
...
|-- lib32
|   |-- ld-2.13.so
...
|-- lost+found 
|-- media
|-- mnt
|-- opt
|-- proc
|   |-- 1
...
|-- root 
|-- run
|   |-- atd.pid
...
|-- sbin
|   |-- acpi_available
...
|-- selinux
|-- srv
|-- sys
|   |-- block
...
|-- tmp
|   |-- ssh-LjWlESaD8958
...
|-- usr
|   |-- bin
|   |-- games
|   |-- include
|   |-- lib
|   |-- lib32
|   |-- local
|   |-- sbin
|   |-- share
|   `-- src
|-- var
|   |-- backups
|   |-- cache
|   |-- games
|   |-- lib
|   |-- local
|   |-- lock -> /run/lock
|   |-- log
|   |-- mail
|   |-- opt
|   |-- run -> /run
|   |-- spool
|   `-- tmp
`-- vmlinuz -> boot/vmlinuz-3.2.0-1-amd64
\end{Console}
%$
e questo ci mostra il contenuto sommario dei primi due livelli dell'albero,
con un esempio dei file e delle sottodirectory presenti in una versione di
Debian (Wheezy).

\itindbeg{Filesystem~Hierarchy~Standard (FHS)} 

L'organizzazione dell'albero delle directory è standardizzata in maniera molto
accurata da un documento che si chiama \textit{Filesystem Hierarchy Standard}
(abbreviato in FHS), preso come riferimento da tutte le
distribuzioni.\footnote{al momento dell'ultima revisione di questo testo
  (Febbraio 2013) la versione corrente è la 2.3, rilasciata nel 2004 e parte
  delle specifiche LSB (\textit{Linux Standard Base}), ma è in corso di
  definizione la versione 3.0, con varie novità come \texttt{/run} già
  adottate dalla gran parte delle distribuzioni.} Lo standard descrive in
dettaglio la struttura dell'albero delle directory e il relativo contenuto,
prevedendo una divisione molto rigorosa che permette una notevole uniformità
anche fra distribuzioni diverse; si organizzano così in maniera meticolosa ed
ordinata dati, programmi, file di configurazione, documentazione, file degli
utenti, ecc.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|l|}
    \hline
    \multicolumn{1}{|c|}{\textbf{Directory}}&\textbf{Contenuto}\\
    \hline
    \hline
    \texttt{/bin}  & comandi essenziali.\\
    \texttt{/boot} & file statici necessari al \textit{bootloader}.\\ 
    \texttt{/dev}  & file di dispositivo.\\
    \texttt{/etc}  & file di configurazione della macchina.\\
    \texttt{/lib}  & librerie essenziali e moduli del kernel. \\
    \texttt{/media}& \textit{mount point} per dispositivi rimovibili. \\
    \texttt{/mnt}  & \textit{mount point} montaggi temporanei. \\
    \texttt{/opt}  & pacchetti software addizionali. \\
    \texttt{/run}  & dati di \textit{run-time} volatili. \\
    \texttt{/sbin} & comandi di sistema essenziali.\\
    \texttt{/srv}  & dati per i servizi forniti dal sistema.\\
    \texttt{/tmp}  & file temporanei.\\
    \texttt{/usr}  & gerarchia secondaria.\\
    \texttt{/var}  & dati variabili.\\
    \hline
  \end{tabular}
  \caption{Sottodirectory di \texttt{/} obbligatorie per qualunque sistema.}
  \label{tab:FHS_mand}
\end{table}

In particolare le directory vengono suddivise sulla base di alcuni criteri
fondamentali. Il primo è quello della possibilità di contenere file il cui
contenuto può essere modificato (nel qual caso il filesystem che le contiene
deve essere montato in lettura/scrittura) o meno (nel qual caso il filesystem
può essere montato in sola lettura).

Il secondo è quello della possibilità di contenere file come i programmi di
sistema che possono essere condivisi (ad esempio utilizzando un filesystem di
rete) fra più stazioni di lavoro o file che invece sono locali e specifici
alla macchina in questione.

Il terzo criterio è quello di contenere o meno comandi o file (configurazioni
e file di dispositivo) che sono necessari all'avvio del sistema, e che
pertanto devono essere situati sul filesystem usato per la directory radice,
dato che essi non sarebbero disponibili se posti in filesystem diversi che
possono essere montati solo dopo che il sistema è partito.

Lo standard prevede che debbano essere necessariamente presenti le
sottodirectory di \texttt{/} specificate in tab.~\ref{tab:FHS_mand}, mentre
quelle di tab.~\ref{tab:FHS_opt} sono obbligatorie soltanto qualora si siano
installati i sottosistemi a cui essi fanno riferimento (utenti, \texttt{/proc}
filesystem, diversi formati binari).\footnote{le eventuali \texttt{/lib<qual>}
  contengono le versioni delle librerie di sistema in formati binari diversi;
  le \texttt{/lib} alternative sono state usate al tempo della transizione dei
  programmi dal formato \textsl{a.out} ad \textsl{ELF}, oggi sono usate
  principalmente per quei sistemi (come gli AMD-64) che supportano diversi
  formati binari (32 o 64 bit).}

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}{|l|p{6cm}|}
    \hline
    \multicolumn{1}{|c|}{\textbf{Directory}}&\textbf{Contenuto}\\
    \hline
    \hline
    \texttt{/lib<qual>}  & librerie in formati alternativi.\\
    \texttt{/home} & home directory degli utenti.\\
    \texttt{/root} & home directory dell'amministratore.\\
    \texttt{/proc} & filesystem virtuale con informazioni su processi e
                     caratteristiche del sistema. \\
    \texttt{/sys} &  filesystem virtuale con informazioni su driver e
                     dispositivi (vedi sez.~\ref{sec:udev_hotplug}).\\
    \hline
  \end{tabular}
  \caption{Sottodirectory di \texttt{/} obbligatorie solo in presenza dei
    relativi sottosistemi.}
  \label{tab:FHS_opt}
\end{table}

Un elenco delle specifiche delle caratteristiche e del contenuto di ciascuna
delle sottodirectory di \texttt{/} è riportato di seguito; per alcune di esse,
come \texttt{/usr} e \texttt{/var}, sono previste delle ulteriori
sotto-gerarchie che definiscono ulteriori dettagli dell'organizzazione dei
file. Si è aggiunto all'elenco anche la directory \texttt{/run}, che pur non
essendo prevista dal FHS è stata adottata da tutte le distribuzioni più
recenti. 
\begin{basedescript}{\desclabelwidth{1.3cm}\desclabelstyle{\nextlinelabel}}
\item[\texttt{/bin}] Contiene i comandi essenziali del sistema (usati sia
  dall'amministratore che dagli utenti, come \texttt{ls}), che devono essere
  disponibili anche quando non ci sono altri filesystem montati oltre la
  radice, ad esempio all'avvio o quando si è in \textit{single user mode}
  (vedi sez.~\ref{sec:struct_sysv_init}). Non deve avere sottodirectory e non
  può stare su un filesystem diverso da quello della radice.
\item[\texttt{/boot}] Contiene tutti i file necessari al procedimento di boot
  (immagini del kernel, del \textit{bootloader}, \textit{ramdisk}, ecc.)
  eccetto i file di configurazione ed i programmi per l'impostazione del
  procedimento stesso, che vanno in \texttt{/sbin}. Può stare su qualunque
  filesystem purché visibile dal \textit{bootloader} (vedi
  sez.~\ref{sec:struct_kernel_boot}).
\item[\texttt{/dev}] Contiene i file di dispositivo, che permettono l'accesso
  alle periferiche. Originariamente doveva stare sullo stesso filesystem della
  radice, dato che i file di dispositivo sono necessari alla procedura di
  avvio. Oggi il contenuto è nella maggior parte dei casi generato
  dinamicamente ed è montata su un \index{filesystem~temporaneo} filesystem
  temporaneo\footnote{si intende con questo un filesystem di tipo
    \texttt{tmpfs} (vedi tab.~\ref{tab:file_filesystem_types}) il cui
    contenuto è mantenuto in memoria.} che viene popolato in fase di avvio
  tramite \texttt{udev} (vedi sez.~\ref{sec:udev_hotplug}).

% materiale vecchio
  % a meno che non si sia
  % installato nel kernel il supporto per il \texttt{devfs},\footnote{ormai
  %   deprecato, assente nei kernel recenti, ed in via di sparizione.} che
  % permette di trasferire il contenuto di questa directory su un apposito
  % filesystem virtuale, o si stia usando (come avviene in tutte le
  % distribuzioni più recenti) la creazione dinamica del contenuto della
  % directory in fase di avvio tramite \texttt{udev} (vedi
  % sez.~\ref{sec:udev_hotplug}), nel qual caso essa viene in genere rimontata
  % su un filesystem virtuale.\footnote{deve comunque essere presente una
  %   versione statica minimale, usata per le fasi iniziali dell'avvio del
  %   sistema, che in genere viene rimontata alla partenza di
  %   \texttt{udev} sotto \texttt{/dev/.static/dev}.}

\item[\texttt{/etc}] Contiene i file di configurazione del sistema e gli
  script\footnote{gli \textit{script}, su cui torneremo in
    sez.~\ref{sec:shell_scripting}, sono un po' gli equivalenti in ambito Unix
    (come potrebbe esserlo una Ferrari in confronto ad una 500) dei file
    \texttt{.bat} del DOS, una lista di comandi messi in un file (in realtà si
    tratta di un vero linguaggio di programmazione) e fatti eseguire
    automaticamente.} di avvio.  Non deve contenere programmi binari e non può
  stare su un filesystem diverso da quello della radice.  I file possono
  essere raggruppati a loro volta in directory; lo standard prevede solo che,
  qualora siano installati, siano presenti le directory \texttt{/etc/opt} (per
  i pacchetti opzionali), \texttt{/etc/X11} (per la configurazione di
  \textit{X Window}, vedi sez.~\ref{sec:cfg_Xwindow}) e \texttt{/etc/sgml} e
  \texttt{/etc/xml} (per la configurazione di SGML e XML).
\item[\texttt{/home}] Contiene le \textit{home directory} degli utenti, la
  sola parte del filesystem (eccetto \texttt{/tmp} e \texttt{/var/tmp}) su cui
  gli utenti hanno diritto di scrittura, che viene usata per mantenere i loro
  file personali. Può essere montata su qualunque filesystem.
\item[\texttt{/lib}] Contiene le librerie condivise essenziali, usate dai
  programmi di \texttt{/bin} e \texttt{/sbin}, e deve essere sullo stesso
  filesystem della radice. Qualora sia stato installato un kernel modulare
  (vedi sez.~\ref{sec:kernel_modules}) i moduli devono essere installati
  in \texttt{/lib/modules}.
\item[\texttt{/media}] Contiene i \textit{mount point} (vedi
  sez.~\ref{sec:file_disk_management}) per i dispositivi rimovibili, come
  CDROM, floppy, chiavette USB, dischi USB o Firewire, ecc. Nelle
  distribuzioni meno recenti i floppy ed i CDROM hanno delle directory
  dedicate, ma con l'introduzione di meccanismi di rilevazione automatica dei
  dispositivi rimovibili (vedi sez.~\ref{sec:udev_hotplug}) è stata definita
  questa directory all'interno della quale vengono create le opportune
  sotto-directory su cui poi essi vengono montati un maniera automatica.
\item[\texttt{/mnt}] Contiene i \textit{mount point} (vedi
  sez.~\ref{sec:file_disk_management}) per i montaggi temporanei ad uso
  dell'amministratore di sistema; i filesystem di periferiche permanenti con
  supporti rimovibili come i floppy o il CDROM che prima venivano tenuti sia
  in questa directory che direttamente sotto \texttt{/} devono essere spostati
  sotto \texttt{/media}.  Normalmente è vuota e deve essere creata
  direttamente sotto la radice.
\item[\texttt{/opt}] Contiene eventuali pacchetti software aggiuntivi. Può
  essere su qualunque filesystem. Un pacchetto deve installarsi nella
  directory \texttt{/opt/package} dove \textit{package} è il nome del
  pacchetto. All'amministratore è riservato l'uso di alcune directory
  opzionali: \texttt{/opt/bin}, \texttt{/opt/doc}, \texttt{/opt/include},
  \texttt{/opt/info}, \texttt{/opt/lib} e \texttt{/opt/man}. File variabili
  attinenti ai suddetti pacchetti devono essere installati in
  \texttt{/var/opt} ed i file di configurazione in \texttt{/etc/opt}, nessun
  file attinente ai pacchetti deve essere installato al di fuori di queste
  directory.
\item[\texttt{/proc}] È il \textit{mount point} standard del filesystem
  virtuale \texttt{proc}. Questo è un filesystem speciale che permette di
  accedere a tutta una serie di variabili interne al kernel (relative a
  parametri e impostazioni di tutti tipi) con l'interfaccia dei file. Così se
  si vogliono informazioni sugli interrupt ed i canali di DMA (vedi
  sez.~\ref{sec:expansions_interface}) utilizzati dal sistema si potranno
  leggere i file \texttt{/proc/interrupts} e \texttt{/proc/dma}, mentre si
  potranno impostare varie caratteristiche del sistema scrivendo nei file
  sotto \texttt{/proc/sys} (vedi sez.~\ref{sec:sysctl_conf}).
\item[\texttt{/root}] È la \textit{home directory} dell'amministratore. Di
  norma la si mantiene nello stesso filesystem della radice; il suo uso è
  opzionale ma questa è la collocazione consigliata.
\item[\texttt{/run}] Presente solo nelle distribuzioni più recenti, viene
  utilizzata per mettere a disposizione fin dall'avvio una directory su cui
  viene montato un filesystem temporaneo e su cui sono mantenuti i cosiddetti
  dati di \textit{run-time} volatili (come i file che registrano i PID dei
  programmi di servizio, i file di lock ed altri file il cui utilizzo attiene
  principalmente all'esecuzione di programmi) di cui non serve il mantenimento
  attraverso un riavvio. La directory consente di avere un posto dove anche i
  programmi lanciati all'avvio possono mantenere i loro dati, dato che in
  generale \texttt{/var/run} e \texttt{/var/lock} possono non essere
  disponibili quando \texttt{/var} viene mantenuta su un filesystem
  separato. Consente anche di unificare in un'unica directory e su un unico
  filesystem temporaneo tutti questi dati, dato che se viene utilizzata il
  contenuto di \texttt{/var/run} e \texttt{/var/lock} viene riportato al suo
  interno.
\item[\texttt{/sbin}] Contiene i programmi essenziali ad uso
  dell'amministratore del sistema (come \texttt{init} o \texttt{fsck}). Deve
  stare sullo stesso filesystem della radice. Vanno messi in questa directory
  solo i programmi essenziali per l'avvio del sistema, il recupero e la
  manutenzione dei filesystem.
\item[\texttt{/srv}] È stata introdotta per mantenervi i dati relativi ai vari
  servizi che possono essere stati installati su una macchina (come ad esempio
  le pagine servite da un web server) che in precedenza venivano installati
  direttamente sotto \texttt{/var}.\footnote{è stata introdotta con la
    versione 2.3 del FHS, ma il suo uso non si è molto diffuso.} Non ne è
  definita una ulteriore suddivisione, ma in genere si tende a creare una
  sottodirectory per ciascun servizio (ad esempio \texttt{www}, \texttt{svn},
  ecc.).
\item[\texttt{/tmp}] La directory viene usata per mantenere file temporanei.
  Viene cancellata ad ogni riavvio, ed i programmi non devono assumere che i
  file siano mantenuti fra due esecuzioni successive. 
\item[\texttt{/usr}] È la directory principale che contiene tutti i programmi,
  i file ed i dati non variabili, che possono anche essere condivisi fra più
  stazioni di lavoro.  Può essere montata su un filesystem separato rispetto a
  \texttt{/} e può essere montata in sola lettura, anche se questa scelta
  potrebbe rendere problematico l'uso di alcuni ambienti. Prevede una ulteriore
  gerarchia di directory in cui i vari file vengono organizzati; lo standard
  richiede obbligatoriamente le seguenti:
  \begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
  \item[\texttt{bin}] contiene i programmi usati dall'utente installati
    direttamente dal sistema (o dalla distribuzione originale). Non può essere
    ulteriormente suddivisa;
  \item[\texttt{include}] contiene tutti i file di dichiarazione delle
    funzioni di libreria usati dal compilatore e dai programmi C e C++;
  \item[\texttt{lib}] contiene le librerie, file oggetto e binari relativi ai
    programmi di \texttt{bin} e \texttt{sbin}. Può contenere sottodirectory
    con tutti i file relativi a singoli programmi;
  \item[\texttt{local}] contiene una replica della gerarchia di \texttt{/usr}
    dedicata ai file installati localmente dall'amministratore. In genere qui
    vengono installati i programmi compilati dai sorgenti e tutto quello che
    non fa parte della distribuzione ufficiale;
  \item[\texttt{sbin}] contiene i programmi per la gestione di sistema ad uso
    dell'amministratore non essenziali all'avvio;
  \item[\texttt{share}] contiene una gerarchia in cui sono organizzati tutti i
    file e i dati che non dipendono dall'architettura hardware: sono sempre
    obbligatori \texttt{man} per le pagine di manuale, e \texttt{misc}; se
    installati vi si possono trovare anche una serie di altre directory come:
    \texttt{dict} per i dizionari, \texttt{doc} per la documentazione,
    \texttt{games} per i dati statici dei giochi, \texttt{info} per i file del
    relativo sistema di help (vedi sez.~\ref{sec:documentazione}),
    \texttt{terminfo} per il database con le informazioni sui terminali,
    \texttt{zoneinfo} per i dati relativi ai fusi orari (per l'elenco completo
    si consulti il sito citato). Deve essere posto dentro \texttt{misc} tutto
    quello che non viene classificato nelle altre directory opzionali;
  \end{basedescript}
  mentre sono obbligatorie solo se i relativi pacchetti sono installati, le
  seguenti directory:
  \begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
  \item[\texttt{X11R6}] conteneva la gerarchia dei file relativi ad \textit{X
      Window} (vedi sez.~\ref{sec:cfg_Xwindow}), dalla versione 7.0 di
    \textit{X.org} è stata rimossa;
  \item[\texttt{games}] contiene i binari dei giochi;
  \item[\texttt{src}] contiene i sorgenti dei pacchetti, per riferimenti, ed
    è opzionale;
  \end{basedescript}
\item[\texttt{/var}] Contiene i file variabili: le directory di spool, i file
  di log, i dati transienti e temporanei, in modo che \texttt{/usr} possa
  essere montata in sola lettura. È preferibile montarla in un filesystem
  separato; alcune directory non possono essere condivise.  Anche in questo
  caso i file sono organizzati in una ulteriore gerarchia standardizzata che
  prevede la presenza delle seguenti sottodirectory:
  \begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}}
  \item[\texttt{cache}] dati di appoggio e memorizzazione temporanea per le
    applicazioni;
  \item[\texttt{lib}] informazioni di stato e dati delle applicazioni;
  \item[\texttt{local}] dati variabili relativi ai pacchetti di
    \texttt{/usr/local};
  \item[\texttt{lock}] file di lock, se si usa \texttt{/run} è un collegamento
    simbolico a \texttt{/run/lock};
  \item[\texttt{log}] file di log delle applicazioni (vedi
    \ref{sec:syslog.conf});
  \item[\texttt{opt}] file variabili per i pacchetti di \texttt{/opt};
  \item[\texttt{spool}] directory per le code contenenti i dati in transito
    delle applicazioni (lavori di stampa, posta elettronica, ecc.);
  \item[\texttt{tmp}] file temporanei non cancellati al riavvio del sistema;
  \end{basedescript}
  a queste si aggiungono tradizionalmente altre directory, come
  \texttt{/var/backups}, \texttt{/var/cron}, ecc. non indicate dallo standard.
\end{basedescript}

In fig.~\ref{fig:file_hier} è riportata una rappresentazione grafica della
struttura generale delle directory prevista dal FHS, anche se si è mostrata
solo una parte delle directory previste. I dettagli completi sulla struttura,
così come le specifiche relative ad i contenuti delle varie directory, possono
essere reperiti sul documento ufficiale di definizione del FHS, disponibile
all'indirizzo \url{http://www.pathname.com/fhs/}.

\begin{figure}[htb]
  \centering \includegraphics[width=12cm]{images/file_hyer}
  \caption{Struttura tipica delle directory, secondo il \textit{Filesystem
    Hierarchy Standard}.}
  \label{fig:file_hier}
\end{figure}

L'importanza del \textit{Filesystem Hierarchy Standard} diventa evidente
quando si vanno ad esaminare le strategie di partizionamento dei dischi
(torneremo sull'argomento in sez.~\ref{sec:partitioning}). In tal caso infatti
occorrerà stabilire quali directory dovranno restare sul filesystem usato come
radice, e quali altre directory si potranno disporre su altre partizioni o
altri dischi.

È evidente infatti che alcune directory (come \texttt{/usr} ed \texttt{/opt})
possono essere mantenute su partizioni e filesystem diversi rispetto alla
directory radice. Può risultare pertanto utile separare queste due directory
che, contenendo file comuni di norma identici per le diverse installazioni,
possono essere montate in sola lettura e non inserite nei backup (in quanto è
possibile sempre ripristinarle dall'installazione), o addirittura montate via
rete e condivise fra più macchine.

La situazione è invece del tutto diversa per directory come \texttt{/home} e
\texttt{/var}. Anche in questo caso può risultare utile separarle dalle altre
directory, ma in questo caso è necessario l'accesso in scrittura e le
informazioni variabili non saranno necessariamente condivisibili (ad esempio
non lo sono \texttt{/var/run} e \texttt{/var/lock} che contengono informazioni
sui processi locali). Inoltre essendo qui contenuti la gran parte dei dati del
sistema (le altre directory sono solo \texttt{/root} per i file personali
dell'amministratore e \texttt{/etc} per le configurazioni) queste dovranno
essere sottoposte a regolare backup.

Si tenga inoltre presente che alcune di queste directory (ad esempio
\texttt{/proc}) devono essere lasciate vuote sul disco; esse infatti servono
solo come riferimento per montare i relativi filesystem virtuali. Non ha
quindi alcun senso effettuare backup del contenuto di queste directory in
quanto esse presentano solo una interfaccia di accesso (che permette però
l'uso dei normali comandi per i file) a variabili interne del kernel create
dinamicamente.

\itindend{Filesystem~Hierarchy~Standard (FHS)} 

\index{directory~radice|)}


\section{L'architettura dei processi}
\label{sec:struct_process}

In questa sezione prenderemo in esame l'architettura della gestione dei
processi, che costituiscono le entità fondamentali con cui il kernel permette
l'esecuzione dei vari programmi. Vedremo come i processi sono organizzati in
forma gerarchica, quali sono caratteristiche e proprietà che ciascuno di essi
porta con sé, e come vengono gestiti all'interno del sistema.


\subsection{Le caratteristiche dell'architettura dei processi}
\label{sec:struct_proc_architecture}

Come accennato in sez.~\ref{sec:struct_sys_arch} una delle caratteristiche
principali dell'architettura dei processi in un sistema unix-like è che
qualunque processo può creare nuovi processi; in questo contesto il processo
originale viene chiamato \textsl{padre}, mentre i processi da lui creati
vengono detti \textsl{figli}.  La caratteristica distintiva è che tutti i
processi presenti nel sistema possono essere creati solo in questo modo, e
pertanto tutti i processi avranno un padre; l'unica eccezione è quella di
\texttt{init}, il processo iniziale che, venendo lanciato direttamente dal
kernel all'avvio, non è figlio di nessun altro processo.

Questa caratteristica permette di classificare i processi in una gerarchia ad
albero basata sulla relazione padre-figlio; in questa gerarchia \texttt{init}
viene a ricoprire nel sistema un ruolo speciale, come radice dell'albero.
Questa classificazione può essere stampata con il comando
\index{comando!\texttt{pstree}} \texttt{pstree} che evidenzia in maniera
grafica l'\textsl{albero genealogico} dei processi presenti nel sistema, con
un risultato del tipo:
\begin{Console}
piccardi@anarres:~$ \textbf{pstree -A}
init-+-acpid
     |-atd
     |-cron
     |-dhclient
     |-exim4
     |-5*[getty]
     |-login---bash
     |-portmap
     |-rpc.statd
     |-rsyslogd---3*[{rsyslogd}]
     |-sshd---sshd---sshd---bash---pstree
     `-udevd---2*[udevd]
\end{Console}
%$
dove si può notare che, come dicevamo all'inizio, alla radice dell'albero c'è
\texttt{init}.

Si tenga presente che questa architettura, in cui qualunque processo può
creare degli altri processi, è molto diversa da quella di altri sistemi
operativi in cui spesso l'operazione di lanciare un nuovo processo è
privilegiata e non può essere eseguita da un programma qualsiasi.

Nella creazione di un processo figlio questo eredita dal padre tutta una serie
di proprietà (vedremo alcune di esse in sez.~\ref{sec:struct_proc_property}) e
risorse,\footnote{la trattazione dettagliata del meccanismo e di quali
  proprietà e risorse vengono trasmesse da padre a figlio va al di là dello
  scopo di questo testo, gli interessati possono consultare il capitolo 3 di
  \cite{GaPiL}.} ed in particolare una delle caratteristiche che
contraddistingue l'architettura dei processi in un sistema unix-like è che
tutti i file aperti nel processo padre resteranno tali ed immediatamente
disponibili anche per il figlio;\footnote{di nuovo si sta facendo una
  descrizione estremamente vaga e semplificata, in realtà il meccanismo con
  cui un processo figlio ``\textsl{vede}'' i file aperti dal padre è piuttosto
  complesso, una trattazione dettagliata si può trovare in sez.~5.2.1 di
  \cite{GaPiL}.} vedremo in sez.~\ref{sec:shell_IO_redirect} come questo sia
fondamentale per una delle funzionalità più importanti dell'interfaccia a riga
di comando.

Una seconda differenza rispetto ad altri sistemi multiutente come il VMS o
Windows, è che in Linux la creazione di un processo e l'esecuzione di un
programma sono due operazioni separate, gestite da due \textit{system call}
diverse,\footnote{le due funzioni si chiamano rispettivamente \texttt{fork} ed
  \texttt{exec}, per i dettagli del meccanismo si può consultare la sezione
  3.1 di \cite{GaPiL}.} la prima delle quali crea un nuovo processo, identico
al padre, il quale normalmente va ad usare la seconda per eseguire un altro
programma.\footnote{è questa la modalità con cui funziona l'interfaccia a riga
  di comando in cui un programma, la shell, crea dei processi figli per
  eseguire tramite essi gli altri programmi.}

Questa caratteristica permette anche, con una modalità di funzionamento comune
per i server di rete, di scrivere un programma unico che esegue più processi,
con una struttura in cui il padre esegue la parte che si occupa di ricevere le
richieste, e per ciascuna di esse fa eseguire, ad un figlio creato
appositamente, le operazioni necessarie a fornire le relative risposte.


\subsection{Le proprietà dei processi}
\label{sec:struct_proc_property}

Il comando che permette di ottenere la lista dei processi attivi nel sistema è
\index{comando!\texttt{ps}} \texttt{ps}, il cui nome deriva da
\textit{\textbf{p}rocess \textbf{s}tatus}. Questo è uno dei comandi
fondamentali presenti fin dalle prime versioni di Unix, per questo si sono
accavallate anche diverse sintassi per le opzioni, derivate dalle varie
versioni del comando che sono state realizzate nel tempo.  La versione GNU del
comando supporta la maggior parte delle opzioni esistenti, in genere indicate
da lettere singole: quelle derivate da SysV devono essere precedute da un
``\texttt{-}'', quelle derivate da BSD \textsl{non} devono essere precedute da
un ``\texttt{-}'', mentre le estensioni specifiche GNU usano un
``\texttt{-{}-}'' ed una forma estesa.

Si tenga presente che in molti casi viene usata la stessa lettera, con
significati diversi, sia nel formato BSD che in quello SysV, nel caso si
vogliano combinare le due opzioni di questi formati alternativi allora non
vale la sintassi usuale (che tratteremo in dettaglio in
sez.~\ref{sec:shell_sintax}) di specificare più opzioni con lettere
consecutive dopo il ``\texttt{-}'', e ciascuna andrà ripetuta a parte.

Il comando non richiede nessun argomento, e se eseguito su un terminale senza
specificare nessuna opzione \texttt{ps} mostra l'elenco dei processi
appartenenti all'utente che ha eseguito il comando attivi su quel terminale;
avremo cioè qualcosa del tipo:
\begin{Console}
piccardi@hain:~/truedoc/corso$ \textbf{ps}
  PID TTY          TIME CMD
10511 pts/2    00:00:00 bash
22461 pts/2    00:00:22 emacs
22746 pts/2    00:00:03 evince
22971 pts/2    00:00:00 ps
\end{Console}
%$
che mostra, nell'ultima colonna marcata \texttt{CMD}, come sul terminale siano
presenti la shell, il comando \texttt{ps} stesso, più l'editor ed il
visualizzatore di PDF utilizzati per la realizzazione di questo testo.
Tralasciamo per ora il significato delle altre colonne, ci torneremo fra poco.

Specificando l'opzione ``\texttt{a}'' verranno visualizzati anche i processi
lanciati da altri utenti, purché facenti riferimento ad un terminale, mentre
con l'opzione ``\texttt{x}'' si visualizzano tutti i processi non associati ad
un terminale, infine l'opzione ``\texttt{f}'' permette di mostrare la
gerarchia dei processi. Così si può ottenere un elenco completo dei processi
con un comando del tipo:\label{sec:process_ps_out} 
\begin{Console}
piccardi@anarres:~$ \textbf{ps axf}
\end{Console}
%$
\begin{Terminal}
  PID TTY      STAT   TIME COMMAND
    2 ?        S      0:01 [kthreadd]
    3 ?        S      0:00  \_ [migration/0]
...
  508 ?        S      0:00  \_ [kjournald]
    1 ?        Ss     0:04 init [2]  
  217 ?        S<s    0:00 udevd --daemon
  266 ?        S<     0:00  \_ udevd --daemon
  279 ?        S<     0:00  \_ udevd --daemon
  724 ?        Sl     0:00 /usr/sbin/rsyslogd -c4
  773 ?        Ss     0:00 /usr/sbin/acpid
  786 ?        Ss     0:00 /usr/sbin/atd
  813 ?        Ss     0:00 /usr/sbin/cron
 1069 ?        Ss     0:00 /usr/sbin/exim4 -bd -q30m
 1087 tty1     Ss     0:00 /bin/login --     
 1093 tty1     S+     0:00  \_ -bash
 1088 tty2     Ss+    0:00 /sbin/getty 38400 tty2
 1089 tty3     Ss+    0:00 /sbin/getty 38400 tty3
 1090 tty4     Ss+    0:00 /sbin/getty 38400 tty4
 1091 tty5     Ss+    0:00 /sbin/getty 38400 tty5
 1092 tty6     Ss+    0:00 /sbin/getty 38400 tty6
 1148 ?        Ss     0:00 /usr/sbin/sshd
 1151 ?        Ss     0:00  \_ sshd: piccardi [priv]
 1153 ?        S      0:00      \_ sshd: piccardi@pts/0
 1154 pts/0    Ss     0:00          \_ -bash
 1181 pts/0    R+     0:00              \_ ps axf
\end{Terminal}
dato che la combinazione delle opzioni ``\texttt{a}'' e ``\texttt{x}'',
essendo queste complementari, seleziona tutti i processi attivi nel sistema.
L'uso dell'opzione ``\texttt{r}'' permette invece di restringere la selezione
ai soli processi in esecuzione effettiva (cioè nello stato ``\texttt{R}'', che
spiegheremo fra poco).

Come già questi primi esempi ci mostrano, in realtà lo scopo di \texttt{ps}
non è solo quello di fornire la lista dei processi in esecuzione, quanto
quello di mostrarne in generale caratteristiche e proprietà; la descrizione
del significato di quest'ultime andrà allora di pari passo con la spiegazione
dell'output del comando.

Per ogni processo attivo infatti il kernel mantiene tutta una serie di dati
che vengono usati per il controllo delle varie operazioni che esso può
compiere, insieme ad una serie di informazioni relative alle risorse da esso
utilizzate.  Già in questi due primi esempi il comando ci mostra alcune
informazioni di base sufficienti ad introdurre alcune delle proprietà
essenziali dei processi.

La prima colonna dei precedenti esempi, marcata \texttt{PID}, mostra il
cosiddetto \textit{process ID} del processo. Questo è il numero che il kernel
utilizza per identificare univocamente ciascun processo; questo numero viene
assegnato alla creazione del processo, ed è unico fintanto che il processo
resta attivo.  È questo il numero che si deve usare tutte le volte che si
vuole fare riferimento ad uno specifico processo.

La seconda colonna, marcata \texttt{TTY}, mostra il nome del cosiddetto
``\textsl{terminale di controllo}'' del processo. Il concetto di
``\textsl{terminale di controllo}'' è alquanto complesso, e ci torneremo in
sez.~\ref{sec:struct_job_control}, per quanto ci interessa è sufficiente dire
che un processo ``\textsl{interattivo}'' è sempre associato ad un terminale di
controllo che corrisponde appunto al terminale da cui il processo riceve i
dati in ingresso (in genere dalla tastiera) e sul quale scrive il suo output
(in genere lo schermo).

I processi non interattivi (i cosiddetti \textsl{demoni}) che vengono usati
per compiere una serie di compiti di servizio, come spedire la posta, eseguire
lavori periodici, servire pagine web, ecc. dovendo essere attivi anche quando
non c'è nessun utente collegato, lavorano invece come suol dirsi ``in
\textit{background}'' per cui non esiste un terminale di controllo ad essi
associato e la colonna \texttt{TTY} riporta come valore ``\texttt{?}''.

In realtà questa caratterizzazione dell'interattività viene a cadere qualora
si utilizzi una interfaccia grafica, dato che questa non necessita dell'uso di
un terminale per operare in modo interattivo, ma Unix è nato molto prima
dell'introduzione delle interfacce grafiche, ed a quel tempo l'uso di un
terminale costituiva l'unica modalità di accesso al sistema.  Per questo
motivo il kernel fornisce una serie di servizi collegati a questo speciale
dispositivo, ed uno dei punti più oscuri dell'interfaccia a linea di comando
di un sistema unix-like è proprio quello relativo alla gestione delle
\textsl{sessioni di lavoro}, su cui torneremo anche in
sez.~\ref{sec:struct_job_control}.

Si tenga presente che dal punto di vista del kernel non esiste nessuna
differenza fra processi interattivi e non, o meglio fra processi con un
terminale di controllo o meno; esso si limita a mettere a disposizione alcune
risorse che possono essere utilizzate per realizzare il controllo di sessione,
con la presenza di alcuni identificatori aggiuntivi come il \textit{session
  ID} ed il \textit{process group ID}, delle relative funzioni di gestione, e
di alcuni segnali associati all'uso del terminale.\footnote{per i dettagli su
  questi identificativi si consulti sez.~8.1.3 di \cite{GaPiL}.}

Il controllo di sessione viene poi realizzato completamente in \textit{user
  space}, usando queste risorse secondo le modalità classiche ereditate dai
primi Unix. Anche questi identificativi possono essere visualizzati tramite
\texttt{ps}, usando l'opzione \texttt{-j}, che ne stamperà il relativo valore
nelle colonne \texttt{SID} e \texttt{PGID}; vedremo un esempio di tutto questo
in sez.~\ref{sec:struct_job_control} quando tratteremo con qualche dettaglio
in più la gestione delle cosiddette \textsl{sessioni di lavoro}.

In tutti i precedenti esempi compare, nella colonna marcata \texttt{STAT},
un'altra informazione fondamentale: lo stato del processo. Il sistema infatti
prevede cinque possibili stati diversi per i processi, i cui valori sono
riportati in tab.~\ref{tab:proc_proc_states}; torneremo su questo a breve, in
quanto ci permette di spiegare varie caratteristiche dell'architettura dei
processi.  Seguono infine la colonna \texttt{TIME} che indica il tempo di CPU
usato finora dal processo e la colonna \texttt{COMMAND} che riporta la riga di
comando usata per lanciare il programma.

Per capire il significato del campo \texttt{STAT} occorrono alcune spiegazioni
generali sull'architettura della gestione dei processi.  Come sistema
multitasking Linux è in grado di eseguire più processi contemporaneamente, in
genere però un processo, pur essendo attivo, non è assolutamente detto che sia
anche in esecuzione. Il caso più comune infatti è quello in cui il programma è
in attesa di ricevere dati da una periferica; in tal caso il kernel pone il
programma in stato di \textit{sleep} e lo toglie dalla lista di quelli che
hanno bisogno del processore (che sono identificati invece dallo stato
\textit{runnable}).

\begin{table}[htb]
  \footnotesize
  \centering
  \begin{tabular}[c]{|p{2.8cm}|c|p{8cm}|}
    \hline
    \textbf{Stato} & \texttt{STAT} & \textbf{Descrizione} \\
    \hline
    \hline
    \textit{runnable}& \texttt{R} & il processo è in esecuzione o è pronto ad
                                    essere eseguito (cioè è in attesa che gli
                                    venga assegnata la CPU). \\
    \textit{sleep}   & \texttt{S} & il processo è in attesa di una
                                    risposta dal sistema, ma può essere
                                    interrotto da un segnale. \\
    \textit{uninterruptible sleep}& \texttt{D} & il  processo è in
                                    attesa di una risposta dal sistema (in
                                    genere per I/O), e non può essere
                                    interrotto in nessuna circostanza. \\
    \textit{stopped} & \texttt{T} & il processo è stato fermato con un
                                    \texttt{SIGSTOP}, o è tracciato.\\
    \textit{zombie}  & \texttt{Z} & il processo è terminato ma il
                                    suo stato di terminazione non è ancora
                                    stato letto dal padre. \\
    \hline
  \end{tabular}
  \caption{Elenco dei possibili stati di un processo in Linux, nella colonna
    \texttt{STAT} si è riportata la corrispondente lettera usata dal comando
    \texttt{ps} nell'omonimo campo.}
  \label{tab:proc_proc_states}
\end{table}

Si noti allora come nell'elenco precedente tutti i processi, eccetto lo stesso
comando \texttt{ps axf}, fossero in stato di \textit{sleep}. In genere un
processo entra in stato di \textit{sleep} tutte le volte che si blocca
nell'esecuzione di una \textit{system call} che richiede una qualche forma di
accesso non immediato a dei dati: un caso classico è la lettura dell'input da
tastiera.

Come dettagliato in tab.~\ref{tab:proc_proc_states} gli stati di
\textit{sleep} sono due, contraddistinti dalle lettere \texttt{S} e
\texttt{D}. Il più comune è il primo; l'esecuzione della maggior parte delle
\textit{system call} infatti può essere interrotta da un segnale (i segnali
saranno trattati in sez.~\ref{sec:struct_signal}), per cui se un processo si
blocca nell'esecuzione di una di queste esso può essere comunque terminato, in
alcuni casi (in genere questo avviene quando la \textit{system call} sta
gestendo la risposta ad un interrupt hardware) questo non è possibile ed
allora si ha uno stato di \textit{uninterruptible sleep}, in questo caso se il
processo resta bloccato\footnote{in genere questo avviene in maniera
  permanente solo per un qualche errore nella gestione della periferica nel
  kernel, ad esempio se si monta un disco USB e poi si lo si estrae dal bus
  senza smontarlo e si ha la sventura di farlo in un momento poco opportuno, o
  se ci sono problemi hardware o con un filesystem di rete come NFS in caso di
  crollo della connessione.}  nello stato \texttt{D} non può più essere
terminato se non con il riavvio della macchina.\footnote{in realtà con i
  kernel più recenti è stata introdotta una variante dello stato
  \textit{uninterruptible sleep}, denominata \textit{killable}, che consente,
  per i filesystem di rete (in sostanza NFS), di terminare il processo, ma
  \texttt{ps} non la distingue.}  Un processo in stato \texttt{D} comunque non
avrà nessun effetto né sugli altri processi né sul sistema, che continuerà a
funzionare senza problemi a parte quello di non poter liberare le risorse
occupate dal processo.

Lo stato di \textit{stopped} è relativo ai processi che vengono
tracciati,\footnote{si dice che un processo è tracciato se su di esso si usa
  il comando \texttt{strace}, che consente di intercettare e stampare a video
  tutte le \textit{system call}, vedi sez.~\ref{sec:diagnostic_command}.}  o
la cui esecuzione è stata fermata per una richiesta dell'utente (per fare
questo, come vedremo in sez.~\ref{sec:struct_signal}, si ha a disposizione un
segnale apposito), nel qual caso semplicemente il processo non viene eseguito
(ma resta in memoria e può riprendere l'esecuzione in qualunque momento)
fintanto che non lo si fa ripartire (anche per questo è previsto un altro
segnale).

\itindbeg{zombie}

Infine c'è lo stato di \textit{zombie}, il cui significato può essere compreso
solo ritornando con maggiori dettagli sulla relazione fra processo padre e gli
eventuali figli. La relazione padre/figlio infatti è ben definita finché
entrambi i processi sono attivi nel sistema, ma se uno dei due termina cosa
accade?  Alla terminazione di un processo il kernel provvede ad una serie di
compiti di pulizia; tutti i file aperti dal processo vengono chiusi, la
memoria utilizzata viene liberata e con essa tutte le risorse occupate dal
processo.  Resta il problema di come notificare l'avvenuta conclusione del
processo, ad esempio se questa è stata regolare o è stata dovuta ad un qualche
errore, e il problema è a chi fare questa notifica.

Dato che in un sistema Unix tutto viene fatto con i processi, la scelta è
stata quella di assegnare al padre il compito di ricevere lo stato di uscita
del figlio e controllare se tutto è andato bene o c'è stato qualche errore.
Quando un processo termina al padre viene inviato un apposito segnale che lo
avvisa del fatto, e lui deve invocare una apposita \textit{system call} per
ricevere lo stato di uscita. Questo ad esempio è il meccanismo con cui la
shell riceve lo stato di uscita dei comandi che si sono eseguiti.

Se questo non viene fatto il processo figlio si conclude comunque regolarmente
e tutte le risorse che occupava nel sistema vengono rilasciate, resta allocata
soltanto una voce nella tabella dei processi che contiene le informazioni per
riportare lo stato di uscita. Questo è quello che in gergo viene chiamato uno
\textit{zombie}, cioè un processo che non esiste più, perché è terminato, ma
che mostra una voce con lo stato ``\texttt{Z}'' nella lista fornita da
\texttt{ps} e che di nuovo non può essere terminato, per il semplice fatto che
lo è già. È pertanto compito di chi scrive programmi che creano processi figli
curarsi della ricezione del loro stato di uscita, ed infatti i programmi ben
scritti non presentano mai questo problema.

Di per sé la presenza di uno \textit{zombie} non è un grave problema, in
quanto esso non occupa, a differenza di un processo bloccato in stato
``\texttt{D}'', nessuna risorsa nel sistema a parte la voce mantenuta
nell'output di \texttt{ps}. Però la voce nella tabella dei processi resta
occupata e pertanto se il numero degli \textit{zombie} dovesse crescere in
maniera eccessiva si può rischiare di saturare quest'ultima, rendendo di fatto
inutilizzabile il sistema, dato che non sarà più possibile creare nuovi
processi. Ma a differenza dei processi bloccati permanentemente in stato
``\texttt{D}'' per gli \textit{zombie} è possibile risolvere il problema, e
far sì che essi siano terminati regolarmente, senza dover riavviare il
sistema.

Per capire come comportarsi con gli \textit{zombie} si deve considerare un
altro caso della gestione del funzionamento dei processi: quello in cui è il
padre a terminare prima del figlio. Se accade questo chi è che riceverà lo
stato di terminazione dei suoi figli? Dato che i processi sono eseguiti in
maniera del tutto indipendente un caso come questo è assolutamente naturale, e
in tal caso si dice che il figlio diventa ``\textsl{orfano}''. Per questo il
kernel controlla, durante le operazioni di terminazione di un processo, se
questo ha dei figli, e nel caso assegna a questi ultimi \texttt{init} come
nuovo padre.\footnote{si vedrà cioè, ad una successiva esecuzione di
  \texttt{ps} con opzioni che permettano di visualizzare il PID del padre, che
  questo è diventato 1.} Si dice allora che \texttt{init} \textsl{adotta} i
figli dei processi che terminano, e sarà lui che gestirà, alla terminazione di
questi ultimi, la ricezione del loro stato di uscita.

Perciò, dato che \texttt{init} è scritto bene e sa gestire la ricezione dello
stato di uscita, tutto quello che serve fare per eliminare gli \textit{zombie}
presenti nel sistema è di renderli orfani, terminando il processo che li ha
generati.\footnote{per poterlo fare però occorre avere un processo in grado di
  eseguire il comando di terminazione, cosa non facile da ottenere se si è già
  riempita la tabella dei processi.} In questo modo essi saranno adottati da
\texttt{init} che si curerà immediatamente di riceverne lo stato di uscita
liberando la voce che occupavano nella tabella dei processi.

\itindend{zombie}

Si noti nella lista precedente la presenza di alcuni processi con un nome del
comando fra parentesi quadre e con un PID molto basso;\footnote{prima del
  kernel 2.6 veniva riportata anche una lettera aggiuntiva ``\texttt{W}''
  nella colonna \texttt{STAT}.} questi non sono processi in \textit{user
  space} lanciati da \texttt{init} quanto dei processi interni al kernel da
esso utilizzati per la gestione di alcuni compiti, come lo scaricamento su
disco dei buffer dei file, la generazione di eventi dovuti all'inserimento di
periferiche, ecc. Questa notazione sta ad indicare che questi processi non
usano memoria in \textit{user space}, il che permette di identificarli.  Le
altre lettere associate al campo \texttt{STAT} sono ``\verb|<|'',
``\texttt{N}'' e ``\texttt{L}'' e indicano rispettivamente una priorità
maggiore o minore di quella standard (torneremo sulla priorità in
sez.~\ref{sec:struct_priority}) e la presenza di pagine di memoria
bloccate.\footnote{quest'ultima è una caratteristica avanzata che va al di là
  degli scopi di questo testo, per una trattazione si può fare riferimento
  alla sezione 2.2.4 di \cite{GaPiL}.}  A queste si aggiungono ulteriori
informazioni indicate dalle lettere minuscole, per il significato delle quali
si rimanda alla pagina di manuale di \texttt{ps}.

Le opzioni di visualizzazione di \texttt{ps} sono moltissime, e qui potremo
prendere in esame solo le principali. Restando nell'ambito della sintassi BSD
una delle più usate è ``\texttt{u}'' che stampa una lista con le informazioni
più rilevanti riguardo l'utente che ha lanciato il programma. Altre opzioni
sono ``\texttt{v}'' che stampa informazioni relative all'uso della memoria
virtuale, e \texttt{s} che stampa informazioni sui segnali. Infine l'opzione
``\texttt{o}'' permette all'utente di specificare un suo formato, con l'uso di
una serie di direttive \texttt{\%X}, dove ``\texttt{X}'' indica quale
proprietà del processo si vuole far comparire nella lista (secondo una tabella
di valori riportata nella pagina di manuale).

Se invece si usa la sintassi SysV le opzioni più usate sono \texttt{-e}, che
permette di selezionare tutti i processi presenti, e \texttt{-f} che permette
di avere una lista con più informazioni; in tal caso infatti si avrà come
uscita del comando:
\begin{Console}
piccardi@anarres:~$ \textbf{ps -ef}
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 12:39 ?        00:00:04 init [2]  
root         2     0  0 12:39 ?        00:00:00 [kthreadd]
root         3     2  0 12:39 ?        00:00:00 [migration/0]
...
root       217     1  0 12:39 ?        00:00:00 udevd --daemon
root       266   217  0 12:39 ?        00:00:00 udevd --daemon
root       279   217  0 12:39 ?        00:00:00 udevd --daemon
root       508     2  0 12:39 ?        00:00:00 [kjournald]
root       724     1  0 12:39 ?        00:00:00 /usr/sbin/rsyslogd -c4
root       773     1  0 12:39 ?        00:00:00 /usr/sbin/acpid
daemon     786     1  0 12:39 ?        00:00:00 /usr/sbin/atd
root       813     1  0 12:39 ?        00:00:00 /usr/sbin/cron
101       1069     1  0 12:39 ?        00:00:00 /usr/sbin/exim4 -bd -q30m
root      1087     1  0 12:39 tty1     00:00:00 /bin/login --     
root      1088     1  0 12:39 tty2     00:00:00 /sbin/getty 38400 tty2
root      1089     1  0 12:39 tty3     00:00:00 /sbin/getty 38400 tty3
root      1090     1  0 12:39 tty4     00:00:00 /sbin/getty 38400 tty4
root      1091     1  0 12:39 tty5     00:00:00 /sbin/getty 38400 tty5
root      1092     1  0 12:39 tty6     00:00:00 /sbin/getty 38400 tty6
root      1093  1087  0 12:40 tty1     00:00:00 -bash
root      1148     1  0 12:40 ?        00:00:00 /usr/sbin/sshd
root      1151  1148  0 12:40 ?        00:00:00 sshd: piccardi [priv]
piccardi  1153  1151  0 12:40 ?        00:00:00 sshd: piccardi@pts/0
piccardi  1154  1153  0 12:40 pts/0    00:00:00 -bash
piccardi  1180  1154  0 12:56 pts/0    00:00:00 ps -ef
\end{Console}
%$

Come si può vedere questa versione riporta una serie di dati in più.
Anzitutto notiamo che la prima colonna, \texttt{UID}, riporta un nome utente.
Ciascun processo infatti mantiene le informazioni riguardanti l'utente che ha
lanciato il processo ed il gruppo cui questo appartiene, il kernel infatti
identifica ogni utente e gruppo presente nel sistema con dei numeri interi,
detti rispettivamente \textit{user ID} (UID) e \textit{group ID} (GID) che poi
vengono abbinati a dei nomi simbolici come quelli riportati dal comando
(tratteremo l'argomento in dettaglio in sez.~\ref{sec:struct_multiuser}).

Ogni processo in realtà mantiene diverse versioni di questi
identificatori,\footnote{Linux usa ben quattro gruppi di identificatori
  diversi per gestire il controllo di accesso, secondo uno schema che va al di
  là di quanto è possibile spiegare qui, gli interessati possono trovare una
  trattazione dell'argomento nella sezione 3.2 di \cite{GaPiL}.} ma i più
significativi sono i l'\textit{effective user ID} ed l'\textit{effective
  group ID}, che vengono utilizzati per il controllo di accesso (che
tratteremo in sez.~\ref{sec:struct_access_control}). I nomi corrispondenti a
questi identificatori sono quelli che corrispondono alla colonna \texttt{UID}
(e ad una eventuale colonna \texttt{GID}) del comando, ma è possibile anche
richiedere il \textit{real user ID} e il \textit{real group ID}, che
identificano l'utente che ha lanciato il processo,\footnote{di norma questi
  coincidono con gli identificatori del gruppo \textit{effective}, ma vedremo
  in sez.~\ref{sec:struct_file_perm} che esistono casi in cui questo non
  avviene.} che invece vengono identificati da sigle come \texttt{RUSER} e
\texttt{RGROUP}, se indicati con il nome o con \texttt{RUID} e \texttt{RGID}
se numerici.

La seconda colonna del nostro esempio riporta di nuovo il PID di ciascun
processo, mentre la terza colonna, \texttt{PPID}, indica il \textit{parent
  process ID}, ogni processo infatti mantiene il PID del padre, in modo da
poter ricostruire agevolmente la genealogia dei processi. Questa ci permette
anche, in caso di \textit{zombie}, di identificare il processo responsabile
della produzione degli stessi.

La quarta colonna, \texttt{C}, indica il valore medio, espresso come intero,
della percentuale di utilizzo della CPU su tutta la vita del processo. La
quinta colonna, \texttt{STIME}, indica invece il momento in cui il comando è
stato lanciato.  Le altre colonne sono analoghe a quelle già viste in
precedenza per la sintassi BSD.  Un elenco delle principali informazioni
relative ai processi che vengono riportate da \texttt{ps} sono elencate in
tab.~\ref{tab:proc_ps_process_property}, indicate sempre in base al nome usato
come intestazione della colonna che ne visualizza il valore.  Per l'elenco
completo di opzioni, informazioni e dati visualizzabili si può fare
riferimento alla pagina di manuale del comando, accessibile con \texttt{man
  ps}.


\begin{table}[!htb]
  \footnotesize
  \centering
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Proprietà} & \textbf{Descrizione} \\
    \hline
    \hline
    \texttt{PID}   & PID, \textit{process ID} del processo.\\
    \texttt{PPID}  & PPID, \textit{process ID} del padre del processo.\\
    \texttt{UID}   & \textit{effective user ID} del processo.\\
    \texttt{GID}   & \textit{effective group ID} del processo.\\
    \texttt{CMD}   & linea di comando con cui è stato lanciato il processo. \\
    \texttt{STAT}  & stato del processo.\\
    \texttt{NI}    & valore di \textit{nice} (vedi sez.~\ref{sec:struct_priority}) del processo.\\
    \texttt{TTY}   & terminale di controllo del processo.\\
    \texttt{SID}   & SID, \textit{session ID} (vedi
                     sez.~\ref{sec:struct_job_control}) del processo.\\
    \texttt{PGID}  & PGID, \textit{process group ID} (vedi
                     sez.~\ref{sec:struct_job_control}) del processo.\\
%    \texttt{RSS}   & la \textit{\textbf{r}esident \textbf{s}et
%                     \textbf{s}ize}, la memoria effettivamente
%                     occupata dal programma, in kb.\\
%    \texttt{VSZ}   & la \texttt{\textbf{v}irtual \textbf{m}emory
%                     \textbf{s}ize}, la memoria occupata virtualmente dal
%                     programma.\\
    \texttt{\%CPU} & percentuale del tempo di CPU usato rispetto al tempo
                     reale di esecuzione.\\ 
    \texttt{\%MEM} & percentuale della memoria fisica utilizzata dal 
                     processo.\\
    \texttt{C}     & percentuale di CPU sulla media della vita del processo.\\
    \texttt{START} & orario dell'avvio del processo.\\
    \texttt{TIME}  & tempo totale di CPU utilizzato dall'avvio del processo.\\
    \texttt{USER}  & \textit{effective user ID} del processo.\\
    \texttt{RUSER} & \textit{real user ID} del processo.\\
    \texttt{GROUP} & \textit{effective group ID} del processo.\\
    \texttt{RGROUP}& \textit{real group ID} del processo.\\
    \texttt{COMMAND}& riga di comando con la quale si è avviato il processo.\\
%    \textbf{}& \texttt{} & \\
    \hline
  \end{tabular}
  \caption{Le principali proprietà dei processi ed il nome della relativa
    colonna nella visualizzazione effettuata da \texttt{ps}.}
  \label{tab:proc_ps_process_property}
\end{table}

Infine ci sono alcune proprietà dei processi, non immediatamente
visualizzabili con \texttt{ps},\footnote{si possono comunque ricercare tutte
  le informazioni relative ai processi nel filesystem \texttt{/proc}, che è
  nato proprio per fornire una interfaccia con il kernel da cui ottenerle
  (tanto che se non è montato \texttt{ps} non funzionerà); in particolare
  sotto \texttt{/proc} si troverà per ciascun processo una directory con nome
  uguale al rispettivo PID, il cui contenuto è costituito una serie di file e
  directory (virtuali) che permettono di accedere alle proprietà dello
  stesso.} che comunque sono importanti e vanno menzionate.  Come accennato in
sez.~\ref{sec:struct_filesystem_arch}, ogni processo ha una directory di
lavoro rispetto alla quale risolve i \textit{pathname} relativi; anche questa
è una caratteristica del processo, che viene ereditata nella creazione di un
processo figlio.

Benché questo possa sembrare strano a prima vista, lo stesso vale per la
\textsl{directory radice}, ogni processo cioè porta con sé, oltre alla
directory di lavoro corrente, anche l'indicazione della directory che
considera come radice, rispetto alla quale risolve i \textit{pathname}
assoluti. Questa directory può essere cambiata con una apposita \textit{system
  call} (chiamata \texttt{chroot}) ottenendo così che il processo venga in un
certo senso \textsl{ristretto} all'interno di una parte dell'albero dei file
(torneremo su questo in sez.~\ref{sec:struct_privileged_operations}).

%Altre caratteristiche ereditate dai figli, oltre ai permessi appena descritti,
%sono i file descriptor aperti e gli eventuali file mappati in memoria.

Come si può notare \texttt{ps} si limita a stampare la lista dei processi
attivi al momento della sua esecuzione. Se si vuole tenere sotto controllo
l'attività del sistema non è pratico ripetere in continuazione l'esecuzione di
\texttt{ps}. Per questo ci viene in aiuto il comando
\index{comando!\texttt{top}} \texttt{top}, che stampa una lista di processi,
aggiornandola automaticamente in maniera periodica.

Il comando opera normalmente in maniera interattiva, a meno di non averlo
lanciato con l'opzione \texttt{-b}, che lo esegue in modalità batch,
consentendo la redirezione dell'output; in tal caso di solito si usa anche
l'opzione \texttt{-n} per specificare il numero di iterazioni volute. Il
comando ristampa la lista ogni secondo, a meno di non aver impostato un
intervallo diverso con l'opzione \texttt{-d}, che richiede un parametro nella
forma \texttt{\textsl{ss.dd}} dove \texttt{\textsl{ss}} sono i secondi e
\texttt{\textsl{dd}} i decimi di secondo. Infine l'opzione \texttt{-p}
permette di osservare una lista di processi scelta dall'utente, che deve
specificarli tramite una lista di PID.  Per la lista completa delle opzioni si
faccia riferimento al solito alla pagina di manuale, accessibile con
\texttt{man top}.

Quando opera in modalità interattiva il comando permette di inviare dei
comandi da tastiera. I più rilevanti sono ``\texttt{h}'' e ``\texttt{?}'' che
mostrano un help in linea dei comandi disponibili, e ``\texttt{q}'' che
termina il programma. Un esempio di output del comando è riportato in
fig.~\ref{fig:top_command_screen}.

\begin{figure}[!htb]
\centering
\includegraphics[scale=0.5]{images/top}
\caption{Schermata del comando \texttt{top}.}
\label{fig:top_command_screen}
\end{figure}

In testa vengono sempre stampate cinque righe di informazioni riassuntive sul
sistema: nella prima riga viene riportato l'orario,
\textit{uptime},\footnote{cioè il tempo trascorso da quando il sistema è stato
  avviato.} il numero di utenti ed il carico medio della macchina; nella
seconda riga le statistiche sul totale dei processi; nella terza le
statistiche di utilizzo della CPU, nelle ultime due le statistiche di uso
della memoria fisica e della \textit{swap} (su cui torneremo in
sez.~\ref{sec:swap_CDROM_management}).

A queste informazioni generiche seguono, dopo una riga lasciata vuota che
serve per gestire l'input in interattivo, le informazioni sui processi,
ordinati per uso decrescente della CPU (vengono cioè mostrati i più attivi),
evidenziando (con la stampa in grassetto) quelli trovati in stato
\textit{runnable}. Le informazioni riportate di default sono il PID del
processo (colonna omonima), l'utente cui esso appartiene (colonna
\texttt{USER}); la priorità ed il valore di \textit{nice} (torneremo su questi
in sez.~\ref{sec:struct_priority}) rispettivamente nelle colonne \texttt{PR} e
\texttt{NI}.

Seguono i dati dell'uso della memoria nelle colonne \texttt{VIRT},
\texttt{RES} e \texttt{SHR}; per capire queste quantità occorre dare qualche
dettaglio in più sul sistema della \textsl{memoria virtuale} cui abbiamo già
accennato in sez.~\ref{sec:struct_base}; in quella occasione abbiamo detto
come sia compito del kernel mappare lo spazio (virtuale) degli indirizzi di
memoria di un processo nella memoria fisica effettivamente disponibile. La
memoria usata da un processo è sostanzialmente suddivisa in due
parti,\footnote{si sta usando una descrizione brutalmente semplificata, per
  una trattazione dettagliata dell'argomento si può fare riferimento alla
  sezione 2.2 di \cite{GaPiL}.} il codice del programma e i dati usati dallo
stesso.

Il programma per essere eseguito dovrà avere il codice ed i relativi dati
nella memoria fisica, e la quantità di memoria attualmente usata a questo
scopo è quella che è indicata dalla colonna \texttt{RES} e viene detta
\textsl{residente}, che sarà la somma della parte usata per i dati (indicata
da \texttt{DATA}) e della parte usata per il codice (indicata da
\texttt{CODE}). Una parte di quest'ultima (ad esempio il codice delle
librerie) sarà condivisa con altri processi, e questa viene indicata dalla
colonna \texttt{SHR}.

Ci sarà però anche una parte di memoria che al momento non è in uso, e che,
per liberare della memoria fisica a favore di altri programmi che devono
essere eseguiti, è stata temporaneamente \textsl{parcheggiata} su una area di
disco a questo dedicata (detta \textit{swap}, vedi
sez.~\ref{sec:swap_CDROM_management}) da cui può essere ripresa in caso di
necessità.  Allora il totale della memoria vista dal programma, che a questo
punto è \textsl{virtuale}, in quanto non corrisponde a della RAM direttamente
accessibile, è quello espresso dalla colonna \texttt{VIRT}, che sarà la somma
sia della parte \textsl{residente} (quella di \texttt{RES}) che di quella che
è stata parcheggiata nell'area di \textit{swap}.

Come altre informazioni presenti nella stampa di default il comando riporta lo
stato del processo (colonna \texttt{S}), le percentuali di utilizzo di CPU e
memoria (colonne \texttt{\%CPU} e \texttt{\%MEM}), il tempo di CPU utilizzato
dall'avvio del programma (colonna \texttt{TIME+}) ed il comando usato per
lanciarlo (colonna \texttt{COMMAND}), il cui significato è analogo a quello
già visto per \texttt{ps}.

\begin{table}[!htb]
  \footnotesize
  \centering
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Proprietà} & \textbf{Descrizione} \\
    \hline
    \hline
%    \texttt{VSZ}   & .\\
    \texttt{\%CPU} & percentuale di uso della CPU dall'ultimo aggiornamento
                     dello schermo.\\
    \texttt{\%MEM} & percentuale di uso della memoria da parte del processo.\\
    \texttt{CODE}  & ammontare della memoria fisica utilizzata dal processo
                     per il suo codice eseguibile.\\  
    \texttt{DATA}  & ammontare della memoria fisica utilizzata dal processo
                     per i suoi dati.\\  
    \texttt{RES}   & ammontare della memoria fisica usata dal processo (uguale 
                     a \texttt{CODE} + \texttt{DATA}).\\  
    \texttt{S}     & stato del processo (analogo allo \texttt{STAT} di
                     \texttt{ps}). \\  
    \texttt{SHR}   & ammontare della \textsl{memoria condivisa}, rappresenta
                     la memoria potenzialmente condivisibile con altri
                     processi.\\  
    \texttt{SWAP}  & ammontare della \textsl{memoria virtuale} di un processo
                     presente nella \textit{swap}.\\
    \texttt{TIME+} & tempo di CPU utilizzato dall'avvio, analogo al
                     \texttt{TIME} di \texttt{ps}, ma con granularità fino al
                     centesimo di secondo.\\  
%    \texttt{VSZ}   & .\\
    \texttt{VIRT}  & ammontare totale della \textsl{memoria virtuale} usata
                     dal processo include tutto il codice, i dati e le
                     librerie condivise più le pagine che sono state messe su
                     \textit{swap} (uguale a \texttt{SWAP} +
                     \texttt{RES}).\\  
    \hline
  \end{tabular}
  \caption{Proprietà dei processi e nome della relativa
    colonna nella visualizzazione effettuata da \texttt{top}.}
  \label{tab:proc_top_process_property}
\end{table}

In generale le informazioni riportate nelle colonne stampate da \texttt{top}
sono simili a quelle di \texttt{ps}, anche se in alcuni casi esse vengono
indicate diversamente. Le principali proprietà mostrate da \texttt{top} sono
riportate in tab.~\ref{tab:proc_top_process_property}, per quelle comuni non
presenti in detta tabella si faccia riferimento alle omonime di \texttt{ps}
riportate in tab.~\ref{tab:proc_ps_process_property}.

Come accennato se \texttt{top} viene usato in modalità interattiva diventa
possibile inviare una serie di comandi da tastiera, ad esempio con
``\texttt{k}'' si può inviare un segnale (di default è \texttt{SIGTERM}, vedi
sez.~\ref{sec:struct_signal}) mentre con ``\texttt{r}'' si può cambiare la
priorità (vedi sez.~\ref{sec:struct_priority}) di un processo.  Con il comando
``\texttt{u}'' si possono selezionare i processi di un utente, con
``\texttt{c}'', si può alternare fra la stampa del nome comando e della riga
completa, con ``\texttt{d}'' cambiare il periodo di aggiornamento dei
risultati.  L'elenco completo, oltre ad essere riportato nella pagina di
manuale, può essere stampato a video con ``\texttt{h}''.

Si noti che nelle righe iniziali mostrate in precedenza \texttt{top} riporta
anche delle statistiche complessive sull'uso della memoria, queste possono
essere ottenute separatamente tramite il comando \index{comando!\texttt{free}}
\texttt{free}, che mostra un riassunto generale dell'impiego della memoria
all'interno del sistema, con un qualcosa del tipo:
\begin{Console}
piccardi@anarres:~$ \textbf{free}
             total       used       free     shared    buffers     cached
Mem:        775444     759364      16080          0     213276     316908
-/+ buffers/cache:     229180     546264
Swap:       498004      34708     463296
\end{Console}
%$

La prima riga riporta l'uso della memoria fisica, mentre l'ultimo quello della
\textit{swap} (se questa è attiva, torneremo sull'argomento in
sez.~\ref{sec:swap_CDROM_management}). La riga centrale ci dice quanto della
memoria è occupata o libera dal punto di vista delle applicazioni, per cui al
valore alle colonne \texttt{used} e \texttt{free} riportato nella prima riga
viene rispettivamente sottratta e aggiunta la somma delle colonne
\texttt{buffers} e \texttt{cached} della stessa, dato che esse indicano i dati
temporanei che possono essere scartati qualora sia necessaria altra memoria
per le applicazioni. In questo modo si ottiene la memoria usata direttamente
dalle applicazioni e il totale di quella che potrebbe essere loro messa a
disposizione.

Si noti che in genere la RAM libera è sempre molto poca; questo è corretto, in
quanto non ha senso lasciare inutilizzata la RAM, per cui viene impiegata dai
buffer del kernel (per gestire più efficacemente il trasferimento dei dati
verso i dispositivi) e per mantenere dati temporanei, come riportato nelle
colonne \texttt{buffers} e \texttt{cached}.\footnote{la colonna \texttt{shared}
  veniva usata per indicare la memoria condivisa fra più processi, adesso è
  obsoleta e deve essere ignorata.} 

Il comando \texttt{free} non ha argomenti e prende come opzioni \texttt{-b},
\texttt{-k} e \texttt{-m} per stampare i dati di utilizzo rispettivamente in
byte, kilobyte (il default) e megabyte. Inoltre lo si può mantenere attivo in
modo da osservare continuamente lo stato della memoria usando l'opzione
\texttt{-s}, seguita dal numero di secondi che passano fra un controllo e
l'altro. L'elenco completo delle opzioni ed i relativi dettagli sono al solito
riportati nella pagina di manuale, accessibile con \texttt{man free}.

Infine qualora si voglia ricercare il valore del PID di un certo programma,
invece di andare a cercare nell'output di \texttt{ps} si può utilizzare
\index{comando!\texttt{pidof}} \texttt{pidof}. Il comando prende come
argomento una lista di nomi dei programmi di cui si vuole conoscere il PID ed
esegue automaticamente una ricerca nella tabella dei processi, stampando la
lista dei PID di tutti i processi che corrispondono. Il comando prende
l'opzione \texttt{-s}, che richiede, in caso di più processi che corrispondono
allo stesso programma, di stampare un solo PID, mentre gli si può dire di
omettere un PID passandolo come parametro per l'opzione \texttt{-o}. Per i
dettagli del funzionamento e l'elenco completo delle opzioni si può consultare
la pagina di manuale accessibile con \texttt{man pidof}.

Il comando viene usato in genere negli script di shell (vedi
sez.~\ref{sec:shell_scripting}) per controllare se un certo programma è in
esecuzione; infatti se nella ricerca non viene trovato nessun processo il
comando non stampa niente ma ritorna uno stato di uscita indicante un errore,
che può essere usato per prendere delle decisioni. Si tenga presente che la
ricerca viene eseguita sul nome del programma, se esistono diversi programmi
con lo stesso nome per avere la certezza di scegliere quello voluto è
necessario indicare un \textit{pathname} assoluto.



\subsection{I segnali}
\label{sec:struct_signal}

Benché i processi siano di norma entità separate e completamente indipendenti
fra di loro, esistono molti casi in cui è necessaria una qualche forma di
comunicazione. La forma più elementare di comunicazione fra processi è
costituita dai segnali, che sono usati anche direttamente dal kernel per
comunicare ai processi una serie di eventi o errori (come l'uso inappropriato
della memoria o una eccezione aritmetica).

Come dice la parola un segnale è una specie di avviso che viene inviato ad un
processo; e non contiene nessuna informazione oltre al fatto di essere stato
inviato. In genere i segnali vengono utilizzati per notificare ai processi una
serie di eventi (abbiamo accennato in sez.~\ref{sec:struct_proc_property} che
uno di essi viene utilizzato per notificare la terminazione di un processo
figlio), e possono essere anche inviati a mano attraverso l'uso del comando
\index{comando!\texttt{kill}} \texttt{kill}.\footnote{con la \texttt{bash}
  shell il comando è disponibile anche come comando interno, nel qual caso può
  avere un comportamento leggermente diverso per alcune delle opzioni rispetto
  a quanto riportato qui.} Ciascun segnale è identificato da un numero e da un
nome simbolico; la lista dei segnali disponibili può essere ottenuta
semplicemente con:
\begin{Console}
piccardi@anarres:~$ \textbf{kill -l}
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL
 5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE
 9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2
13) SIGPIPE     14) SIGALRM     15) SIGTERM     17) SIGCHLD
18) SIGCONT     19) SIGSTOP     20) SIGTSTP     21) SIGTTIN
22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO
30) SIGPWR      31) SIGSYS      32) SIGRTMIN    33) SIGRTMIN+1
34) SIGRTMIN+2  35) SIGRTMIN+3  36) SIGRTMIN+4  37) SIGRTMIN+5
38) SIGRTMIN+6  39) SIGRTMIN+7  40) SIGRTMIN+8  41) SIGRTMIN+9
42) SIGRTMIN+10 43) SIGRTMIN+11 44) SIGRTMIN+12 45) SIGRTMIN+13
46) SIGRTMIN+14 47) SIGRTMIN+15 48) SIGRTMAX-15 49) SIGRTMAX-14
50) SIGRTMAX-13 51) SIGRTMAX-12 52) SIGRTMAX-11 53) SIGRTMAX-10
54) SIGRTMAX-9  55) SIGRTMAX-8  56) SIGRTMAX-7  57) SIGRTMAX-6
58) SIGRTMAX-5  59) SIGRTMAX-4  60) SIGRTMAX-3  61) SIGRTMAX-2
62) SIGRTMAX-1  63) SIGRTMAX     
\end{Console}
%$

I segnali effettivamente usati dal sistema sono i primi 31, gli altri sono
chiamati \textit{real time signal} ed hanno un uso specialistico che va al di
là di quello che possiamo affrontare qui.\footnote{per una spiegazione più
  dettagliata al riguardo si può fare riferimento alla sezione 7.5.1 di
  \cite{GaPiL}.} In generale ciascuno di essi ha un compito o un significato
specifico, alcuni di essi vengono generati automaticamente in caso di errori
del programma. Ad esempio il segnale \texttt{SIGSEGV} viene inviato dal kernel
per segnalare ad un processo una \textit{Segment Violation}, cioè un accesso
illegale alla memoria;\footnote{questo è un altro dei vantaggi della memoria
  virtuale, se per un errore di programmazione un processo cerca di scrivere
  su una parte dello spazio degli indirizzi che non corrisponde a nessuna
  locazione di memoria associata al processo stesso, il sistema se ne accorge
  ed invia questo segnale che ne causa la terminazione; si impedisce così che
  un accesso sbagliato possa andare a sovrascrivere la memoria di altri
  processi.} altri vengono inviati direttamente dall'utente, come
\texttt{SIGKILL} che causa l'immediata terminazione di un processo.

Gran parte dei segnali (tutti eccetto \texttt{SIGKILL} e \texttt{SIGSTOP}, che
hanno un comportamento speciale) possono essere \textsl{intercettati} dal
processo, che può eseguire una opportuna funzione al loro arrivo. Ad esempio
il segnale \texttt{SIGTERM} (che è quello che il comando \texttt{kill} invia
di default) serve per richiedere la terminazione immediata di un processo, ma
il segnale può essere intercettato per eseguire delle operazioni di pulizia,
come cancellare dei file temporanei prima dell'uscita.

Se un segnale non viene intercettato viene eseguita un'azione di default che è
specifica di ciascuno di essi, ma che nella maggior parte dei casi consiste
nella terminazione immediata del processo. Questa può però avvenire in due
modi, o con una semplice uscita o con l'uscita eseguita insieme alla
creazione, nella directory di lavoro del processo, di un file \texttt{core}
che contiene una copia del suo spazio di memoria (e per questo viene chiamato
\textit{core dump}) che può essere usato per ulteriori analisi per vedere in
che punto è avvenuta l'interruzione.  Infine alcuni segnali (come
\texttt{SIGCHLD}, che è quello che viene usato per notificare al padre la
terminazione di un figlio) di default vengono ignorati,\footnote{nel caso di
  \texttt{SIGCHLD} non è proprio il caso di farlo, altrimenti, come spiegato
  in sez.~\ref{sec:struct_proc_property}, ci si ritroverà con degli
  \textit{zombie}.} il programma cioè continua ad essere eseguito senza
nessuna conseguenza.

Tipici segnali che causano una semplice uscita sono \texttt{SIGTERM}, il
default del comando \texttt{kill}, e \texttt{SIGINT} che è associato al
carattere di interruzione dato dalla tastiera (vedi
sez.~\ref{sec:struct_job_control}), un segnale che invece produce un
\textit{core dump} è \texttt{SIGQUIT}, così come tutti i segnali relativi ad
errori di programmazione come \texttt{SIGSEGV}, \texttt{SIGFPE}, ecc. Segnali
come \texttt{SIGSTOP} e \texttt{SIGTSTP} invece hanno come effetto quello di
fermare l'esecuzione di un programma, mandandolo in stato \texttt{T}. Un
elenco dettagliato dei segnali, del loro significato e delle azioni di default
si può trovare nella sezione 9.2 di \cite{GaPiL}.

In generale il comando \texttt{kill} permette di inviare un segnale ad un
processo qualunque, specificando come parametro il PID di quest'ultimo.  Come
accennato il segnale inviato di default è \texttt{SIGTERM}, ma si può inviare
qualunque altro segnale specificandone numero o nome preceduto da un
``\texttt{-}'' come opzione; ad esempio:
\begin{Example}
kill -9 1029
kill -SIGKILL 1029
kill -KILL 1029
kill -s SIGKILL 1029
\end{Example}
sono modalità equivalenti di inviare il segnale \texttt{SIGKILL} al processo
con PID 1029.  Oltre a \texttt{-s} e \texttt{-l} il comando \texttt{kill}
accetta le opzioni \texttt{-L} (sinonimo di \texttt{-l}) e \texttt{-V} che ne
stampa la versione. Per una descrizione accurata delle opzioni si faccia al
solito riferimento alla pagina di manuale accessibile con \texttt{man kill}.

Nel caso specifico, dato che \texttt{SIGKILL} non è intercettabile e la sua
azione di default è la terminazione del processo, l'effetto di questo comando
è di terminare senza possibilità di scampo il processo in questione.  Infatti
\texttt{SIGTERM} può venire intercettato e può risultare inefficace qualora il
processo rimanga bloccato nell'esecuzione della funzione di gestione; ma
siccome non è possibile intercettare \texttt{SIGKILL} si ha a disposizione un
mezzo infallibile\footnote{in realtà quasi infallibile, infatti come accennato
  in sez.~\ref{sec:struct_proc_property}, inviare segnali ad un processo in
  stato ``\texttt{D}'' non ha effetto, perché non può riceverli fintanto che
  resta in quello stato, ed è inutile inviarli ad un processo in stato
  ``\texttt{Z}'' perché in realtà esso non esiste più.}  per terminare un
processo ``\textsl{impazzito}'', e questo senza alcuna conseguenza per gli
altri processi o per il sistema.

I segnali sono un meccanismo di comunicazione elementare fra processi, è cioè
possibile utilizzarli per dare delle istruzioni (molto semplici, come quella
di terminare l'esecuzione) ad un processo. Uno dei segnali più usati come
argomento del comando \texttt{kill} è ad esempio \texttt{SIGHUP}, che viene
spesso utilizzato per dire ai \textsl{demoni} di sistema di rileggere il
proprio file di configurazione. Inoltre alcuni segnali, come \texttt{SIGTSTP},
\texttt{SIGINT} e lo stesso \texttt{SIGHUP}, sono associati al controllo del
terminale e vengono inviati attraverso opportune combinazioni di tasti o in
occasione di eventi particolari; torneremo su questo in
sez.~\ref{sec:struct_job_control} quando affronteremo le questioni relative al
controllo di sessione.

Infine invece che ad un singolo processo si può inviare un segnale ad un
intero \textit{process group} (sui \textit{process group} torneremo più avanti
in sez.~\ref{sec:struct_job_control}) usando come argomento il negativo del
relativo \textit{process group ID}; il valore \texttt{-1} inoltre ha il
significato speciale di indicare tutti i processi correnti, eccetto
\texttt{init} ed il processo che esegue il comando.

Un comando alternativo a \texttt{kill}, e più facile da usare, è
\index{comando!\texttt{killall}} \texttt{killall} che invece di richiedere un
numero di PID funziona indicando il nome del programma, ed invia il segnale
(specificato con la stessa sintassi di \texttt{kill}) a tutti i processi
attivi con quel nome. Le opzioni principali disponibili sono riportate in
tab.~\ref{tab:proc_killall_options}. Al solito la documentazione completa è
nella pagina di manuale, accessibile con \texttt{man killall}. 

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-g} & invia il segnale al \textit{process group} del processo.\\ 
    \texttt{-e} & richiede una corrispondenza esatta anche per nomi molto
                  lunghi (il comando controlla solo i primi 15 caratteri).\\ 
    \texttt{-i} & chiede una conferma interattiva prima di inviare il
                  segnale.\\ 
    \texttt{-l} & stampa la lista dei nomi dei segnali.\\ 
    \texttt{-u \textsl{user}} & manda il segnale ai processi dell'utente
                 \texttt{\textsl{user}}.\\ 
    \texttt{-w} & attende la terminazione di tutti i processi cui ha inviato
                  il segnale.\\ 
    \hline
  \end{tabular}
  \caption{Principali opzioni del comando \texttt{killall}.}
  \label{tab:proc_killall_options}
\end{table}

Altri due comandi ancora più sofisticati per la gestione dei segnali e
l'identificazione dei processi, sono \index{comando!\texttt{pgrep}}
\texttt{pgrep} e \index{comando!\texttt{pkill}} \texttt{pkill} (in realtà il
secondo è una modalità alternativa di chiamare il primo). Con \texttt{pgrep}
infatti è possibile selezionare gruppi di processi, cui eventualmente inviare,
se invocato come \texttt{pkill}, un segnale che di default è \texttt{SIGTERM}
ma che può essere uno qualunque, da indicare con la stessa sintassi di
\texttt{kill}. Entrambi i comandi prendono come argomento una espressione
regolare (vedi sez.~\ref{sec:cmd_regular_expression}) che viene usata per
selezionare i processi usando il relativo nome. La ricerca può essere
ristretta ad una corrispondenza esatta usando l'opzione \texttt{-x} o estesa
all'intera riga di comando con cui è stato lanciato il processo con
\texttt{-f}. Si può anche invertire la selezione con \texttt{-v}, prendendo
tutti i processi che non corrispondono.

\begin{table}[htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{8cm}|}
    \hline
    \textbf{Opzione} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{-f} & estende la selezione all'intera riga di comando.\\ 
    \texttt{-G  \textsl{gid,name,}} & restringe la selezione ai processi con
                                     GID nella lista indicata.\\  
    \texttt{-n} & seleziona il processo più recente.\\ 
    \texttt{-o} & seleziona il processo meno recente.\\ 
    \texttt{-P \textsl{ppid,}} & restringe la selezione ai processi con padre
                                 nella lista indicata.\\ 
    \texttt{-s \textsl{sid,}} & restringe la selezione ai processi con \textit{session
                                    Id} nella lista indicata.\\ 
    \texttt{-t \textsl{tty,}} & restringe la selezione ai processi con
                                terminale di controllo nella lista indicata.\\ 
    \texttt{-u \textsl{uid,name,}} & restringe la selezione ai processi con \textit{effective
                                    user ID} nella lista indicata.\\ 
    \texttt{-U \textsl{uid,name,}} & restringe la selezione ai processi con \textit{real
                                    user ID}  nella lista indicata.\\ 
    \texttt{-v} & inverte la selezione.\\ 
    \texttt{-x} & richiede una corrispondenza esatta al nome del comando.\\ 
    \hline
    \texttt{-d \textsl{delim}} & stampa l'elenco usando il carattere
                                 \texttt{delim} come separatore al posto
                                 dell'a~capo.\\ 
    \hline
  \end{tabular}
  \caption{Principali opzioni dei comandi \texttt{pgrep} e \texttt{pkill}.}
  \label{tab:proc_pgrep_pkill_options}
\end{table}

Oltre che al nome è possibile restringere ulteriormente la selezione dei
processi in base a tutta una serie di altre loro caratteristiche, ad esempio
si possono selezionare per utenti passando una lista separata da virgole, sia
di username che di UID, all'opzione \texttt{-u}, mentre per i gruppi si può
usare in modo analogo l'opzione \texttt{-G}, si possono poi selezionare i
processi per terminale di controllo, \textit{session ID}, \textit{process
  group}, PPID, ecc. Infine possono essere molto comode le opzioni \texttt{-n}
e \texttt{-o} per selezionare rispettivamente il più ed il meno recente (in
termini di tempo di avvio). Un elenco delle opzioni più importanti è riportato
in tab.~\ref{tab:proc_pgrep_pkill_options}, nella cui seconda parte si sono
inserite le opzioni specifiche del solo \texttt{pgrep}.

\subsection{La gestione delle priorità}
\label{sec:struct_priority}

Abbiamo visto in sez.~\ref{sec:struct_proc_property} che una delle proprietà
dei processi che si può modificare con \texttt{top} è la priorità. In realtà,
come accennato in tale occasione, quello che di norma si può modificare non è
tanto la priorità di un processo, quanto il suo valore di \textit{nice}.

La gestione delle priorità in un sistema unix-like infatti è abbastanza
complessa dato che esistono due tipi di priorità: statiche e dinamiche. Di
norma le priorità statiche vengono utilizzate solo per i cosiddetti processi
\textit{real-time},\footnote{questo nome è in realtà fuorviante, Linux, almeno
  nella sua versione standard, non è un sistema operativo \textit{real-time}.
  Se si ha necessità di usare un sistema effettivamente \textit{real-time}
  occorre usare una versione del kernel opportunamente modificata, ad esempio
  Xenomai (\url{http://www.xenomai.org}).}  i processi ordinari (tutti, l'uso
di processi \textit{real-time} è riservato a pochi usi specialistici) hanno
priorità statica nulla e il loro ordine di esecuzione viene stabilito solo in
base a delle priorità dinamiche.

Una priorità statica più alta comporta che un processo verrà sempre eseguito
prima di ogni altro processo a priorità più bassa. Il che vuol dire che se si
lancia un processo a priorità statica alta che non fa I/O non si potrà fare
più nulla nel sistema fintanto che questo non si sarà concluso (e se c'è un
errore e il programma si blocca in un ciclo si dovrà necessariamente riavviare
la macchina, non avendo modo di eseguire nient'altro). La cosa non vale quando
il processo deve fare I/O perché in tal caso anche il processo
\textit{real-time} viene messo in stato di \textit{sleep}, ed in quel momento
altri processi possono essere eseguiti, lasciando così la possibilità di
interromperlo. Se più processi hanno la stessa priorità statica l'ordine di
esecuzione dipende dalla politica di \textit{scheduling} scelta, che può
essere di tipo \textit{Round Robin} (RR), in cui i processi girano a turno per
un tempo fisso, e \textit{First In First Out} (FIFO), in cui vengono eseguiti
nella sequenza in cui sono stati lanciati.

\itindbeg{nice}

Nell'uso normale comunque non si ha bisogno di usare le priorità statiche (che
come accennato sono anche molto rischiose in caso di errori di
programmazione), e ci si affida al normale procedimento di
\textit{scheduling}, basato su un sistema di priorità dinamiche che permette
di ottenere quella che usualmente viene chiamata la ``\textit{fairness}''
nella distribuzione del tempo di CPU. Tralasciando i dettagli\footnote{una
  trattazione più dettagliata si può trovare in sez.~3.3 di \cite{GaPiL}.}
possiamo dire che le priorità dinamiche sono caratterizzate da un valore
iniziale, che è quello che poi si chiama \textit{nice}, che di default è
nullo; più un processo viene eseguito, più il valore di priorità dinamica
aumenta, e lo \textit{scheduler} mette sempre in esecuzione, fra tutti quelli
in stato \textit{runnable}, il processo che ha una priorità dinamica più
bassa.
Questo fa sì che anche i processi che partono da un valore di \textit{nice}
più alto (che viene chiamato così appunto perché i processi che lo usano sono
più ``\textsl{gentili}'' nei confronti degli altri) ottengano alla fine una
possibilità di essere eseguiti, secondo quello che appunto è il meccanismo
chiamato \textit{fairness}.

Il comando che permette di modificare il valore di \textit{nice} di un
processo è appunto \index{comando!\texttt{nice}} \texttt{nice}, che deve
essere usato per lanciare un altro comando, con una sintassi in cui si fa
seguire a \texttt{nice} la linea di comando di cui si vuole cambiare la
priorità di esecuzione.  L'opzione principale è \texttt{-n} (da specificare
prima della riga di comando che si vuole eseguire) che permette di specificare
un valore di \textit{nice} da applicare al programma. Se non si specifica
nulla viene applicato un valore di default pari a 10. Si ricordi che valori
positivi corrispondono ad una diminuzione della priorità. Solo
l'amministratore può anche usare valori negativi, aumentando così la priorità
di un processo, i valori possibili sono comunque limitati all'intervallo fra
19 e -20.

Il comando \texttt{nice} può essere usato solo quando si avvia un programma,
se si vuole cambiare la priorità di un programma già in esecuzione si può
usare il comando \index{comando!\texttt{renice}} \texttt{renice}. In questo
caso la priorità (o meglio il valore di \textit{nice}) deve essere indicato
con il suo valore numerico come primo argomento; si possono specificare il
processo (o i processi) a cui applicare il cambiamento con gli argomenti
successivi.

Il comando \texttt{renice} interpreta tutti gli argomenti successivi al primo
come indicazione dei processi di cui si vuole cambiare la priorità. Il default
è considerare gli argomenti come valori del PID di un processo, cosa che può
essere indicata esplicitamente usando l'opzione \texttt{-p}; con l'opzione
\texttt{-u} si possono selezionare tutti i processi di un singolo utente,
specificato per nome o tramite il suo identificativo. Infine con \texttt{-g}
si possono indicare tutti i processi di uno stesso gruppo (che in genere, come
vedremo in sez.~\ref{sec:struct_job_control}, corrispondono ai comandi
eseguiti su una stessa riga di shell) specificandone il numero di
\textit{process group}.

Al solito si applica la restrizione che solo l'amministratore può applicare
valori negativi, ed aumentare così la priorità di un processo. Si tenga conto
inoltre che a differenza di \texttt{nice}, i valori di priorità impostati con
\texttt{renice} sono assoluti, ed indicano il valore di \textit{nice} da
impostare. Una volta che si è diminuita la priorità di un processo
aumentandone il valore di \textit{nice} un utente normale in teoria non
potrebbe tornare indietro, ma con le versioni recenti del commando questo non
è più vero.\footnote{questo avveniva fino alla versione 2.2.4 della
  \textsl{glibc}, quando è stata modificata la funzione di libreria
  \texttt{nice}, che non chiama più la corrispondente \textit{system call} del
  kernel che ha questo limite, ma usa altre funzioni che consentono un valore
  assoluto, così che anche il comando \texttt{renice} diventa capace di
  diminuire anche per un utente normale un valore di \textit{nice}
  precedentemente aumentato, ma mai al di sotto di quello di partenza.}

\itindend{nice}


\section{Il controllo degli accessi}
\label{sec:struct_access_control}

Come già detto e ripetuto più volte, Linux è nato come sistema multiutente e
nella sua architettura è nativa la possibilità di avere utenti diversi che
lavorano sulla stessa macchina.  Questo ovviamente comporta la necessità di un
meccanismo di controllo degli accessi, che permetta di restringere le capacità
dei singoli utenti in maniera che questi non possano recare danni
(volontariamente o involontariamente che sia) agli altri o al sistema.
Tratteremo qui le basi dei meccanismi di controllo degli accessi, mentre la
gestione degli utenti sarà affrontata più avanti, in
sez.~\ref{sec:users_groups_management}.


\subsection{L'identificazione di utenti e gruppi}
\label{sec:struct_multiuser}

Essendo nato come sistema multiutente, ogni kernel di tipo unix-like come
Linux deve fornire dei meccanismi di identificazione dei vari utenti, sulla
base dei quali poi possa venire imposto un adeguato controllo degli accessi e
delle operazioni che questi possono eseguire all'interno del sistema.

La struttura di sicurezza tradizionale di un sistema unix-like è estremamente
semplice, tanto da essere in certi casi considerata troppo
primitiva.\footnote{sono previste estensioni specifiche, come quelle di
  SELinux (incorporate nel kernel a partire dalle versioni di sviluppo 2.5.x),
  che implementano il \textit{Mandatory Access Control} e la capacità di
  definire in maniera molto più dettagliata i privilegi di accesso,
  sottoponendo anche l'amministratore ad ulteriori restrizioni; questo
  necessita ovviamente di un bel po' di lavoro amministrativo in più per cui
  non sono utilizzate molto spesso.} Essa prevede una distinzione fondamentale
fra l'amministratore del sistema, per il quale non esiste nessuna restrizione,
e tutti gli altri utenti, per i quali invece vengono effettuati vari
controlli, a seconda delle operazioni che vengono richieste.  Tradizionalmente
l'amministratore viene associato all'username ``\textit{root}'', tanto che
questo nome spesso viene usato come sinonimo di amministratore.

Come già accennato in sez.~\ref{sec:struct_proc_property} all'interno del
sistema il kernel identifica ogni utente con un numero identificativo,
chiamato \textit{user ID} o UID. Questo è nullo per l'amministratore e diverso
da zero per tutti gli altri utenti. I controlli vengono effettuati dal kernel
sulla base di questo numero, e \textsl{se} è diverso da zero viene verificato
se corrisponde a quello per cui la richiesta è consentita, e nel caso si nega
o concede l'accesso. Si tenga presente che quello che conta è comunque
l'\textit{user ID}, non il nome utente, questo infatti è solo un'etichetta che
potrebbe essere qualunque (torneremo sull'argomento in
sez.~\ref{sec:users_groups_management}).

Si noti inoltre il precedente \textsl{se}, qualora l'\textit{user ID} del
processo sia nullo il controllo non viene neanche effettuato: è per questo che
\textit{root} è sempre in grado di compiere qualunque operazione, ed è per
questo che occorre evitare assolutamente l'uso di \textit{root} per qualunque
compito che non sia strettamente connesso all'amministrazione del sistema: un
comando sbagliato che sarebbe innocuo se dato da un utente normale potrebbe
distruggere completamente il sistema se dato da \textit{root}.

Tutti i sistemi unix-like prevedono una procedura di autenticazione che
permette di riconoscere l'utente che si collega al sistema.  Questa nella sua
forma più elementare, per l'accesso da una \textit{console}\footnote{un tempo
  si indicava con questo nome il terminale privilegiato da cui si potevano
  eseguire i compiti amministrativi, in genere collegato direttamente al
  computer stesso; oggi in pratica i compiti amministrativi si possono
  effettuare da qualunque terminale, per cui \textit{console} è diventato
  sostanzialmente un sinonimo di terminale.} testuale, viene effettuata dal
programma \texttt{login}, che in base al nome che identifica un utente di
fronte al sistema (il cosiddetto \textit{username}, o \textsl{nome di login})
richiede l'immissione di una password ad esso associata, che permette di
verificarne l'identità.

Come vedremo con maggiori dettagli in sez.~\ref{sec:users_groups_management},
dove tratteremo la configurazione della procedura di login e le modalità per
gestire utenti e gruppi, ciascun \textit{username} è abbinato ad un
\textit{user ID},\footnote{questa funzionalità viene fornita direttamente
  dalle librerie fondamentali del sistema (le \textsl{glibc}) tramite il
  cosiddetto \textit{Name Service Switch} (vedi
  sez.~\ref{sec:base_nsswitch_conf}).} che sarà quello che verrà utilizzato
dal kernel per tutti i programmi che l'utente lancerà una volta entrato nel
sistema. I comandi invece, per una maggiore leggibilità, riportano l'identità
dell'utente utilizzando il suo \textit{username}, molti di essi comunque (come
\texttt{ls}) supportano l'uso di opportune opzioni (nel caso \texttt{-n}) per
stampare il valore numerico dell'\textit{user ID} al posto
dell'\textit{username}.

\index{gruppo~principale|(} 
\index{gruppo~primario|(} 

Gli utenti poi possono venire raggruppati in \textsl{gruppi}; come per gli
utenti ogni gruppo ha un nome (detto \textit{groupname}) ed un corrispondente
identificatore numerico, il \textit{group ID} o GID. Inoltre ad ogni utente è
sempre associato almeno un \textsl{gruppo}, detto \textsl{gruppo primario} o
\textsl{gruppo principale}, che è quello che viene usato anche come
\textit{group ID} associato al processo di cui abbiamo parlato in
sez.~\ref{sec:struct_proc_property}.

Di norma si fa sì che questo gruppo contenga come membro solo l'utente in
questione e abbia nome uguale all'username, per dare un gruppo specifico ai
file personali dell'utente dato che questo è il gruppo che viene usato nella
creazione di nuovi file (torneremo sull'argomento in
sez.~\ref{sec:struct_file_perm}). In generale però un utente può appartenere
ad un numero qualunque di ulteriori gruppi, detti \index{gruppo~ausiliario}
\textit{gruppi ausiliari}; diventa così possibile permettere l'accesso a delle
risorse comuni a tutti gli utenti che fanno parte dello stesso gruppo.

\index{gruppo~principale|)} 
\index{gruppo~primario|)} 

Ogni processo, quando viene lanciato, eredita dal padre l'informazione
relativa all'utente per conto del quale viene eseguito e di tutti i gruppi a
cui questo appartiene. In questo modo una volta entrati nel sistema tutti i
programmi verranno eseguiti per conto dell'utente che ha effettuato la
procedura di login. Il sistema può così provvedere al controllo degli accessi,
e porre una serie di limitazioni a quello che l'utente può fare, impedendo
l'esecuzione di tutte le operazioni non consentite. Si evita così che utenti
diversi possano danneggiarsi fra loro o danneggiare il sistema.

In realtà, come già accennato in sez.~\ref{sec:struct_proc_property}, il
kernel mantiene diverse versioni di questi identificatori; la trattazione
esatta di tutti i particolari va al di là dello scopo di questo
testo,\footnote{come già detto gli interessati possono trovare una trattazione
  dell'argomento nella sezione 3.3 di \cite{GaPiL}.} per quanto ci interessa
qui basta citare le due versioni principali, quella degli indicatori
cosiddetti \textsl{effettivi} (cioè l'\textit{effective user ID} e
l'\textit{effective group ID}) che vengono usati per le verifiche sul
controllo d'accesso e quelli cosiddetti \textsl{reali} (cioè il \textit{real
  user ID} ed il \textit{real group ID}) che identificano chi ha lanciato il
processo. In generale questi due gruppi di identificatori sono sempre identici
fra loro, a meno che non si sia usato un programma con i permessi speciali
\textit{set user ID} o \textit{set group ID}, come vedremo più avanti in
sez.~\ref{sec:struct_file_perm}.


\subsection{I permessi dei file}
\label{sec:struct_file_perm}

La gestione dei permessi dei file in un sistema unix-like è tutto sommato
abbastanza elementare; esistono estensioni\footnote{come le ACL
  (\textit{Access Control List}), introdotte ufficialmente a partire dai
  kernel 2.6, o altri meccanismi specialistici ancora più sofisticati (come
  SELinux, cui abbiamo già accennato).} che permettono di renderla più sottile
e flessibile, ma nella maggior parte dei casi il controllo di accesso standard
è più che sufficiente.  In sostanza per il sistema esistono tre livelli di
privilegi:
\begin{itemize*}
\item i privilegi dell'utente, indicati con la lettera \texttt{u},
  (dall'inglese \textit{user}).
\item i privilegi del gruppo, indicati con la lettera \texttt{g},
  (dall'inglese \textit{group}).
\item i privilegi di tutti gli altri, indicati con la lettera \texttt{o},
  (dall'inglese \textit{other}).
\end{itemize*}
e tre permessi base:
\begin{itemize*}
\item permesso di lettura, indicato con la lettera \texttt{r}, (dall'inglese
  \textit{read}).
\item permesso di scrittura, indicato con la lettera \texttt{w}, (dall'inglese
  \textit{write}).
\item permesso di esecuzione, indicato con la lettera \texttt{x},
  (dall'inglese \textit{execute}).
\end{itemize*}
il cui significato è abbastanza ovvio.\footnote{almeno fintanto che si fa
  riferimento ad un file normale, vedremo a breve che le cose cambiano quando
  si tratta di directory, link simbolici o dispositivi.}

Ogni file è associato ad un utente, che è detto \textsl{proprietario} del file
e ad un gruppo (detto a sua volta \textsl{gruppo proprietario}), per ciascuno
dei tre livelli di privilegio (utente, gruppo e altri) è possibile specificare
uno dei tre permessi (lettura, scrittura, esecuzione). Questi vengono
riportati nella versione estesa dell'output del comando \texttt{ls}:
\begin{Console}
piccardi@anarres:~/GaPiL$ \textbf{ls -l}
total 2996
-rw-r--r-- 1 piccardi piccardi     67 Feb  9 17:01 AUTHORS
-rw-r--r-- 1 piccardi piccardi   8436 Feb  9 17:01 biblio.bib
-rw-r--r-- 1 piccardi piccardi  29247 Feb  9 17:01 build.tex
-rw-r--r-- 1 piccardi piccardi   7286 Feb  9 17:01 ChangeLog
-rw-r--r-- 1 piccardi piccardi  29941 Feb  9 17:01 errors.tex
-rw-r--r-- 1 piccardi piccardi  17277 Feb  9 17:01 fdl.tex
-rw-r--r-- 1 piccardi piccardi 297727 Feb  9 17:01 fileadv.tex
-rw-r--r-- 1 piccardi piccardi 415730 Feb  9 17:01 filedir.tex
-rw-r--r-- 1 piccardi piccardi 205773 Feb  9 17:01 fileio.tex
-rw-r--r-- 1 piccardi piccardi   5117 Feb  9 17:01 gapil.tex
drwxr-xr-x 3 piccardi piccardi   4096 Feb  9 17:01 htgapil
-rw-r--r-- 1 piccardi piccardi   7592 Feb  9 17:01 htgapil.cfg
-rwxr-xr-x 1 piccardi piccardi    175 Feb  9 17:01 htmakeindex.sh
drwxr-xr-x 3 piccardi piccardi   4096 Feb  9 17:01 html
-rwxr-xr-x 1 piccardi piccardi   2256 Feb  9 17:01 htmlize.sh
drwxr-xr-x 3 piccardi piccardi   4096 Feb  9 17:01 img
-rw-r--r-- 1 piccardi piccardi  84338 Feb  9 17:01 intro.tex
...
\end{Console}
%$
che ci mostra nella prima colonna i permessi secondo lo schema riportato in
fig.~\ref{fig:permessi}. La lettura dell'output di questo comando ci permette
di vedere che i sorgenti dei programmi contenuti nella directory in oggetto
hanno quelli che sono in genere i permessi di default per i file di dati, si
ha cioè il permesso di scrittura solo per il proprietario, quello di lettura
per tutti quanti (proprietario, gruppo e altri) e l'assenza completa del
permesso di esecuzione.

\begin{figure}[htb]
  \centering
  \includegraphics[width=6cm]{images/permission}
  \caption{Legenda dei permessi dell'output di \texttt{ls}.}
  \label{fig:permessi}
\end{figure}

Nel caso di un programma o uno script (tratteremo gli script in
sez.~\ref{sec:shell_scripting}) invece i permessi di default sono diversi,
come per \texttt{htmlize.sh} nell'esempio precedente, ed oltre a quelli
presenti per i normali file di dati si ha anche il permesso di esecuzione, che
è abilitato per il proprietario, per il gruppo e per tutti gli altri.

In generale un utente potrà effettuare solo le azioni per le quali ha i
permessi, nel caso dei permessi appena illustrati questo comporta che un
utente può leggere i file di un altro ma non può modificarli o cancellarli. In
realtà il meccanismo del controllo è abbastanza peculiare, e questo, se non
capito fino in fondo, può dar luogo a qualche confusione.\footnote{per una
  trattazione dettagliata si consultino sez.~3.2 e 4.4 di \cite{GaPiL}.} La
verifica dei permessi di accesso ad un file prevede infatti i seguenti passi,
eseguiti esattamente in questa sequenza:
\begin{enumerate*}
\item se il processo viene eseguito dall'amministratore l'accesso viene sempre
  garantito, senza che sia eseguito nessun controllo;
\item se il processo viene eseguito dal proprietario del file allora:
  \begin{itemize*}
  \item vengono controllati i permessi corrispondenti all'utente (i primi tre
    di fig.~\ref{fig:permessi}), e se questi sono assegnati per l'operazione
    richiesta, l'accesso è consentito;
  \item altrimenti l'accesso è negato;
  \end{itemize*}
\item se il processo viene eseguito da un utente che appartiene al gruppo
  proprietario del file allora:
  \begin{itemize*}
  \item vengono controllati i permessi corrispondenti al gruppo (i centrali in
    fig.~\ref{fig:permessi}), e se questi sono assegnati per l'operazione
    richiesta, l'accesso è consentito;
  \item altrimenti l'accesso è negato;
  \end{itemize*}
\item se il processo viene eseguito da un qualunque altro utente allora:
  \begin{itemize*}
  \item vengono controllati i permessi corrispondenti a tutti gli altri (gli
    ultimi di fig.~\ref{fig:permessi}), e se questi sono assegnati per
    l'operazione richiesta, l'accesso è consentito;
  \item altrimenti l'accesso è negato.
  \end{itemize*}
\end{enumerate*}

Si noti bene come in questa sequenza di controlli, una volta che la decisione
riguardo l'accesso è presa, i passi successivi non vengono più eseguiti.
Tutto ciò significa ad esempio che se un utente non ha il permesso di
scrittura per un proprio file, questi non potrà scriverci, anche qualora il
permesso di scrittura per il gruppo o per tutti gli altri fossero garantiti.

Questo avviene perché il permesso relativo all'utente proprietario viene
controllato per primo, e se l'accesso viene negato i permessi successivi non
vengono controllati. Questo spiega anche perché il permesso indicato con
``\texttt{o}'' si chiama \textsl{per tutti gli altri}, e non semplicemente per
tutti: esso infatti verrà applicato soltanto per gli utenti che non sono il
proprietario e non appartengono al gruppo proprietario.

Vale la pena anche sottolineare di nuovo come i controlli siano eseguiti per
tutti gli utenti eccetto l'amministratore, che non è soggetto a nessun tipo di
restrizione e può quindi eseguire qualunque operazione. In genere ogni
distribuzione fa sì che tutti i file di configurazione ed i programmi
installati nel sistema appartengano a \textit{root}, cosicché diventa
impossibile per un utente normale poter danneggiare (accidentalmente o meno)
gli stessi.\footnote{questa è una delle ragioni per cui i virus sono molto più
  difficili da fare con Linux: non essendo possibile ad un utente normale
  modificare i file di sistema, un virus potrà al più ``\textsl{infettare}'' i
  file di quell'utente, cosa che rende molto più difficile la sua diffusione.}

Fin qui si è dato abbastanza per scontato il significato dei tre permessi di
lettura, scrittura ed esecuzione, fra l'altro facendo riferimento solo a file
normali (cioè ai \textit{regular file} di tab.~\ref{tab:file_file_types}). In
realtà anche in questo caso il funzionamento del sistema ha alcune
sottigliezze che occorre approfondire.  Anzitutto bisogna chiarire che i
suddetti permessi si applicano al \textsl{contenuto} del file: il permesso di
lettura significa che se ne può leggere il contenuto, quello di scrittura che
se ne può modificare il contenuto, e quello di esecuzione che se ne può
eseguire il contenuto (il che si traduce nel poter lanciare il programma).

Il fatto che i permessi facciano riferimento al contenuto di un file ha delle
precise conseguenze, ad esempio avere il permesso di scrittura su un file non
significa che se ne possano cambiare i permessi, perché questi, come accennato
in sez.~\ref{sec:struct_filesystem_arch}, sono mantenuti nell'\textit{inode} e
non hanno perciò nulla a che fare con il suo contenuto.  Il sistema infatti
prevede che solo il proprietario di un file possa modificarne i permessi (con
il comando \texttt{chmod}, che vedremo in
sez.~\ref{sec:struct_file_perm_comm}) e la cosa è del tutto indipendente dai
permessi che detto file può avere, il che consente al proprietario, anche
qualora non avesse un certo permesso su un file (come nell'esempio precedente
per la scrittura) di riassegnarselo.

I permessi inoltre hanno un significato leggermente diverso quando si
applicano agli altri tipi di file illustrati in
tab.~\ref{tab:file_file_types}. Nel caso di file di dispositivo, \textit{fifo}
e \textit{socket} ad esempio il permesso di esecuzione è ignorato, mentre per
i link simbolici tutti i permessi sono totalmente ignorati (è questo il motivo
per cui un collegamento simbolico li presenta come tutti attivi) e quelli che
vengono presi in considerazione sono quelli del file a cui il collegamento fa
riferimento.

Le differenze maggiori però si ritrovano per le directory. Alcune di queste
differenze in realtà sono minori di quel che possono sembrare ed il
significato dei permessi si può capire subito se si tiene presente che, come
illustrato in sez.~\ref{sec:struct_filesystem_arch}, le directory non sono
altro che dei file di tipo speciale il cui contenuto è semplicemente una lista
di nomi associati ad un riferimento ai rispettivi \textit{inode}. Questo ci
dice che il permesso di lettura per una directory si traduce semplicemente
nella possibilità di leggere, e quindi visualizzare, la lista dei file in essa
contenuti.

Un po' meno intuitivo, se non altro nei suoi effetti, è il permesso di
scrittura per una directory. Di nuovo questo significa semplicemente che si
può scrivere nel suo contenuto, il che si traduce nel fatto che si può
aggiungere una voce alla lista, per creare un file, o toglierla, per
cancellarlo.\footnote{si ricordi infatti che, come illustrato in
  sez.~\ref{sec:struct_filesystem_arch}, la cancellazione di un file consiste
  semplicemente nella rimozione del riferimento al relativo \textit{inode}
  presente nella directory.} È in particolare questa seconda possibilità che
normalmente lascia perplesso chi si accosta le prime volte a Linux perché, a
differenza di altri sistemi operativi, non esiste un permesso specifico per
cancellare un file.  Per tale operazione infatti è sufficiente avere il
permesso di scrittura sulla directory che lo contiene, infatti è questa che
viene modificata, e si noti come l'operazione sia del tutto indipendente da
quelli che possono essere i permessi del file, che nel caso non contano
niente.

Il più complesso da capire resta comunque il permesso di esecuzione che
normalmente, come per la directory \texttt{img} dell'esempio precedente, è
sempre presente.  Le directory non sono programmi ed ovviamente
``\textsl{eseguire}'' una lista di file non ha nessun significato. Il kernel
perciò usa questo permesso dandogli un significato particolare, che è quello
di poter ``\textsl{attraversare}'' la directory nella risoluzione del nome di
un file.  

Se cioè manca il permesso di esecuzione, indipendentemente da quali possano
essere i permessi impostati sui file e le directory in essa contenuti, questi
non saranno più accessibili, dato che non sarà possibile attraversarla per
raggiungerli, il che significa che eliminando il permesso di esecuzione su una
directory si preclude l'accesso all'intero ramo dell'albero dei file posto al
di sotto di essa. Si tenga presente che tutto ciò resta valido anche in
presenza del permesso di lettura sulla directory, che significa solo che è
possibile elencarne il contenuto.

Ci si può chiedere a cosa serva questa separazione fra il permesso di vedere
il contenuto di una directory ed il permesso di poterla attraversare; esistono
però casi in cui si può voler consentire a degli utenti (in genere
appartenenti ad un certo gruppo) di accedere a dei file (di cui conoscono il
nome) all'interno di una directory condivisa, ma non si vuole che questi
possano vedere se ci sono anche file di altri. Un esempio di tutto ciò è la
directory \texttt{/etc/ssl/private}, i cui permessi sono:
\begin{Console}
piccardi@anarres:~$ \textbf{ls -ld /etc/ssl/private/}
drwx--x--- 2 root ssl-cert 1024 2007-10-18 12:54 /etc/ssl/private
\end{Console} 
%$
che permette agli utenti del gruppo \texttt{ssl-cert} di accedere ai file
creati sotto tale directory ma non di vederne il contenuto. La directory è
creata dal pacchetto \texttt{openssl} per contenere le chiavi dei certificati
digitali,\footnote{i dettagli di SSL vanno al di là di quanto sia possibile
  affrontare qui, per una trattazione dell'argomento si veda sez.~2.1 di
  \cite{SGL}.} e viene impostata con questi permessi per far sì che un utente
possa accedere alle proprie chiavi, ma non possa sapere se ve ne sono anche di
altri utenti.

\itindbeg{suid}  
\itindbeg{sgid}

Fino ad adesso si sono trattati soltanto i permessi ordinari, a questi però in
tutti i sistemi unix-like sono stati aggiunti tre \textsl{permessi speciali}
che permettono di rendere più flessibile una infrastruttura che, se fosse
stata limitata soltanto a quegli ordinari, sarebbe stata troppo limitata. Dal
punto di vista del kernel ciascun permesso corrisponde ad un bit in una
apposita variabile mantenuta nell'\textit{inode} (vedi
sez.~\ref{sec:struct_filesystem_arch}) del file.  I bit usati per i permessi
sono in tutto 12; i primi nove sono quelli già illustrati in
fig.~\ref{fig:permessi}, gli altri tre vengono chiamati col nome assegnato al
rispettivo bit, e cioè: \textit{suid bit}, \textit{sgid bit} e \textit{sticky
  bit}.

Questi tre permessi aggiuntivi nascono per modificare il comportamento del
sistema nell'esecuzione dei programmi. Per questo normalmente sono sempre
abbinati al permesso di esecuzione,\footnote{con l'eccezione del cosiddetto
  \textit{mandatory locking}, una estensione ripresa da SysV su cui potete
  trovare maggiori dettagli in sez.~10.1.5 di \cite{GaPiL}, che viene attivato
  impostando lo \itindex{sgid} \textit{sgid bit} su un file non eseguibile.}
ed hanno effetto solo se vengono applicati a dei binari eseguibili (nel caso
siano presenti su uno script come misura di sicurezza vengono ignorati). I più
importanti sono i primi due che servono per consentire ad un programma di
eseguire delle operazioni che nel caso generico sarebbero riservate al solo
amministratore.

Il sistema infatti quando esegue un programma lo fa sempre con i permessi
dell'utente che lo ha lanciato, il che significa, per riprendere quanto
illustrato in sez.~\ref{sec:struct_multiuser}, che gli identificativi
\textit{real} ed \textit{effective} di utente e gruppo del nuovo processo
coincidono con quelli del processo che lo ha creato. Per consentire ad un
processo lanciato da un utente normale di eseguire degli accessi che i
permessi normalmente gli impedirebbero, è possibile, impostando
rispettivamente il \textit{suid bit} o lo \textit{sgid bit} su un programma,
far sì che quest'ultimo venga eseguito rispettivamente con i privilegi
dell'utente e del gruppo a cui appartiene. Questo è ovviamente pericoloso,
dato che questi privilegi possono essere maggiori di quelli di un utente
normale, è pertanto assolutamente inopportuno impostare questi permessi su un
programma senza sapere esattamente cosa si sta facendo.

Tutto questo viene realizzato dal kernel che quando trova questi permessi
attivi per un programma lo pone in esecuzione impostando per il corrispondente
processo l'\textit{effective user ID} (se \textit{suid}) o l'\textit{effective
  group ID} (se \textit{sgid}) rispettivamente a quello corrispondente
all'utente o al gruppo proprietario del file.  Dato che gli identificativi del
gruppo \textit{effective} sono quelli usati nel controllo degli accessi, tutto
ciò fa sì che il programma risulti avere i privilegi di tale utente o gruppo.
Gli identificativi del gruppo \textit{real} però resteranno gli stessi, e cioè
quelli dell'utente che ha eseguito il programma, il quale sarà in grado di
accorgersi di essere stato lanciato da un utente normale.

Con l'uso di questi permessi si possono far eseguire anche ad un utente
normale delle operazioni che nel caso generico sarebbero riservate al solo
amministratore.  Questo ad esempio è il modo in cui funziona il comando
\texttt{passwd}, che ha il bit \textit{suid bit} impostato ed appartiene
all'amministratore.  Se usato direttamente da questi il programma (che
verifica quale sia l'utente che l'ha posto in esecuzione controllando il
\textit{real user ID}) non pone restrizioni e permette di cambiare la password
a qualunque utente.  Se invece viene usato da un utente normale il programma
consente ancora di modificare la password, ma solo la propria e fornendo prima
quella corrente.  Per poter eseguire la modifica della password
\texttt{passwd} necessita dell'accesso in scrittura al file dove questa viene
memorizzata (che, vedi sez.~\ref{sec:cfg_user_db}, è di proprietà
dell'amministratore) e questo viene garantito appunto grazie all'uso del
\textit{suid bit}.

\itindbeg{sticky}

Per i file lo \textit{sticky bit} al giorno d'oggi è sostanzialmente
inutilizzato e su Linux viene ignorato. Veniva usato nelle prime versioni di
Unix, quando memoria e disco erano risorse molto scarse e gli algoritmi per la
memoria virtuale poco raffinati, per dare ad un programma un accesso
privilegiato all'uso della \textit{swap}. Per i programmi con questo permesso
attivo (era usato per quelli di uso più frequente) il codice veniva mantenuto
in permanenza nella \textit{swap} per diminuire il tempo di caricamento, cosa
da cui deriva il nome \textit{sticky}. Oggi tutto ciò non è più necessario,
per cui detto permesso viene ignorato, ha assunto però, come vedremo a breve,
un significato speciale per le directory.

Al contrario di quanto avviene con i permessi normali, i permessi speciali non
hanno a disposizione una propria posizione nell'output di \texttt{ls}, ma
quando attivati cambiano il valore della lettera associata al permesso di
esecuzione.  In particolare se il \textit{suid bit} o lo \textit{sgid bit}
sono attivi verrà rispettivamente mostrata una ``\texttt{s}'' nella posizione
del permesso di esecuzione per utente e gruppo, o una ``\texttt{S}'' qualora
il corrispondente permesso di esecuzione non sia attivo.  Lo \textit{sticky
  bit} invece modifica la lettera che indica il permesso di esecuzione per
tutti gli altri in una ``\texttt{t}'' che come per i precedenti diventa una
``\texttt{T}'' qualora il corrispondente permesso di esecuzione non sia
attivo. Nel caso di \texttt{passwd} avremo allora:
\begin{Console}
piccardi@anarres:~$ \textbf{ls -l /usr/bin/passwd}
-rwsr-xr-x 1 root root 29036 2007-10-30 19:32 /usr/bin/passwd
\end{Console} 
%$

Abbiamo visto come i permessi speciali consentano di modificare il
comportamento del kernel nell'esecuzione dei programmi, essi però non hanno
nessun effetto su file di dispositivo, \textit{fifo} o \textit{socket}, per i
quali vengono ignorati. Per le directory invece il discorso è diverso, il
\textit{suid bit} viene sempre ignorato, ma lo \textit{sgid bit} e lo
\textit{sticky bit} vengono utilizzati, ed assumono un significato
particolare.

Lo \textit{sgid bit} viene utilizzato per modificare il comportamento
ordinario del kernel nella creazione di nuovi file. Il sistema infatti prevede
che quando un processo crea un nuovo file o directory, file di dispositivo,
ecc. a questo vengano assegnati come proprietario e gruppo proprietario
rispettivamente \textit{user ID} ed \textit{group ID} del processo stesso, in
cui quest'ultimo corrisponde di solito al gruppo principale dell'utente. Se
però si è attivato lo \textit{sgid bit} nella directory in cui si va a creare
il file a questi sarà assegnato come gruppo proprietario quello della
directory stessa e non quello del processo. In questo modo si può far sì che
il gruppo proprietario di una directory si propaghi automaticamente a tutti i
file che vengono creati al suo interno.

Anche lo \textit{sticky bit} assume un significato particolare per le
directory: se esso è presente allora un file potrà essere cancellato solo
dall'utente a cui appartiene o dal proprietario della directory stessa, anche
qualora si abbia su di essa il permesso di scrittura.  Questa ad esempio è la
modalità in cui viene protetta la directory \texttt{/tmp}, i cui permessi sono
i seguenti:
\begin{Console}
piccardi@anarres:~$ \textbf{ls -ld /tmp}
drwxrwxrwt 18 root root 155648 2008-01-08 18:38 /tmp
\end{Console} 
%$
si noti come questi permessi consentono a chiunque di scrivere sulla directory
\texttt{/tmp} per crearvi i propri file, come è dovuto, essendo questa la
directory messa a disposizione degli utenti per la creazione di file
temporanei come abbiamo visto sez.~\ref{sec:file_FHS}.

Il permesso di scrittura consentirebbe anche la cancellazione arbitraria degli
stessi file, ma la presenza contemporanea dello \textit{sticky bit} fa sì che
un utente sia in grado di cancellare solo i file che ha creato lui senza poter
interferire con quelli creati dagli altri utenti. Questa è una misura
necessaria, perché si deve sempre ricordare che, a parte questa eccezione,
qualunque siano i permessi dati ad un file sarà sempre possibile cancellarlo
se si ha il permesso di scrittura sulla directory che lo contiene.

\itindend{suid}  
\itindend{sgid}
\itindend{sticky}



\subsection{La gestione dei permessi dei file}
\label{sec:struct_file_perm_comm}

Come accennato in precedenza ciascun permesso corrisponde ad uno specifico bit
di una variabile che viene mantenuta nell'\textit{inode} del file insieme a
tutte le altre proprietà dello stesso. Assegnare un permesso significa
attivare il bit ad esso associato in questa variabile. La disposizione
completa dei bit dei permessi, compresi quelli relativi ai permessi speciali,
è riportata in fig.~\ref{fig:struct_bit_permission}.

\begin{figure}[htb]
  \centering
  \includegraphics[width=7cm]{images/perm_complete}
  \caption{Schema dei bit dei permessi mantenuti nell'\textit{inode}.}
  \label{fig:struct_bit_permission}
\end{figure}

Sfruttando questa disposizione è possibile utilizzare una notazione compatta
che esprima lo stato dei permessi usando il valore di questa variabile. Dato
che i permessi sono raggruppati a blocchi di tre bit, risulta naturale
esprimere questo valore in notazione ottale,vale a dire con numeri in base 8,
con le cifre che vanno da 0 a 7, in modo che ciascuna cifra corrisponda ad un
gruppo di permessi. Se si fa riferimento allo schema di
fig.~\ref{fig:struct_bit_permission}, in questo modo si avrà che, partendo
dalla meno significativa, la prima cifra esprime il valore dei permessi per
gli altri, la seconda quello dei permessi per il gruppo, e la terza quello dei
permessi per il proprietario. Con questa notazione allora i permessi presenti
nel caso illustrato in fig.~\ref{fig:struct_bit_permission} si possono
indicare con la cifra \texttt{750}.

Qualora serva specificare anche uno dei permessi speciali, occorrerà usare
anche la quarta cifra, se di nuovo si fa riferimento allo specchietto di
fig.~\ref{fig:struct_bit_permission}, e lo si confronta con i permessi del
comando \texttt{passwd} che si sono visti in precedenza, considerato che
questo ha attivo il bit \textit{suid}, si otterrà che questi si possono
esprimere con il valore \texttt{4755}. Per la sua compattezza questa
notazione, nonostante costringa l'utente a fare un po' di conti in binario ed
ottale, è molto utilizzata, ed una volta che ci si è abituati, finisce in
genere anche col risultare più immediata di quella ordinaria, che, come
vedremo più avanti, è basata sull'uso delle lettere che indicano livello e
tipo riportate all'inizio di sez.~\ref{sec:struct_file_perm}.

Prima di illustrare il funzionamento dei comandi che consentono la
manipolazione dei permessi dei file conviene esaminare meglio le modalità con
cui questi vengono assegnati ai nuovi file e directory che vengono creati.
Abbiamo visto in sez.~\ref{sec:struct_file_perm} come vengono assegnati di
default l'utente ed il gruppo proprietario, ci resta da vedere come vengono
assegnati i permessi.  Questi dipendono in maniera diretta dalle modalità con
cui i programmi creano i file, e da quali funzioni di sistema essi
utilizzano.

Il kernel prevede comunque una modalità per controllare i permessi assegnati
di default. Il sistema prevede che si parta da uno stato in cui alla creazione
di un nuovo file i permessi di lettura e scrittura sono attivati per
\textsl{tutti}, dove con tutti qui si vuole intendere sia il proprietario, che
il gruppo, che tutti gli altri. Si parte cioè da dei permessi espressi in
forma numerica dal valore ottale di \texttt{666}.  Per la creazione di una
nuova directory invece lo stato di partenza prevede anche l'assegnazione del
permesso di esecuzione, con un valore corrispondente a \texttt{777}.

\index{umask|(}

Ovviamente lasciare aperti a chiunque i permessi di scrittura non è cosa molto
saggia dal punto di vista della sicurezza. Per questo motivo il kernel
mantiene per ogni processo una proprietà, chiamata \textit{umask}, che viene
ereditata nella creazione di un processo figlio. La \textit{umask} specifica
una maschera di bit che serve ad indicare quali permessi devono essere rimossi
alla creazione di un nuovo file o directory.  Il formato in cui si specifica
la maschera è lo stesso utilizzato per i bit dei permessi ed illustrato in
fig.~\ref{fig:struct_bit_permission}, solo che in questo caso il valore
indicherà quali sono i bit da togliere.

In genere la \textit{umask} viene impostata negli script eseguiti al
\textit{login} grazie al comando \index{comando!built-in!\texttt{umask}}
\texttt{umask}.  Dato che il valore viene ereditato nella creazione dei
processi figli è sufficiente farlo all'avvio perché quanto scelto sia
mantenuto anche in seguito.  Un utente può comunque modificare il valore di
questo parametro invocando direttamente il comando \texttt{umask}\footnote{si
  tenga presente che questo è un comando interno della shell (vedremo il
  significato di ciò in sez.~\ref{sec:shell_sintax}), dato che l'invocazione
  di un altro programma non servirebbe a nulla, in quanto la \textit{system
    call} che esegue l'operazione opera solo sul processo corrente.} per
impostare un nuovo valore, da passare come argomento.

Il valore dell'argomento di \texttt{umask} può essere specificato sia in forma
numerica (con un valore ottale) che in forma simbolica, con una notazione
identica a quella di \texttt{chmod}, che tratteremo a breve.  In questo
secondo caso però si dovranno indicare quali sono i permessi da
\textsl{conservare}, se si usa un valore numerico infatti questo viene
impostato direttamente come \textit{umask} del processo, per cui vi si
indicano i permessi da togliere, il valore simbolico invece viene usato per
indicare quali permessi devono restare. Se invocato senza argomenti il comando
permette di visualizzare il valore corrente della \textit{umask}, e con
l'opzione \texttt{-S} ne stampa il valore in forma simbolica anziché
numerica. Di norma un utente personalizza questo valore negli script di avvio
della shell (vedi sez.~\ref{sec:shell_scripting}).

Il valore di default per la \textit{umask} usato dalla gran parte delle
distribuzioni è di \texttt{022}; questo significa che i permessi di scrittura
relativi al gruppo e a tutti gli altri sono cancellati alla creazione di un
nuovo file o directory: i nuovi file saranno creati cioè con permessi
\texttt{644} (lettura e scrittura per il proprietario e sola lettura per il
gruppo e gli altri), mentre le nuove directory saranno create con permessi
\texttt{755} (tutti i permessi per il proprietario ma solo lettura e
attraversamento per il gruppo e gli altri).  Se ad esempio si fossero voluti
cancellare completamente i permessi per tutti gli altri, si sarebbe dovuta
usare una \textit{umask} di \texttt{027}.

\index{umask|)}

Il comando che permette di modificare direttamente i permessi di file e
directory è \index{comando!\texttt{chmod}} \texttt{chmod}. Nella sua forma più
elementare esso prende come argomenti il valore numerico dei permessi
(espresso in forma ottale) seguito dal nome o dalla lista dei nomi di file e
directory cui applicarli. Come accennato però le operazioni di modifica dei
permessi possono essere espresse anche in forma simbolica, utilizzando un
formato comune che viene usato da tutti i comandi che operano sui permessi.
Questo formato prevede che una operazione (o un valore di un permesso) possano
essere specificati tramite una opportuna stringa di caratteri divisa in tre
parti, nella forma:
\begin{Example}
[set][operator][permission]
\end{Example}

La prima parte della stringa, \textit{set}, specifica a quale gruppo di
permessi si fa riferimento. Si può usare il carattere ``\texttt{u}''
(\textit{user}) per indicare quelli relativi al proprietario, il carattere
``\texttt{g}'' (\textit{group}) per indicare quelli relativi al gruppo ed il
carattere ``\texttt{o}'' (\textit{others}) per indicare tutti gli altri.
Inoltre con il carattere ``\texttt{a}'' (\textit{all}) si possono indicare in
un colpo solo proprietario, gruppo e tutti gli altri. Se non si indica nulla
si ha lo stesso effetto di ``\texttt{a}'', a meno che fra quelli indicati non
vi siano permessi non consentiti dalla \textit{umask}, che non verranno
impostati.  La notazione prevede anche che si possano usare più caratteri per
specificare più insiemi a cui assegnare gli stessi permessi: ad esempio con
\texttt{ug} si indicherà di operare sui permessi del proprietario e del gruppo
proprietario.

La seconda parte della stringa, \textit{operator}, indica il tipo di modifica
che si vuole effettuare, questa prevede l'uso di un singolo carattere che
serve appunto da \textsl{operatore}. I caratteri consentiti in questa parte
sono tre: con ``\texttt{+}'' si richiede l'aggiunta di un permesso a quelli
già presenti, con ``\texttt{-}'' si richiede la rimozione di un permesso da
quelli presenti, mentre con ``\texttt{=}'' si indicano esattamente quali sono
i permessi da assegnare, vale a dire che saranno assegnati esattamente quelli
indicati, mentre quelli non indicati saranno rimossi.

L'ultima parte, \textit{permission}, serve ad indicare quali permessi devono
essere applicati (aggiunti, rimossi o impostati). Per i permessi ordinari si
possono usare i caratteri ``\texttt{w}'' per il permesso di scrittura,
``\texttt{r}'' per il permesso di lettura e ``\texttt{x}'' per il permesso di
esecuzione.  Quando si opera sugli insiemi di proprietario e gruppo
proprietario il carattere ``\texttt{s}'' permette di impostare i
corrispondenti bit \textit{suid} e \textit{sgid}, infine con il carattere
``\texttt{t}'' si può impostare lo \textit{sticky bit}.

Così ad esempio \texttt{a+x} aggiunge il permesso di esecuzione per tutti,
\texttt{o-r} toglie il permesso di lettura per gli altri, \texttt{g+w}
aggiunge il permesso di scrittura al gruppo proprietario, \texttt{u=rw}
imposta i permessi di lettura e scrittura per il proprietario (eliminando un
eventuale permesso di esecuzione) e \texttt{u+s} attiva il \textit{suid
  bit}. Infine si tenga presente che si possono anche combinare insieme più
espressioni come le precedenti, scrivendole in una sequenza separata da
virgole: così ad esempio con \texttt{g+w,o-r} si abilita la scrittura per il
gruppo proprietario e si disabilita la lettura per tutti gli altri.

Si ricordi che un utente può cambiare i permessi solo dei file che gli
appartengono e che il permesso di scrittura in questo caso non significa nulla
in quanto si applica solo al contenuto del file e non alle sue proprietà.
Inoltre se si usa \texttt{chmod} su un collegamento simbolico l'operazione
verrà eseguita sul file referenziato dal link,\footnote{si ricordi che i
  permessi di un link non hanno alcun significato e pertanto non avrebbe senso
  cambiarli.} e valgono quindi le credenziali di quest'ultimo, questo
significa che anche se il link vi appartiene non potete cambiare i permessi
del file a cui esso fa riferimento fintanto che anche questo non vi
appartiene.

Il comando inoltre supporta l'uso dell'opzione \texttt{-R} che, quando lo si
applica ad una directory, esegue la modifica dei permessi ricorsivamente per
tutto il tratto di albero contenuto nella stessa. In questo caso però se nella
sezione di albero ci sono dei collegamenti simbolici, questi verranno ignorati
ed i file a cui fanno riferimento resteranno immutati.  La versione GNU/Linux
del comando supporta anche l'opzione \texttt{-{}-reference=FILE} che permette
di fare riferimento ai permessi di un altro file. Per la descrizione completa
del comando e di tutte le opzioni al solito si faccia riferimento alla pagina
di manuale, accessibile con \texttt{man chmod}.

Oltre ai permessi può essere necessario anche cambiare proprietario e gruppo
di un file (o di una directory). Per il cambiamento del proprietario il
comando da utilizzare è \index{comando!\texttt{chown}} \texttt{chown}, il
comando prende come primo argomento il nome utente (o il valore numerico
dell'\textit{user ID}) a cui assegnare la proprietà del file e come argomenti
successivi la lista dei file su cui operare. Il comando è comunque in grado di
cambiare in contemporanea anche il gruppo proprietario specificando il primo
argomento nella forma \texttt{utente:gruppo}, e viene supportata per
compatibilità anche la forma obsoleta \texttt{utente.gruppo}.

Se invece si vuole cambiare solo il gruppo proprietario il comando da usare è
\index{comando!\texttt{chgrp}} \texttt{chgrp}, che prende di nuovo come primo
argomento il nome del gruppo (o il valore numerico del \textit{group ID})
seguito dalla lista dei file a cui applicare il cambiamento. I comandi
\texttt{chown} e \texttt{chgrp} sono simili e prevedono opzioni analoghe: in
particolare con \texttt{-R} si eseguono i cambiamenti ricorsivamente su tutto
il contenuto di una directory e con \texttt{-{}-reference} si può fare
riferimento alle credenziali prese da un altro file. 

Inoltre entrambi i programmi, quando usati su un link simbolico, operano sul
file a cui questo fa riferimento, a meno che non si usi l'opzione \texttt{-h},
nel qual caso si opererà direttamente sul link. Questa operazione in realtà
assume un significato soltanto se il link è in una directory con lo
\textit{sticky bit} attivo, dove cambiare proprietario del link simbolico
significa modificare l'identità dell'utente che può cancellarlo.

Infine si tenga conto che modificare il proprietario di file è una operazione
privilegiata, che su Linux può essere eseguita solo
dall'amministratore. Questa è una caratteristica di sicurezza mutuata da BSD
che consente di evitare aggiramenti delle quote disco (vedi
sez.~\ref{sec:disk_quota}); non è detto che sia presente su altri sistemi
unix-like. In questo modo un utente normale non può assegnare ad un altro
utente i suoi file, e può cambiare il gruppo proprietario soltanto per i file
che gli appartengono, ed assegnare a questi ultimi soltanto gruppi a cui egli
stesso appartiene.  Solo l'amministratore ha la capacità piena di cambiare
proprietario e gruppo di un file qualunque.



\subsection{Altre operazioni privilegiate}
\label{sec:struct_privileged_operations}

Oltre al rispetto delle restrizioni imposte dai permessi dei file, il sistema
sottopone gli utenti a controllo di accesso per una lunga serie di altre
operazioni. Alcune le abbiamo già incontrate, come il cambiamento di
proprietario o gruppo proprietario, secondo quanto appena visto in
sez.~\ref{sec:struct_file_perm_comm}, o la possibilità di inviare segnali ad
un processo, che come accennato in sez.~\ref{sec:struct_signal} per un utente
normale è ristretta ai soli processi lanciati da lui, o la possibilità di
aumentare la priorità di esecuzione di un processo che come visto in
sez.~\ref{sec:struct_priority} è possibile solo all'amministratore.

Oltre a queste ci sono una lunga serie di altre operazioni privilegiate che
riguardano la rete (che vedremo meglio a partire da
cap.~\ref{cha:networks_base}), per cui solo l'amministratore può attivare e
disattivare interfacce, modificare la tabella di instradamento dei pacchetti,
applicare o rimuovere regole al sistema di \textit{firewall}.
All'amministratore inoltre è riservata l'allocazione delle prime 1024 porte
usate dai protocolli UDP e TCP, per cui di norma soltanto lui è in grado di
lanciare demoni che usano una di queste porte (dette per questo
\textsl{riservate}) come un server web, di posta o un DNS.

\itindbeg{chroot}

Una particolare operazione riservata all'amministratore è quella della
possibilità di usare la \textit{system call} \texttt{chroot} ed il comando
omonimo per eseguire processi con una directory radice diversa (si rammenti
quanto accennato in sez.~\ref{sec:struct_proc_property}) in modo da
restringerne l'accesso ad una sezione dell'albero dei file.

Uno degli impieghi più comuni è quello in cui è montato su una directory il
disco di un altra installazione e si vuole lavorare come se si fosse
all'interno di questa, cosa che si può fare usando appunto il comando
\index{comando!\texttt{chroot}} \texttt{chroot}.  Il comando prende come
argomenti la directory da usare come radice, ed opzionalmente il programma da
eseguire. Se non si specifica nessun programma verrà eseguita di default una
shell, che ovviamente si troverà ad operare all'interno del tratto di albero
specificato.

Il meccanismo del \textit{chroot} viene spesso inteso come misura di sicurezza
per la sua caratteristica di restringere il processo all'interno di un ramo
dell'albero dei file in modo che esso non possa accedere alle altre parti che
non lo riguardano. In realtà questo è vero soltanto se il processo non ha
privilegi di amministratore (né modo di ottenerli) perché altrimenti diventa
semplicissimo uscire dalla gabbia del \textit{chroot}.\footnote{basta creare
  una sottodirectory, eseguire un \texttt{chroot} su di essa per avere la
  directory di lavoro corrente fuori dal \textit{chroot}, per maggiori
  dettagli si veda sez.~4.5.5 di \cite{GaPiL}.}

Si tenga presente però che per poter funzionare un programma eseguito in un
\textit{chroot} dovrà trovare all'interno della relativa directory tutti i
file (e programmi) che gli possono essere necessari,\footnote{questo è
  scontato nel caso del precedente esempio, molto meno se si vuole eseguire un
  programma qualunque in un ramo di albero qualunque.} per questo in genere i
programmi che prevedono di operare in questa modalità richiedono anche
l'approntamento di un ambiente appropriato all'interno della directory di
\textit{chroot}.  In genere questa tecnica viene usata da alcuni demoni di
rete per aumentare la propria sicurezza una volta che hanno rilasciato
eventuali privilegi amministrativi.  In definitiva un semplice \textit{chroot}
non è sufficiente per creare un ambiente virtuale ristretto ad una
sottodirectory, per realizzarlo occorrono delle ulteriori restrizioni
(presenti con estensioni come LXC o OpenVZ) la cui trattazione va al di là
dello scopo di questo testo.

\itindend{chroot}

Una serie di ulteriori operazioni riservate all'amministratore sono: la
possibilità di modificare il tempo sull'orologio di sistema (vedi
sez.~\ref{sec:cmd_time}), la possibilità di riavviare o fermare il sistema
(vedi sez.~\ref{sec:struct_sysv_init}), la possibilità di caricare moduli del
kernel (vedi sez.~\ref{sec:kernel_modules}) e la possibilità di montare i
filesystem. Quest'ultima operazione, anche se in parte può essere delegata
agli utenti (come illustrato in sez.~\ref{sec:file_disk_management}) resta
comunque privilegiata in quanto l'esecuzione generica del comando
\texttt{mount} con parametri qualunque può essere effettuata soltanto
dall'amministratore.

\index{file~di~dispositivo|(}

Infine soltanto l'amministratore è in grado di creare i file speciali relativi
ai dispositivi, cioè solo lui può usare il comando
\index{comando!\texttt{mknod}} \texttt{mknod} per creare un file di
dispositivo.  Questo comando prende come argomenti il nome del file da creare
seguito da una lettera, che indica il tipo di file speciale; questa può essere
``\texttt{p}'' per indicare una \textit{fifo}, ``\texttt{b}'' per indicare un
dispositivo a blocchi e ``\texttt{c}'' per indicare un dispositivo a
caratteri. Qualora si crei un file di dispositivo (che sia a blocchi o a
caratteri è lo stesso) devono poi essere specificati di seguito come ulteriori
argomenti il \itindex{major~number} \textit{major number} ed il
\itindex{minor~number} \textit{minor number} \footnote{questi due numeri sono
  il meccanismo con cui storicamente vengono identificati i dispositivi
  all'interno del kernel (così come gli \textit{inode} identificano un file);
  il nome sotto \texttt{/dev} è solo una etichetta, potrebbe essere qualunque
  (anche se poi molti script non funzionerebbero), quello che indica al kernel
  quale dispositivo usare quando si accede a quel file di dispositivo sono
  questi due numeri.} che lo identificano univocamente. Per una lista completa
delle corrispondenze di questi numeri con i vari dispositivi si può fare
riferimento al file \texttt{devices.txt} distribuito con i sorgenti del kernel
nella directory \texttt{Documentation}.

Si noti che creare un file di dispositivo è una azione diversa dall'accedere
al dispositivo sottostante, cosa che invece è regolata dai permessi di
quest'ultimo come file. Pertanto se si è stati poco accorti e si è permesso
agli utenti l'accesso in scrittura a \texttt{/dev/sda}, anche se questi non
possono creare un file di dispositivo, potranno comunque scrivere nel suddetto
disco e ad esempio saranno tranquillamente in grado di ripartizionarlo.

\index{file~di~dispositivo|)}
\itindbeg{fifo}

Si tenga presente inoltre che per un utente è sempre possibile creare una
\textit{fifo} usando il comando dedicato \index{comando!\texttt{mkfifo}}
\texttt{mkfifo}; questo prende come argomento il nome della \textit{fifo} e
crea la relativa voce nel filesystem. Il comando supporta anche l'opzione
\texttt{-m} che permette di specificare la maschera dei permessi (con la
stessa sintassi di \texttt{chmod}) da applicare alla stessa.  Non esiste
invece un comando specifico per creare un \textit{socket} su disco, i
programmi che li usano li creano chiamando direttamente le \textit{system
  call} necessarie.

\itindend{fifo}


Infine alcuni filesystem supportano delle ulteriori operazioni speciali sui
file, la cui gestione non rientra nella normale politica dei controlli di
accesso di sez.~\ref{sec:struct_file_perm}, ma viene effettuata attraverso
quelli che vengono chiamati gli \textsl{attributi speciali}.  Queste
operazioni attengono ad una serie di capacità aggiuntive, fornite dai
filesystem che le supportano, che possono essere attivate o meno per ciascun
file.\footnote{come per tutte le altre proprietà di un file, anche la lista
  degli attributi speciali attivi viene mantenuta all'interno
  dell'\textit{inode}.}

Alcuni di questi attributi, in particolare quelli che permettono di imporre
delle speciali restrizioni all'accesso, possono essere impostati soltanto
dall'amministratore, questo è il motivo per cui si è scelto di trattare questo
argomento in questa sezione.  Facendo riferimento a delle estensioni che non è
detto siano presenti su un qualunque tipo di filesystem\footnote{queste
  estensioni sono state introdotte con \textit{ext2}, sono presenti nei
  successivi \textit{ext3} ed \textit{ext4}, ma sono supportate anche da altri
  filesystem.} gli attributi speciali dei file non possono essere visualizzati
con il comando \texttt{ls}; per visualizzarli è stato creato un apposito
comando, \index{comando!\texttt{lsattr}} \texttt{lsattr}.

Il comando è analogo a \texttt{ls} sia per l'uso degli argomenti, che per
l'uso delle opzioni \texttt{-R}, \texttt{-a} e \texttt{-d} che hanno lo stesso
significato visto in tab.~\ref{tab:file_ls_options}. Il comando stampa a video
l'elenco dei file, preceduto dal relativo valore degli attributi speciali,
pertanto se lo eseguiamo sui file di questo testo otterremo qualcosa del tipo:
\begin{Console}
piccardi@anarres:~/truedoc/corso$ \textbf{lsattr *.tex}
------------------- advadmin.tex
------------------- appendici.tex
------------------- config.tex
------------------- corso.tex
------------------- netadmin.tex
------------------- netbase.tex
------------------- netdns.tex
------------------- netinter.tex
------------------- netlpi.tex
------------------- ordadmin.tex
------------------- ringraziamenti.tex
------------------- shell.tex
------------------- stradmin.tex
------------------- struttura.tex
\end{Console}
%$
che ci mostra come in questo caso nessun attributo speciale sia stato
impostato. Quando uno di essi è attivo questo viene indicato nell'elenco dalla
presenza della lettera che lo identifica (un elenco è riportato
tab.~\ref{tab:file_special_attributes}) al posto del carattere
``\texttt{-}''. Alcune di queste proprietà dipendono comunque dal supporto
nella versione specifica del filesystem che si sta utilizzando, e non è detto
siano presenti in generale, inoltre alcune di queste, riportate nella seconda
parte di tab.~\ref{tab:file_special_attributes}, possono soltanto essere
rilette con \texttt{lsattr}.

  % \footnote{questo è il caso normale, gli attributi speciali infatti
  % vanno impostati esplicitamente, i file vengono sempre creati senza che
  % nessuno di essi sia presente.} 

Il comando che permette di impostare gli attributi speciali è
\index{comando!\texttt{chattr}} \texttt{chattr}, questo prende come primo
argomento una stringa che identifica quali attributi attivare o disattivare, e
come argomenti successivi una lista di file. Il comando supporta anche
l'opzione \texttt{-R} per eseguire ricorsivamente le operazioni quando nella
lista dei file si è inclusa una directory, mentre se invocato con l'opzione
\texttt{-V} diventa prolisso e descrive le operazioni effettuate.

La stringa che permette di specificare quali attributi attivare o disattivare
è analoga a quella usata con \texttt{chmod} per i permessi, ciascun attributo
è identificato da una lettera fra quelle riportate nella prima parte di
tab.~\ref{tab:file_special_attributes}, in cui però non si sono menzionati
alcuni attributi sperimentali, per i quali si rimanda alla lettura della
pagina di manuale di \texttt{chattr}. Per attivare un attributo occorrerà
farla precedere dal carattere ``\texttt{+}'', mentre se si vuole cancellare un
attributo già impostato si dovrà usare il carattere ``\texttt{-}''. Come per
\texttt{chmod} si possono specificare insieme anche più attributi, ed usare il
carattere ``\texttt{=}'' per impostare la lista esatta di quelli che si
vogliono impostare.

\begin{table}[!htb]
  \centering
  \footnotesize
  \begin{tabular}[c]{|l|p{10cm}|}
    \hline
    \textbf{Attributo} & \textbf{Significato} \\
    \hline
    \hline
    \texttt{A} & blocca l'aggiornamento del tempo di ultimo accesso.\\ 
    \texttt{a} & attiva il cosiddetto \textit{append flag}, che  
                 consente la scrittura solo in coda al file; il contenuto
                 corrente non può essere modificato e solo l'amministratore può
                 attivare o disattivare questo attributo.\\
    \texttt{c} & attiva la compressione trasparente del contenuto del file.\\  
    \texttt{D} & richiede che il contenuto della directory sia salvato su
                 disco in maniera sincrona.\\ 
    \texttt{d} & esclude il file dalla registrazione dei dati necessari ad
                 eseguire il backup del filesystem.\\ %con \texttt{dump} (vedi
%                 sez.~\ref{sec:dump_restore}).\\ 
    % \texttt{e} & indica che il file sta usando gli \textit{extent}, è presente
    %              solo sul filesystem \textit{ext4}, e non può essere rimosso
    %              con \texttt{chattr}.\\  
    \texttt{i} & attiva il cosiddetto \textit{immutable flag}, il file non può
                 essere cancellato o rinominato, non si possono creare hard
                 link, né modificarne il contenuto; solo l'amministratore può
                 attivare o disattivare questo attributo.\\
    \texttt{j} & richiede che tutti i contenuti del file siano prima scritti
                 sul giornale (tratteremo il \textit{journalling} dei
                 filesystem in sez.~\ref{sec:filesystem_create}); solo
                 l'amministratore può attivare o disattivare questo
                 attributo.\\
    \texttt{s} & richiede che quando un file viene cancellato tutti i blocchi
                 che contenevano i suoi dati siano riscritti su disco
                 azzerandone il contenuto.\footnotemark \\ 
    \texttt{S} & richiede che il contenuto del file sia salvato su
                 disco in maniera sincrona.\\ 
    \texttt{u} & richiede che alla cancellazione il contenuto del file sia
                 salvato in modo da poterne consentire il recupero.\\ 
%    \texttt{T} & .\\ 
%    \texttt{t} & .\\ 
    \hline
    \texttt{E} & segnala un errore nella compressione quando questa è stata
                 attivata; l'attributo può solo essere letto da
                 \texttt{lsattr}.\\ 
    \texttt{I} & segnala che una directory viene indicizzata con gli
                 \textit{hash tree} (una funzionalità avanzata trattata in
                 sez.~\ref{sec:filesystem_create}); l'attributo può solo 
                 essere letto da \texttt{lsattr}.\\ 
    \texttt{X} & permette di accedere direttamente al contenuto di un file
                 compresso disabilitando la decompressione trasparente.\\ 
    \texttt{Z} & indica che un file compresso è in uno stato inconsistente
                 (\textit{dirty}); l'attributo può solo essere letto da
                 \texttt{lsattr}.\\  
    \hline
  \end{tabular}
  \caption{Gli attributi speciali dei file.}
  \label{tab:file_special_attributes}
\end{table}

\footnotetext{di default infatti il kernel si limita a marcare i blocchi come
  liberi, ma non cancella il precedente contenuto, che potrebbe pertanto
  essere riletto, l'uso di questo attributo è una forma meno sicura, ma
  automatica, del tipo di cancellazione effettuato con \texttt{shred} di cui
  si è parlato in sez.~\ref{sec:struct_filesystem_arch}.}

Come accennato alcuni attributi, che solo l'amministratore può impostare,
permettono di utilizzare delle speciali restrizioni di accesso, ad esempio con
``\texttt{a}'' si attiva l'\textit{append flag} che consente soltanto di
aggiungere dati ad un file mentre il contenuto corrente non può essere
modificato;\footnote{è cioè possibile aprire un file in scrittura soltanto se
  lo si fa nel cosiddetto \textit{append mode}; per i dettagli sul
  funzionamento di questa modalità si può consultare sez.~5.2.1 di
  \cite{GaPiL}.}  questo può essere utilizzato per salvaguardare i file di log
(vedi sez.~\ref{sec:syslog.conf}) da eventuali modifiche, accidentali o meno,
dato che questi sono in genere la prima cosa che un intruso cerca di
modificare in caso di compromissione di un sistema. Con la presenza di questo
attributo questo viene impedito fintanto che l'attributo non viene rimosso,
purtroppo nelle operazioni ordinarie questo resta sempre possibile se si hanno
i privilegi di amministratore.\footnote{a meno che non si faccia ricorso a
  meccanismi di controllo di accesso più sofisticati di quelli ordinari, come
  SELinux o le \textit{capabilities}, che vanno però al di là dello scopo di
  questo testo.}

Un altro attributo che permette di attivare una protezione speciale è
``\texttt{i}'' che abilita il cosiddetto \textit{immutable flag}, che finché
attivo impedisce qualunque tipo di modifica al file.\footnote{in sostanza,
  oltre ad impedirne la rimozione dalla directory in cui si trova è
  impossibile modificare sia il contenuto del file che dell'\textit{inode},
  pertanto anche tutte le altre caratteristiche del file (permessi,
  proprietario, ecc.) non possono essere modificate.} Si noti che sia questo
che l'\textit{append flag} impongono le loro restrizioni anche alle operazioni
richieste dall'amministratore stesso: questo significa ad esempio che un file
immutabile potrà essere cancellato o modificato (anche dall'amministratore)
soltanto se prima questi ne ha rimosso il relativo attributo. Di nuovo questa
funzionalità permette di proteggere file essenziali in modo da impedirne ogni
forma di modifica, anche se in maniera parziale visto che la protezione può
essere rimossa dall'amministratore.

Potremo allora attivare alcuni di questi attributi (ad esempio
l'\textit{append flag} per un file di log, o l'\textit{immutable flag} per
\texttt{/etc/fstab}), in questo caso basterà eseguire i comandi:
\begin{Console}
root@anarres:~# \textbf{chattr +a /var/log/auth.log}
root@anarres:~# \textbf{chattr +i /etc/fstab}
\end{Console}
e potremo controllare lo stato degli attributi ottenendo che:
\begin{Console}
root@anarres:~# \textbf{lsattr /var/log/auth.log /etc/fstab}
-----a----------- /var/log/auth.log
----i------------ /etc/fstab
\end{Console}
a questo punto si potrà anche verificare che non è più possibile modificare
\texttt{/etc/fstab}: 
\begin{Console}
root@anarres:~# \textbf{touch /etc/fstab}
touch: cannot touch `/etc/fstab': Permission denied
\end{Console}
nonostante il comando sia stato eseguito con privilegi di amministratore.


% LocalWords:  multitasking kernel fig POSIX system call library scheduler VM
% LocalWords:  Virtual Memory MMU Unit swap sez like bootloader LILO GRUB init
% LocalWords:  filesystem shell cap Windows Di Mandrake RedHat Slackware AT BSD
% LocalWords:  Foundation embedded Solaris AIX HP UX Digital IRIX SysV  Waiting
% LocalWords:  Distribution VFS DOS MacOS everything is SCSI CDROM IDE USB vfat
% LocalWords:  hfs VMS device tab regular inode symbolic char block fifo socket
% LocalWords:  llseek read write ioctl readdir ls LiSt total root Jul window ln
% LocalWords:  modification change access count LiNk hardlink rm fR autofs
% LocalWords:  pathname unlink cp  gapil home built pwd acpi discover pgrep
% LocalWords:  Print Work username mkdir rmdir Hierarchy tree bin arch cdrom OS
% LocalWords:  dev MAKEDEV GNUstep initrd lib cpp lost found mnt usb opt proc
% LocalWords:  sbin tmp ssh usr doc games info local share src var backups lock
% LocalWords:  cache log run spool vmlinuz FHS LSB mount point ELF AMD ramdisk
% LocalWords:  devfs bat SGML package interrupt DMA header dict pkill sid
% LocalWords:  terminfo misc news nfs smbfs type adfs Acorn Filing RiscOS ext
% LocalWords:  cramfs Compressed Second journalled hpfs iso jfs Journalling IBM
% LocalWords:  minix Minix ntfs NT qnx QNX reiserfs Reiser romfs ufs SunOS 
% LocalWords:  FreeBSD NetBSD OpenBSD Veritas VxFS UnixWare xfs SGI befs BeOS
% LocalWords:  msdos FAT shm devpts usbdevfs Sun SMB nodev rootfs rw
% LocalWords:  bdev sockfs tmpfs pipefs ramfs usbfs users defaults async ro
% LocalWords:  atime fstab suid exec nouser noatime noauto noexec nosuid sgid
% LocalWords:  sync dirsync remount loopback encryption keybits dump
% LocalWords:  table static information options pass errors sw fsck only umount
% LocalWords:  lazy pstree atd bdflush moniker cron evolution kdeinit bash kdm
% LocalWords:  emacs mozilla agent lockd rpciod cleanup pickup smtp smtpd sshd
% LocalWords:  trivial rewrite syslogd ps PID TTY CMD pts xpdf PDF STAT COMMAND
% LocalWords:  tty process sleep runnable uninterruptible stopped 
% LocalWords:  SIGSTOP axf PCMCIA UID PPID Aug keventd daemon postfix Henry
% LocalWords:  GID group effective RUSER RGROUP RUID RGID parent NI nice SID PR
% LocalWords:  session PGID chroot load average Tasks running sleeping Cpu Mem
% LocalWords:  used buffers cached RES SHR portmap klogd inetd pbbuttonsd VIRT
% LocalWords:  uptime SIGTERM shared kilobyte kill SIGHUP SIGINT SIGQUIT SIGILL
% LocalWords:  SIGTRAP SIGABRT SIGBUS SIGFPE SIGKILL SIGUSR SIGSEGV SIGPIPE RT
% LocalWords:  SIGALRM SIGCHLD SIGCONT SIGTSTP SIGTTIN SIGTTOU SIGURG SIGXCPU
% LocalWords:  SIGXFSZ SIGVTALRM SIGPROF SIGWINCH SIGIO SIGPWR SIGSYS SIGRTMIN
% LocalWords:  SIGRTMAX signal Segment Violation debug killall RTAI scheduling
% LocalWords:  Robin First fairness OPTION ARG renice priority pid pgrp job pty
% LocalWords:  control error descriptor getty helper priv xmms xdvi name gs tex
% LocalWords:  forwarding jed bg fg jobs foreground SELinux Mandatory uid gid
% LocalWords:  dall'username all'username whoami groups List other execute Jan
% LocalWords:  sources Sep Oct getparam chmod sticky mandatory umask 
% LocalWords:  locking passwd others reference chown chgrp UDP nell'inode
% LocalWords:  firewall TCP DNS mknod major number devices txt Documentation SN
% LocalWords:  mkfifo lsattr chattr append hash immutable journalling 
% LocalWords:  dirty capabilities touch cannot Permission denied kjournald 
% LocalWords:  dhclient CVS ElemDaytimeTCPClient ElemDaytimeTCPServer
% LocalWords:  ElemDaytimeTCPCuncServ ElemEchoTCPClient ElemEchoTCPServer Jun
% LocalWords:  ErrCode ForkTest Makefile ProcInfo SimpleEchoTCPClient SockRead
% LocalWords:  SimpleEchoTCPServer SockWrite TestRen advadmin config netadmin
% LocalWords:  netbase netinter ordadmin stradmin Piccardi granted copy and the
% LocalWords:  Mandriva Ubuntu OSS ALSA brw crw drwxr xr prw lrwxrwxrwx srv sys
% LocalWords:  udev Firewire svn High sysfs mapper junkbuster kswapd SWN qmgr
% LocalWords:  ksoftirqd kupdated kapmd khubd FN sDEVICE sr rwxr fopen wrappers
% LocalWords:  xvncviewer XFree kde kwrapper korgac ksensors oafd
% LocalWords:  proxymap wombat wwwoffled dd Spencer those who don't understand
% LocalWords:  doomed to reinvent it poorly alarm gconfd famd kalarmd artsd org
% LocalWords:  hungup nohup disown shred calendar Sarge address corsoFSE
% LocalWords:  netdns netlpi wait Ferrari zoneinfo strace glibc adm dialout  ld
% LocalWords:  dip plugdev lpadmin admin ssl cert openssl operation drwxrwxrwt
% LocalWords:  permission fork pidof Service Switch groupname drwx rwsr SuSE
% LocalWords:  dell'inode systemd upstart execution charset acpid udevd
% LocalWords:  killable migration Xenomai Feb build html intro LXC OpenVZ


%%% Local Variables: 
%%% mode: latex
%%% TeX-master: "corso"
%%% End: 
