-In generale si tenga presente che le dimensioni delle stringe di una
-\struct{utsname} non è specificata, e che esse sono sempre terminate con NUL;
-il manuale delle \acr{glibc} indica due diverse dimensioni,
-\const{\_UTSNAME\_LENGTH} per i campi standard e
-\const{\_UTSNAME\_DOMAIN\_LENGTH} per quello specifico per il nome di dominio;
-altri sistemi usano nomi diversi come \const{SYS\_NMLN} o \const{\_SYS\_NMLN}
-o \const{UTSLEN} che possono avere valori diversi.\footnote{Nel caso di Linux
- \func{uname} corrisponde in realtà a 3 system call diverse, le prime due
- usano rispettivamente delle lunghezze delle stringhe di 9 e 65 byte; la
- terza usa anch'essa 65 byte, ma restituisce anche l'ultimo campo,
- \var{domainname}, con una lunghezza di 257 byte.}
-
-
-\section{Opzioni e configurazione del sistema}
-\label{sec:sys_config}
-
-Come abbiamo accennato nella sezione precedente, non tutti i limiti che
-caratterizzano il sistema sono fissi, o perlomeno non lo sono in tutte le
-implementazioni. Finora abbiamo visto come si può fare per leggerli, ci manca
-di esaminare il meccanismo che permette, quando questi possono variare durante
-l'esecuzione del sistema, di modificarli.
-
-Inoltre, al di la di quelli che possono essere limiti caratteristici previsti
-da uno standard, ogni sistema può avere una sua serie di altri parametri di
-configurazione, che, non essendo mai fissi e variando da sistema a sistema,
-non sono stati inclusi nella standardizzazione della sezione precedente. Per
-questi occorre, oltre al meccanismo di impostazione, pure un meccanismo di
-lettura. Affronteremo questi argomenti in questa sezione, insieme alle
-funzioni che si usano per il controllo di altre caratteristiche generali del
-sistema, come quelle per la gestione dei filesystem e di utenti e gruppi.
-
-
-\subsection{La funzione \func{sysctl} ed il filesystem \file{/proc}}
-\label{sec:sys_sysctl}
-
-La funzione che permette la lettura ed l'impostazione dei parametri del
-sistema è \funcd{sysctl}; è una funzione derivata da BSD4.4, ma
-l'implementazione è specifica di Linux; il suo prototipo è:
-\begin{functions}
-\headdecl{unistd.h}
-\funcdecl{int sysctl(int *name, int nlen, void *oldval, size\_t *oldlenp, void
- *newval, size\_t newlen)}
-
-Legge o scrive uno dei parametri di sistema.
-
-\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di
- errore, nel qual caso \var{errno} assumerà uno dei valori:
- \begin{errlist}
- \item[\errcode{EPERM}] non si ha il permesso di accedere ad uno dei
- componenti nel cammino specificato per il parametro, o di accedere al
- parametro nella modalità scelta.
- \item[\errcode{ENOTDIR}] non esiste un parametro corrispondente al nome
- \param{name}.
-% \item[\errcode{EFAULT}] si è specificato \param{oldlenp} zero quando
-% \param{oldval} è non nullo.
- \item[\errcode{EINVAL}] o si è specificato un valore non valido per il
- parametro che si vuole impostare o lo spazio provvisto per il ritorno di un
- valore non è delle giuste dimensioni.
- \item[\errcode{ENOMEM}] talvolta viene usato più correttamente questo errore
- quando non si è specificato sufficiente spazio per ricevere il valore di un
- parametro.
- \end{errlist}
- ed inoltre \errval{EFAULT}.
-}
-\end{functions}
-
-I parametri a cui la funzione permettere di accedere sono organizzati in
-maniera gerarchica all'interno di un albero;\footnote{si tenga presente che
- includendo solo \file{unistd.h}, saranno definiti solo i parametri generici;
- dato che ce ne sono molti specifici dell'implementazione, nel caso di Linux
- occorrerà includere anche i file \file{linux/unistd.h} e
- \file{linux/sysctl.h}.} per accedere ad uno di essi occorre specificare un
-cammino attraverso i vari nodi dell'albero, in maniera analoga a come avviene
-per la risoluzione di un pathname (da cui l'uso alternativo del filesystem
-\file{/proc}, che vedremo dopo).
-
-Ciascun nodo dell'albero è identificato da un valore intero, ed il cammino che
-arriva ad identificare un parametro specifico è passato alla funzione
-attraverso l'array \param{name}, di lunghezza \param{nlen}, che contiene la
-sequenza dei vari nodi da attraversare. Ogni parametro ha un valore in un
-formato specifico che può essere un intero, una stringa o anche una struttura
-complessa, per questo motivo i valori vengono passati come puntatori
-\ctyp{void}.
-
-L'indirizzo a cui il valore corrente del parametro deve essere letto è
-specificato da \param{oldvalue}, e lo spazio ivi disponibile è specificato da
-\param{oldlenp} (passato come puntatore per avere indietro la dimensione
-effettiva di quanto letto); il valore che si vuole impostare nel sistema è
-passato in \param{newval} e la sua dimensione in \param{newlen}.
-
-Si può effettuare anche una lettura e scrittura simultanea, nel qual caso il
-valore letto restituito dalla funzione è quello precedente alla scrittura.
-
-I parametri accessibili attraverso questa funzione sono moltissimi, e possono
-essere trovati in \file{sysctl.h}, essi inoltre dipendono anche dallo stato
-corrente del kernel (ad esempio dai moduli che sono stati caricati nel
-sistema) e in genere i loro nomi possono variare da una versione di kernel
-all'altra; per questo è sempre il caso di evitare l'uso di \func{sysctl}
-quando esistono modalità alternative per ottenere le stesse informazioni.
-Alcuni esempi di parametri ottenibili sono:
-\begin{itemize}
-\item il nome di dominio
-\item i parametri del meccanismo di \textit{paging}.
-\item il filesystem montato come radice
-\item la data di compilazione del kernel
-\item i parametri dello stack TCP
-\item il numero massimo di file aperti
-\end{itemize}
-
-Come accennato in Linux si ha una modalità alternativa per accedere alle
-stesse informazioni di \func{sysctl} attraverso l'uso del filesystem
-\file{/proc}. Questo è un filesystem virtuale, generato direttamente dal
-kernel, che non fa riferimento a nessun dispositivo fisico, ma presenta in
-forma di file alcune delle strutture interne del kernel stesso.
-
-In particolare l'albero dei valori di \func{sysctl} viene presentato in forma
-di file nella directory \file{/proc/sys}, cosicché è possibile accedervi
-specificando un pathname e leggendo e scrivendo sul file corrispondente al
-parametro scelto. Il kernel si occupa di generare al volo il contenuto ed i
-nomi dei file corrispondenti, e questo ha il grande vantaggio di rendere
-accessibili i vari parametri a qualunque comando di shell e di permettere la
-navigazione dell'albero dei valori.
-
-Alcune delle corrispondenze dei file presenti in \file{/proc/sys} con i valori
-di \func{sysctl} sono riportate nei commenti del codice che può essere trovato
-in \file{linux/sysctl.h},\footnote{indicando un file di definizioni si fa
- riferimento alla directory standard dei file di include, che in ogni
- distribuzione che si rispetti è \file{/usr/include}.} la informazione
-disponibile in \file{/proc/sys} è riportata inoltre nella documentazione
-inclusa nei sorgenti del kernel, nella directory \file{Documentation/sysctl}.
-
-Ma oltre alle informazioni ottenibili da \func{sysctl} dentro \file{proc}
-sono disponibili moltissime altre informazioni, fra cui ad esempio anche
-quelle fornite da \func{uname} (vedi \secref{sec:sys_config}) che sono
-mantenute nei file \file{ostype}, \file{hostname}, \file{osrelease},
-\file{version} e \file{domainname} di \file{/proc/kernel/}.
-
-
-
-\subsection{La gestione delle proprietà dei filesystem}
-\label{sec:sys_file_config}
-
-Come accennato in \secref{sec:file_organization} per poter accedere ai file
-occorre prima rendere disponibile al sistema il filesystem su cui essi sono
-memorizzati; l'operazione di attivazione del filesystem è chiamata
-\textsl{montaggio}, per far questo in Linux\footnote{la funzione è specifica
- di Linux e non è portabile.} si usa la funzione \funcd{mount} il cui
-prototipo è:
-\begin{prototype}{sys/mount.h}
-{mount(const char *source, const char *target, const char *filesystemtype,
- unsigned long mountflags, const void *data)}
-
-Monta il filesystem di tipo \param{filesystemtype} contenuto in \param{source}
-sulla directory \param{target}.
-
- \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di
- fallimento, nel qual caso gli errori comuni a tutti i filesystem che possono
- essere restituiti in \var{errno} sono:
- \begin{errlist}
- \item[\errcode{EPERM}] il processo non ha i privilegi di amministratore.
- \item[\errcode{ENODEV}] \param{filesystemtype} non esiste o non è configurato
- nel kernel.
- \item[\errcode{ENOTBLK}] non si è usato un \textit{block device} per
- \param{source} quando era richiesto.
- \item[\errcode{EBUSY}] \param{source} è già montato, o non può essere
- rimontato in read-only perché ci sono ancora file aperti in scrittura, o
- \param{target} è ancora in uso.
- \item[\errcode{EINVAL}] il device \param{source} presenta un
- \textit{superblock} non valido, o si è cercato di rimontare un filesystem
- non ancora montato, o di montarlo senza che \param{target} sia un
- \textit{mount point} o di spostarlo quando \param{target} non è un
- \textit{mount point} o è \file{/}.
- \item[\errcode{EACCES}] non si ha il permesso di accesso su uno dei
- componenti del pathname, o si è cercato di montare un filesystem
- disponibile in sola lettura senza averlo specificato o il device
- \param{source} è su un filesystem montato con l'opzione \const{MS\_NODEV}.
- \item[\errcode{ENXIO}] il \textit{major number} del device \param{source} è
- sbagliato.
- \item[\errcode{EMFILE}] la tabella dei device \textit{dummy} è piena.
- \end{errlist}
- ed inoltre \errval{ENOTDIR}, \errval{EFAULT}, \errval{ENOMEM},
- \errval{ENAMETOOLONG}, \errval{ENOENT} o \errval{ELOOP}.}
-\end{prototype}
-
-La funzione monta sulla directory \param{target}, detta \textit{mount point},
-il filesystem contenuto in \param{source}. In generale un filesystem è
-contenuto su un disco, e l'operazione di montaggio corrisponde a rendere
-visibile al sistema il contenuto del suddetto disco, identificato attraverso
-il file di dispositivo ad esso associato.
-
-Ma la struttura del virtual filesystem vista in \secref{sec:file_vfs} è molto
-più flessibile e può essere usata anche per oggetti diversi da un disco. Ad
-esempio usando il \textit{loop device} si può montare un file qualunque (come
-l'immagine di un CD-ROM o di un floppy) che contiene un filesystem, inoltre
-alcuni filesystem, come \file{proc} o \file{devfs} sono del tutto virtuali, i
-loro dati sono generati al volo ad ogni lettura, e passati al kernel ad ogni
-scrittura.
-
-Il tipo di filesystem è specificato da \param{filesystemtype}, che deve essere
-una delle stringhe riportate nel file \file{/proc/filesystems}, che contiene
-l'elenco dei filesystem supportati dal kernel; nel caso si sia indicato uno
-dei filesystem virtuali, il contenuto di \param{source} viene ignorato.
-
-Dopo l'esecuzione della funzione il contenuto del filesystem viene resto
-disponibile nella directory specificata come \textit{mount point}, il
-precedente contenuto di detta directory viene mascherato dal contenuto della
-directory radice del filesystem montato.
-
-Dal kernel 2.4.x inoltre è divenuto possibile sia spostare atomicamente un
-\textit{mount point} da una directory ad un'altra, sia montare in diversi
-\textit{mount point} lo stesso filesystem, sia montare più filesystem sullo
-stesso \textit{mount point} (nel qual caso vale quanto appena detto, e solo il
-contenuto dell'ultimo filesystem montato sarà visibile).
-
-Ciascun filesystem è dotato di caratteristiche specifiche che possono essere
-attivate o meno, alcune di queste sono generali (anche se non è detto siano
-disponibili in ogni filesystem), e vengono specificate come opzioni di
-montaggio con l'argomento \param{mountflags}.
-
-In Linux \param{mountflags} deve essere un intero a 32 bit i cui 16 più
-significativi sono un \textit{magic number}\footnote{cioè un numero speciale
- usato come identificativo, che nel caso è \code{0xC0ED}; si può usare la
- costante \const{MS\_MGC\_MSK} per ottenere la parte di \param{mountflags}
- riservata al \textit{magic number}.} mentre i 16 meno significativi sono
-usati per specificare le opzioni; essi sono usati come maschera binaria e
-vanno impostati con un OR aritmetico della costante \const{MS\_MGC\_VAL} con i
-valori riportati in \tabref{tab:sys_mount_flags}.
-
-\begin{table}[htb]
- \footnotesize
- \centering
- \begin{tabular}[c]{|l|r|l|}
- \hline
- \textbf{Parametro} & \textbf{Valore}&\textbf{Significato}\\
- \hline
- \hline
- \const{MS\_RDONLY} & 1 & monta in sola lettura\\
- \const{MS\_NOSUID} & 2 & ignora i bit \acr{suid} e \acr{sgid}\\
- \const{MS\_NODEV} & 4 & impedisce l'accesso ai file di dispositivo\\
- \const{MS\_NOEXEC} & 8 & impedisce di eseguire programmi \\
- \const{MS\_SYNCHRONOUS}& 16 & abilita la scrittura sincrona \\
- \const{MS\_REMOUNT} & 32 & rimonta il filesystem cambiando i flag\\
- \const{MS\_MANDLOCK} & 64 & consente il \textit{mandatory locking} (vedi
- \secref{sec:file_mand_locking})\\
- \const{S\_WRITE} & 128 & scrive normalmente \\
- \const{S\_APPEND} & 256 & consente la scrittura solo in \textit{append
- mode} (vedi \secref{sec:file_sharing})\\
- \const{S\_IMMUTABLE} & 512 & impedisce che si possano modificare i file \\
- \const{MS\_NOATIME} &1024 & non aggiorna gli \textit{access time} (vedi
- \secref{sec:file_file_times})\\
- \const{MS\_NODIRATIME}&2048 & non aggiorna gli \textit{access time} delle
- directory\\
- \const{MS\_BIND} &4096 & monta il filesystem altrove\\
- \const{MS\_MOVE} &8192 & sposta atomicamente il punto di montaggio \\
- \hline
- \end{tabular}
- \caption{Tabella dei codici dei flag di montaggio di un filesystem.}
- \label{tab:sys_mount_flags}
-\end{table}
-
-Per l'impostazione delle caratteristiche particolari di ciascun filesystem si
-usa invece l'argomento \param{data} che serve per passare le ulteriori
-informazioni necessarie, che ovviamente variano da filesystem a filesystem.
-
-La funzione \func{mount} può essere utilizzata anche per effettuare il
-\textsl{rimontaggio} di un filesystem, cosa che permette di cambiarne al volo
-alcune delle caratteristiche di funzionamento (ad esempio passare da sola
-lettura a lettura/scrittura). Questa operazione è attivata attraverso uno dei
-bit di \param{mountflags}, \const{MS\_REMOUNT}, che se impostato specifica che
-deve essere effettuato il rimontaggio del filesystem (con le opzioni
-specificate dagli altri bit), anche in questo caso il valore di \param{source}
-viene ignorato.
-
-Una volta che non si voglia più utilizzare un certo filesystem è possibile
-\textsl{smontarlo} usando la funzione \funcd{umount}, il cui prototipo è:
-\begin{prototype}{sys/mount.h}{umount(const char *target)}
-
- Smonta il filesystem montato sulla directory \param{target}.
-
- \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di
- fallimento, nel qual caso \var{errno} assumerà uno dei valori:
- \begin{errlist}
- \item[\errcode{EPERM}] il processo non ha i privilegi di amministratore.
- \item[\errcode{EBUSY}] \param{target} è la directory di lavoro di qualche
- processo, o contiene dei file aperti, o un altro mount point.
- \end{errlist}
- ed inoltre \errval{ENOTDIR}, \errval{EFAULT}, \errval{ENOMEM},
- \errval{ENAMETOOLONG}, \errval{ENOENT} o \errval{ELOOP}.}
-\end{prototype}
-\noindent la funzione prende il nome della directory su cui il filesystem è
-montato e non il file o il dispositivo che è stato montato,\footnote{questo è
- vero a partire dal kernel 2.3.99-pre7, prima esistevano due chiamate
- separate e la funzione poteva essere usata anche specificando il file di
- dispositivo.} in quanto con il kernel 2.4.x è possibile montare lo stesso
-dispositivo in più punti. Nel caso più di un filesystem sia stato montato
-sullo stesso \textit{mount point} viene smontato quello che è stato montato
-per ultimo.
-
-Si tenga presente che la funzione fallisce quando il filesystem è
-\textsl{occupato}, questo avviene quando ci sono ancora file aperti sul
-filesystem, se questo contiene la directory di lavoro corrente di un qualunque
-processo o il mount point di un altro filesystem; in questo caso l'errore
-restituito è \errcode{EBUSY}.
-
-Linux provvede inoltre una seconda funzione, \funcd{umount2}, che in alcuni
-casi permette di forzare lo smontaggio di un filesystem, anche quando questo
-risulti occupato; il suo prototipo è:
-\begin{prototype}{sys/mount.h}{umount2(const char *target, int flags)}
-
- La funzione è identica a \func{umount} per comportamento e codici di errore,
- ma con \param{flags} si può specificare se forzare lo smontaggio.
-\end{prototype}
-
-Il valore di \param{flags} è una maschera binaria, e al momento l'unico valore
-definito è il bit \const{MNT\_FORCE}; gli altri bit devono essere nulli.
-Specificando \const{MNT\_FORCE} la funzione cercherà di liberare il filesystem
-anche se è occupato per via di una delle condizioni descritte in precedenza. A
-seconda del tipo di filesystem alcune (o tutte) possono essere superate,
-evitando l'errore di \errcode{EBUSY}. In tutti i casi prima dello smontaggio
-viene eseguita una sincronizzazione dei dati.
-
-Altre due funzioni specifiche di Linux,\footnote{esse si trovano anche su BSD,
- ma con una struttura diversa.} utili per ottenere in maniera diretta
-informazioni riguardo al filesystem su cui si trova un certo file, sono
-\funcd{statfs} e \funcd{fstatfs}, i cui prototipi sono:
-\begin{functions}
- \headdecl{sys/vfs.h}
- \funcdecl{int statfs(const char *path, struct statfs *buf)}
-
- \funcdecl{int fstatfs(int fd, struct statfs *buf)}
-
- Restituisce in \param{buf} le informazioni relative al filesystem su cui è
- posto il file specificato.
-
- \bodydesc{Le funzioni ritornano 0 in caso di successo e -1 in caso di
- errore, nel qual caso \var{errno} assumerà uno dei valori:
- \begin{errlist}
- \item[\errcode{ENOSYS}] il filesystem su cui si trova il file specificato non
- supporta la funzione.
- \end{errlist}
- e \errval{EFAULT} ed \errval{EIO} per entrambe, \errval{EBADF} per
- \func{fstatfs}, \errval{ENOTDIR}, \errval{ENAMETOOLONG}, \errval{ENOENT},
- \errval{EACCES}, \errval{ELOOP} per \func{statfs}.}
-\end{functions}
-
-Queste funzioni permettono di ottenere una serie di informazioni generali
-riguardo al filesystem su cui si trova il file specificato; queste vengono
-restituite all'indirizzo \param{buf} di una struttura \struct{statfs} definita
-come in \figref{fig:sys_statfs}, ed i campi che sono indefiniti per il
-filesystem in esame sono impostati a zero. I valori del campo \var{f\_type}
-sono definiti per i vari filesystem nei relativi file di header dei sorgenti
-del kernel da costanti del tipo \var{XXX\_SUPER\_MAGIC}, dove \var{XXX} in
-genere è il nome del filesystem stesso.