X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=system.tex;h=1572830cfcf158113051ad811ee6444a661aab0e;hp=27f484c83ad837d969c5fe75a91f6aec45365ad4;hb=aef0d7a31187dfbb7574f477636e75fc3c8c81ef;hpb=7bd1670460aea5107ad0aeeb5f0639587ceb4399 diff --git a/system.tex b/system.tex index 27f484c..1572830 100644 --- a/system.tex +++ b/system.tex @@ -8,6 +8,7 @@ stesso, quelle per il controllo dell'uso delle risorse da parte dei processi, quelle per la gestione dei tempi e degli errori. + \section{La lettura delle caratteristiche del sistema} \label{sec:sys_characteristics} @@ -74,7 +75,7 @@ avere un valore minimo di 8. \hline \hline \macro{MB\_LEN\_MAX}& 16 & massima dimensione di un - carattere multibyte\\ + carattere esteso\\ \macro{CHAR\_BIT} & 8 & bit di \type{char}\\ \macro{UCHAR\_MAX}& 255 & massimo di \type{unsigned char}\\ \macro{SCHAR\_MIN}& -128 & minimo di \type{signed char}\\ @@ -179,7 +180,7 @@ A complicare la faccenda si aggiunge il fatto che POSIX.1 prevede una serie di altre macro (che iniziano sempre con \code{\_POSIX\_}) che definiscono i valori minimi le stesse caratteristiche devono avere, perché una implementazione possa dichiararsi conforme allo standard; detti valori sono -riportati in \tabref{tab:sys_posix1_base}. +riportati in \tabref{tab:sys_posix1_general}. \begin{table}[htb] \centering @@ -217,11 +218,11 @@ riportati in \tabref{tab:sys_posix1_base}. \label{tab:sys_posix1_general} \end{table} -In genere questi valori non servono a molto, la loro unica utilità è quella -di indicare un limite superiore che assicura la portabilità senza necessità di -ulteriori controlli. Tuttavia molti di essi sono troppo ristretti, ed -ampiamente superati in tutti i sistemi POSIX in uso oggigiorno. Per questo è -sempre meglio usare i valori provvisti da \func{sysconf}. +In genere questi valori non servono a molto, la loro unica utilità è quella di +indicare un limite superiore che assicura la portabilità senza necessità di +ulteriori controlli. Tuttavia molti di essi sono ampiamente superati in tutti +i sistemi POSIX in uso oggigiorno. Per questo è sempre meglio utilizzare i +valori ottenuti da \func{sysconf}. \begin{table}[htb] \centering @@ -247,12 +248,12 @@ sempre meglio usare i valori provvisti da \func{sysconf}. \label{tab:sys_posix1_other} \end{table} -Oltre ai precedenti valori (e a quelli elencati in +Oltre ai precedenti valori (e a quelli relativi ai file elencati in \tabref{tab:sys_posix1_file}), che devono essere obbligatoriamente definiti, -lo standard POSIX.1 ne prevede parecchi altri; in Linux la lista completa si -può ricavare dall'header file \file{bits/posix1\_lim.h} (da non usare mai -direttamente, è incluso automaticamente all'interno di \file{limits.h}); di -questi vale la pena menzionare quelli di uso più comune, riportati in +lo standard POSIX.1 ne prevede parecchi altri. La lista completa si trova +dall'header file \file{bits/posix1\_lim.h} (da non usare mai direttamente, è +incluso automaticamente all'interno di \file{limits.h}); di questi vale la +pena menzionare quelli di uso più comune, riportati in \tabref{tab:sys_posix1_other}, che permettono di ricavare alcune caratteristiche del sistema (come il supporto del \textit{job control} o dei \textit{saved id}). @@ -339,7 +340,7 @@ spiegazioni, si pu In generale ogni limite o caratteristica del sistema per cui è definita una macro, sia dagli standard ANSI C e ISO C90, che da POSIX.1 e POSIX.2, può essere ottenuto attraverso una chiamata a \func{sysconf}. Il valore si otterrà -speficando come valore del parametro \param{name} il nome ottenuto aggiungendo +specificando come valore del parametro \param{name} il nome ottenuto aggiungendo \code{\_SC\_} ai nomi delle macro definite dai primi due, o sostituendolo a \code{\_POSIX\_} per le macro definite dagli gli altri due. @@ -469,16 +470,19 @@ suo prototipo \subsection{La funzione \func{uname}} \label{sec:sys_uname} -Una altra funzione che si può utilizzare per raccogliere informazioni riguardo -al sistema ed al computer su cui esso sta girando è \func{uname}, il suo -prototipo è: +Una altra funzione che si può utilizzare per raccogliere informazioni sia +riguardo al sistema che al computer su cui esso sta girando è \func{uname}, il +suo prototipo è: \begin{prototype}{sys/utsname.h}{int uname(struct utsname *info)} Restituisce informazioni sul sistema nella struttura \param{info}. \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di fallimento, nel qual caso \var{errno} viene settata a \macro{EFAULT}.} \end{prototype} -\noindent la struttura è anch'essa definita in \file{sys/utsname.h} come: + +La funzione, che viene usata dal comando \cmd{umane}, restituisce le +informazioni richieste nella struttura \param{info}, anche questa struttura è +definita in \file{sys/utsname.h} come: \begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} struct utsname { char sysname[_UTSNAME_LENGTH]; @@ -491,37 +495,320 @@ prototipo #endif }; \end{lstlisting} -ed i suoi menbri indicano rispettivamente: +e le informazioni memorizzate nei suoi membri indicano rispettivamente: \begin{itemize*} -\item il nome del systema operativo; +\item il nome del sistema operativo; \item il nome della release del kernel; \item il nome della versione del kernel; \item il tipo di macchina in uso; \item il nome della stazione; -\item il nome del domino (è una estensione recente). +\item il nome del domino. \end{itemize*} - +(l'ultima informazione è stata aggiunta di recente e non è prevista dallo +standard POSIX). \section{Opzioni e configurazione del sistema} \label{sec:sys_config} -In questa sezione prenderemo in esame le funzioni per leggere e settare i vari -parametri di configurazione del sistema. +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, non sono stati inclusi nella +standardizzazione della sezione precedente, e per i quali occorre, oltre al +meccanismo di settaggio, 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}} + +\subsection{La funzione \func{sysctl} ed il filesystem \file{/proc}} \label{sec:sys_sysctl} -\subsection{Il filesystem \file{/proc}} -\label{sec:sys_proc_files} +La funzione che permette la lettura ed il settaggio dei parametri del kernel è +\func{sysctl}, è una funzione derivata da BSD4.4, ma l'implementazione è +specifica di Linux; il suo prototipo è: +\begin{functions} +\headdecl{unistd.h} +\headdecl{linux/unistd.h} +\headdecl{linux/sysctl.h} +\funcdecl{int sysctl(int *name, int nlen, void *oldval, size\_t *oldlenp, void + *newval, size\_t newlen)} + + +\bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di + errore, nel qual caso \var{errno} viene settato ai valori: + \begin{errlist} + \item[\macro{EPERM}] il processo non ha il permesso di accedere ad uno dei + componenti nel cammino specificato per il parametro, o non ha il permesso + di accesso al parametro nella modalità scelta. + \item[\macro{ENOTDIR}] non esiste un parametro corrispondente al nome + \param{name}. + \item[\macro{EFAULT}] si è specificato \param{oldlenp} zero quando + \param{oldval} è non nullo. + \item[\macro{EINVAL}] o si è specificato un valore non valido per il + parametro che si vuole settare o lo spazio provvisto per il ritorno di un + valore non è delle giuste dimensioni. + \item[\macro{ENOMEM}] talvolta viene usato più correttamente questo errore + quando non si è specificato sufficiente spazio per ricevere il valore di un + parametro. + \end{errlist} +} +\end{functions} + +I parametri a cui la funzione permettere di accedere sono organizzati in +maniera gerarchica ad albero, e per accedere ad uno di essi occorre +specificare un cammino attraverso i vari nodi dell'albero, in maniera analoga +a come si specifica un pathname (da cui l'uso alternativo del filesystem +\file{/proc} che vedremo dopo). + +Ciascun nodo è identificato da un valore intero, ed il cammino che arriva ad +identificare un parametro specifico è passato attraverso l'array \param{name}, +di lunghezza \param{nlen}, che contiene la sequenza dei vari nodi da +attraversare. Il formato del valore di un parametro dipende dallo stesso e può +essere un intero, una stringa o anche una struttura complessa. + +L'indirizzo a cui il valore 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 scrivere è 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 è 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. -\subsection{La configurazione dei filesystem} +Alcune delle corrispondenze con i valori di \func{sysctl} sono riportate nei +commenti in \file{linux/sysctl.h}, la informazione disponibile in +\file{/proc/sys} è riportata inoltre nella documentazione inclusa nei sorgenti +del kernel, nella directory \file{Documentation/sysctl}. + + +\subsection{La gestione delle proprietà dei filesystem} \label{sec:sys_file_config} -\subsection{La funzione \func{statfs}} -\label{sec:sys_file_stafs} +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 \func{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[\macro{EPERM}] il processo non ha i privilegi di amministratore. + \item[\macro{ENODEV}] \param{filesystemtype} non esiste o non è configurato + nel kernel. + \item[\macro{ENOTBLK}] non si è usato un \textit{block device} per + \param{source} quando era richiesto. + \item[\macro{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[\macro{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 + \type{mount point} o di spostarlo quando \param{target} non è un + \type{mount point} o è \file{/}. + \item[\macro{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 \macro{MS\_NODEV}. + \item[\macro{ENXIO}] il \textit{major number} del device \param{source} è + sbagliato. + \item[\macro{EMFILE}] la tabella dei device \textit{dummy} è piena. + \end{errlist} + ed inoltre \macro{ENOTDIR}, \macro{EFAULT}, \macro{ENOMEM}, + \macro{ENAMETOOLONG}, \macro{ENOENT} o \macro{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 in \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, che montare in diversi +\textit{mount point} lo stesso filesystem, che 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 \macro{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 settati con un OR aritmetico della costante \macro{MS\_MGC\_VAL} con i +valori riportati in \ntab. + +\begin{table}[htb] + \centering + \begin{tabular}[c]{|l|r|l|} + \hline + \textbf{Parametro} & \textbf{Valore}&\textbf{Significato}\\ + \hline + \hline + \macro{MS\_RDONLY} & 1 & monta in sola lettura\\ + \macro{MS\_NOSUID} & 2 & ignora i bit \acr{suid} e \acr{sgid}\\ + \macro{MS\_NODEV} & 4 & impedisce l'accesso ai file di dispositivo\\ + \macro{MS\_NOEXEC} & 8 & impedisce di eseguire programmi \\ + \macro{MS\_SYNCHRONOUS}& 16 & abilita la scrittura sincrona \\ + \macro{MS\_REMOUNT} & 32 & rimonta il filesystem cambiando i flag\\ + \macro{MS\_MANDLOCK} & 64 & consente il \textit{mandatory locking} (vedi + \secref{sec:file_mand_locking})\\ + \macro{S\_WRITE} & 128 & scrive normalmente \\ + \macro{S\_APPEND} & 256 & consente la scrittura solo in \textit{append + mode} (vedi \secref{sec:file_sharing})\\ + \macro{S\_IMMUTABLE} & 512 & impedisce che si possano modificare i file \\ + \macro{MS\_NOATIME} &1024 & non aggiorna gli \textit{access time} (vedi + \secref{sec:file_file_times})\\ + \macro{MS\_NODIRATIME}&2048 & non aggiorna gli \textit{access time} delle + directory\\ + \macro{MS\_BIND} &4096 & monta il filesystem altrove\\ + \macro{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 il settaggio 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}, \macro{MS\_REMOUNT}, che se settato 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 \func{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} viene settata a: + \begin{errlist} + \item[\macro{EPERM}] il processo non ha i privilegi di amministratore. + \item[\macro{EBUSY}] \param{target} è la directory di lavoro di qualche + processo, o contiene dei file aperti, o un altro mount point. + \end{errlist} + ed inoltre \macro{ENOTDIR}, \macro{EFAULT}, \macro{ENOMEM}, + \macro{ENAMETOOLONG}, \macro{ENOENT} o \macro{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. + +Linux provvede inoltre una seconda funzione \func{umount2}, che, in alcuni +casi, permette di forzare lo smontaggio di un filesystem nei casi in cui mount +fallirebbe; il suo prototipo è: + + + +Due funzioni, utili per ottenere in maniera diretta informazioni riguardo al +filesystem su cui si trova un certo file, sono \func{statfs} e \func{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{La funzione restituisce 0 in caso di successo e -1 in caso di + errore, nel qual caso \var{errno} viene settato ai valori: + \begin{errlist} + \item[\macro{ENOSYS}] il filesystem su cui si trova il file specificato non + supporta la funzione. + \end{errlist} + e \macro{EFAULT} ed \macro{EIO} per entrambe, \macro{EBADF} per + \func{fstatfs}, \macro{ENOTDIR}, \macro{ENAMETOOLONG}, \macro{ENOENT}, + \macro{EACCES}, \macro{ELOOP} per \func{statfs}.} +\end{functions} + + + +\subsection{La gestione di utenti e gruppi} +\label{sec:sys_user_group} @@ -539,6 +826,8 @@ sul loro utilizzo. \label{sec:sys_resource_use} + + \subsection{Limiti sulle risorse} \label{sec:sys_resource_limit} @@ -806,9 +1095,6 @@ o la macro (\texttt{\small 15--17}) associate a quel codice. \end{figure} -\section{La gestione di utenti e gruppi} -\label{sec:sys_user_group} - %%% Local Variables: %%% mode: latex