From 702770a35b02bf0a4d882e6e6ac573a05f414335 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Wed, 21 Aug 2019 19:39:53 +0200 Subject: [PATCH] Finita statx, inizio execvat e fexecve --- .gitignore | 2 + fileio.tex | 273 +++++++++++++++++++++++++++++++------- listati/statx_timestamp.h | 6 + system.tex | 15 ++- 4 files changed, 239 insertions(+), 57 deletions(-) create mode 100644 listati/statx_timestamp.h diff --git a/.gitignore b/.gitignore index f29054c..710a9f0 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,8 @@ *.tgz *.toc *.out +*.o +*.so *.html *.eps *~ \ No newline at end of file diff --git a/fileio.tex b/fileio.tex index a99960a..b41f6bc 100644 --- a/fileio.tex +++ b/fileio.tex @@ -1938,10 +1938,11 @@ possibili diversi valori a seconda della funzione usata. \label{tab:at-functions_constant_values} \end{table} -\footnotetext{si tratta di una funzionalità fornita dal kernel che consente di - montare automaticamente una directory quando si accede ad un - \textit{pathname} al di sotto di essa, per i dettagli, più di natura - sistemistica, si può consultare sez.~5.1.6 di \cite{AGL}.} +\footnotetext{l'\textit{automount} \itindex{automount} è una funzionalità + fornita dal kernel che consente di montare automaticamente una directory + quando si accede ad un \textit{pathname} al di sotto di essa, per i + dettagli, di natura prevalentemente sistemistica, si può consultare + sez.~5.1.6 di \cite{AGL}.} Si tenga presente che non tutte le funzioni che prevedono l'argomento aggiuntivo sono \textit{system call}, ad esempio \func{faccessat} e @@ -2433,12 +2434,6 @@ come supporto per la scrittura. Infine l'operazione non è compatibile con \itindend{overlay~filesytem} \itindend{union~filesytem} - - -% TODO trattare anche statx, aggiunta con il kernel 4.11 (vedi -% https://lwn.net/Articles/707602/ e -% https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a528d35e8bfcc521d7cb70aaf03e1bd296c8493f) - Benché non rientri nelle \textit{at-functions} previste nello standard POSIX.1-2008, tratteremo qui anche la funzione di sistema \funcd{statx}, introdotta con il kernel 4.11 e disponibile dalle versione 2.28 della @@ -2522,7 +2517,6 @@ consente, con l'argomento \param{mask} di selezionare quelle volute, questa deve essere assegnata ad una maschera binaria dei valori illustrati in tab.~\ref{tab:statx_mask_const}. - \begin{table}[htb] \centering \footnotesize @@ -2542,7 +2536,7 @@ tab.~\ref{tab:statx_mask_const}. \texttt{stx\_gid}).\\ \constd{STATX\_ATIME} & Tempo di ultimo accesso (\texttt{stx\_atime}).\\ \constd{STATX\_MTIME} & Tempo di ultima modifica (\texttt{stx\_mtime}).\\ - \constd{STATX\_CTIME} & Tempo di ultimo cambiamento (\texttt{stx\_mtime}).\\ + \constd{STATX\_CTIME} & Tempo di ultimo cambiamento (\texttt{stx\_ctime}).\\ \constd{STATX\_INO} & Numero di \textit{inode} (\texttt{stx\_ino}).\\ \constd{STATX\_SIZE} & Dimensione del file (\texttt{stx\_size}).\\ \constd{STATX\_BLOCKS}& Numero di blocchi del file (\texttt{stx\_blocks}).\\ @@ -2557,29 +2551,18 @@ tab.~\ref{tab:statx_mask_const}. \label{tab:statx_mask_const} \end{table} -Si tenga presente che il kernel accetta non richiede che \param{mask} contenga -solo i flag di tab.~\ref{tab:statx_mask_const}, valori ulteriori in genere -vengono usualmente ignorati ma non si può comunque indicare un valore -qualunque in quanto alcuni bit sono riservati per future -estensioni.\footnote{in particolare il bit \constd{STATX\_\_RESERVED} che se - usato causa il fallimento della funzione con un errore di \errval{EINVAL}.} -Inoltre non è detto che tutte le informazioni richieste con \param{mask} siano -disponibili, per questo il kernel restituisce in un opportuno campo della -struttura \struct{statx}, \val{stx\_mask}, quali sono i dati effettivamente -restituiti, che possono in alcuni casi essere anche di più di quelli richiesti -(se l'informazione aggiuntiva è ottenuta senza costi ulteriori) per cui è -normale che questo valore possa essere diverso da quanto richiesto. - -In particolare se un filesystem ha dei campi che non sono supportati o con -valori che non hanno corrispondenza in un sistema unix-like, questi potranno -essere restituiti con valori fittizi se disponibili (ad esempio gli \ids{UID} -e \ids{GID} impostati in fase di montaggio per filesystem che non supportano -gli utenti) ma il relativo bit in \val{stx\_mask} sarà comunque -cancellato. Infine è possibile che campi diversi possano avere informazioni -ottenute in momenti diversi per cui in caso di cambiamenti al file eseguiti in -concorrenza a \func{statx} si possono ottenere campi con valori precedenti o -posteriori il cambiamento. - +Si tenga presente che il kernel non richiede che \param{mask} contenga solo i +flag di tab.~\ref{tab:statx_mask_const}, valori ulteriori in genere vengono +ignorati ma non si può comunque indicare un valore qualunque in quanto alcuni +bit sono riservati per future estensioni.\footnote{in particolare il bit + \constd{STATX\_\_RESERVED} che se usato causa il fallimento della funzione + con un errore di \errval{EINVAL}.} Inoltre non è detto che tutte le +informazioni richieste con \param{mask} siano disponibili, per questo il +kernel restituisce in un opportuno campo della struttura \struct{statx}, +\var{stx\_mask}, quali sono i dati effettivamente restituiti, che possono in +alcuni casi essere anche di più di quelli richiesti (se l'informazione +aggiuntiva è ottenuta senza costi ulteriori) per cui è normale che questo +valore possa essere diverso da quanto richiesto. \begin{figure}[!htb] \footnotesize @@ -2593,28 +2576,214 @@ posteriori il cambiamento. \label{fig:file_statx_struct} \end{figure} - Si è riportata in fig.~\ref{fig:file_statx_struct} la definizione della -struttura \struct{statx} come presente in \headfile{sys/stat.h}. +struttura \struct{statx} come presente in \headfile{sys/stat.h}; i campi +\var{stx\_mode}, \var{stx\_nlink}, \var{stx\_uid}, \var{stx\_gid}, +\var{stx\_ino}, \var{stx\_size}, \var{stx\_blksize}, \var{stx\_blocks} sono +identici agli analoghi (con prefisso \texttt{st\_}) dell'ordinaria struttura +\struct{stat} illustrata in fig.~\ref{fig:file_stat_struct} e vale per essi +quanto già detto in sez.~\ref{sec:file_stat} e seguenti. +\begin{figure}[!htb] + \footnotesize + \centering + \begin{minipage}[c]{0.8\textwidth} + \includestruct{listati/statx_timestamp.h} + \end{minipage} + \normalsize + \caption{La struttura \structd{statx\_timestamp} per i tempi dei file con + \func{statx}. } + \label{fig:file_statx_timestamp_struct} +\end{figure} -% TODO: manca prototipo e motivazione di fexecve, da trattare qui in quanto -% inserita nello stesso standard e da usare con openat, vedi -% http://pubs.opengroup.org/onlinepubs/9699939699/toc.pdf +Anche i campi \var{stx\_atime}, \var{stx\_mtime}, \var{stx\_ctime} mantengono +questa analogia, ma esprimono i tempi di ultimo accesso, modifica e +cambiamento con una precisione ed estensione maggiore grazie all'uso di una +struttura dedicata \struct{statx\_timestamp} (riportata in +fig.~\ref{fig:file_statx_timestamp_struct}) che consente di estendere i tempi +dei file ad una granularità del nanosecondo e con un valore dello \textit{unix + time} (vedi sez.~\ref{sec:sys_unix_time}) a 64 bit, che non darà problemi di +overflow per parecchio tempo (sicuramente ben oltre la durata di questa +guida). + +Oltre ai precedenti, e a \val{stx\_mask} che abbiamo già visto e che indica +quali delle informazioni richieste alla funzione sono state fornite, +\func{statx} prevede una serie di informazioni aggiuntive fornite in +altrettanti nuovi campi, illustrati nell'elenco seguente. È comunque previsto +che in futuro \struct{statx} venga estesa per supportare ulteriori +informazioni. + +\begin{basedescript}{\desclabelwidth{1.6cm}\desclabelstyle{\nextlinelabel}} +\item[\var{stx\_btime}] In questo campo viene restituito il \textsl{tempo di + creazione} del file. Come detto in sez.~\ref{sec:file_file_times} questo + tempo normalmente non esiste in un sistema \textit{unix-like}, ma per + migliorare l'interoperabilità è stato aggiunto nelle versioni più recenti di + vari filesystem (come XFS, \acr{ext4}, ecc.) in modo che possa essere + utilizzato da servizi di condivisione dei file (è usato da \textsl{Samba}, + ed è previsto nello standard di NFSv4). +\item[\var{stx\_attributes\_mask}] in questo campo viene restituita una + maschera che indica quali sono i bit restituiti in \var{stx\_attributes} + effettivamente supportati per il file, e per poter utilizzare quest'ultimo + occorre sempre eseguire un AND aritmetico con \var{stx\_attributes\_mask} per + ottenere i valori validi. +\item[\var{stx\_attributes}] in questo campo vengono restituiti gli eventuali + attributi addizionali posseduti dal file. Gran parte di questi sono quelli + impostati con i comandi \cmd{lsattr} e \cmd{chattr} ed abbiamo già incontrato + alcuni di essi in sez.~\ref{sec:file_perm_overview}. Gli attributi vengono + restituiti in forma di maschera binaria con i valori delle costanti elencate + in tab.~\ref{tab:statx_stx_attributes}, dove si trova anche la relativa + descrizione. +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|p{8cm}|} + \hline + \textbf{Costante} & \textbf{Significato} \\ + \hline + \hline + \constd{STATX\_ATTR\_COMPRESSED}& Il file è compresso automaticamente dal + filesystem (quindi può richiedere un + maggior uso di risorse in caso di + accesso).\\ + \constd{STATX\_ATTR\_IMMUTABLE} & Il file è marcato come + \textit{immutable} e non può essere + modificato in nessun modo (vedi + sez.~\ref{sec:file_perm_overview}).\\ + \constd{STATX\_ATTR\_APPEND} & Il file è marcato come + \textit{append-only} e può essere + soltanto esteso in \textit{append} (vedi + sez.~\ref{sec:file_perm_overview}).\\ + \constd{STATX\_ATTR\_NODUMP} & Il file è marcato per essere escluso da + eventuali backup a livello di filesystem + come quelli eseguiti con il comando + \cmd{dump}.\\ + \constd{STATX\_ATTR\_ENCRYPTED} & Il file è cifrato sul filesystem ed è + necessaria una chiave di accesso per + decifrarne il contenuto.\\ + \constd{STATX\_ATTR\_AUTOMOUNT} & Il file, in questo caso in genere una + directory, è marcata come punto di + innesco per un \textit{automount}.\\ + \hline + \end{tabular} + \caption{Le costanti degli attributi addizionali restituiti in + \var{stx\_attributes}.} + \label{tab:statx_stx_attributes} +\end{table} -% TODO manca prototipo di execveat, introdotta nel 3.19, vedi -% https://lwn.net/Articles/626150/ cerca anche fexecve +\item[\var{stx\_rdev\_major}, \var{stx\_rdev\_minor}] in questi campi vengono + restituiti rispettivamente \textit{major number} e \textit{minor number} del + file quando questo è un file di dispositivo (fanno le veci del campo + \var{st\_rdev} di \struct{stat}). -% TODO: manca prototipo e motivazione di execveat, vedi -% http://man7.org/linux/man-pages/man2/execveat.2.html +\item[\var{stx\_dev\_major}, \var{stx\_dev\_minor}] in questi campi vengono + restituiti \textit{major number} e \textit{minor number} del dispositivo su + cui risiede il file (fanno le veci del campo \var{st\_dev} di \struct{stat}). +\end{basedescript} +Di questi campi \var{stx\_mode}, \var{stx\_nlink}, \var{stx\_uid}, +\var{stx\_gid}, \var{stx\_ino}, \var{stx\_size} e \var{stx\_blocks} e quelli +relativi ai tempi ordinari dei file vengono sempre restituiti, ed il relativo +valore in \struct{statx} sovrascritto, indipendentemente dal fatto che siano +stati richiesti o no, con \var{stx\_mask} che indicherà quali sono quelli che +hanno valori effettivamente validi. + +Se un filesystem ha dei campi che non esistono o hanno valori senza +corrispondenza in un sistema unix-like, questi potranno essere restituiti con +valori fittizi ricostruiti, ad esempio usando \ids{UID} e \ids{GID} impostati +in fase di montaggio per un filesystem che non supporta gli utenti; in questi +casi il relativo bit in \var{stx\_mask} sarà comunque cancellato. In caso di +cambiamenti al file eseguiti in concorrenza a \func{statx} è possibile che +campi diversi possano avere informazioni ottenute in momenti diversi, con +valori precedenti o posteriori il cambiamento. Inoltre, se non richiesti +esplicitamente, alcuni campi possono avere valori approssimati, ad esempio in +caso di NFS, questi non vengono mai aggiornati dallo stato sul server remoto. + +Il campo \var{stx\_btime} viene restituito solo se richiesto, e si otterrà un +valore nullo (ed il relativo bit in \var{stx\_mask} cancellato) se questo non +esiste. Lo stesso vale nel caso si siano richiesti \var{stx\_rdev\_major} o +\var{stx\_rdev\_minor} ed il file non è un file di dispositivo. I campi +\var{stx\_dev\_major}, \var{stx\_dev\_minor} e \var{stx\_blksize} attengono +ad informazioni locali, e sono sempre disponibili in maniera diretta. + +% NOTE: per statx https://lwn.net/Articles/707602/ e +% https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a528d35e8bfcc521d7cb70aaf03e1bd296c8493f) Infine trattiamo qui altre due funzioni che non attengono che in maniera -indiretta all'uso dei file, ma sono comunque legate alla stessa interfaccia -delle \textit{at-functions} per quanto riguarda l'accesso ad un file. +indiretta all'uso dei file, ma sono comunque legate all'interfaccia delle +\textit{at-functions}. In realtà la sola effettivamente collegata +all'interfaccia delle \textit{at-functions} è la funzione di sistema +\func{execveat}, introdotta con il kernel 3.19, e per la quale non è +disponibile ancora un'interfaccia diretta nella \acr{glibc} che però la usa +(quando disponibile) per realizzare \func{fexecve}. + +L'introduzione di queste funzioni nasce dall'esigenza di verificare i +contenuti di un file eseguibile prima di eseguirlo. Fare il controllo (aprendo +il file e verificandone il contenuto) e poi eseguirlo con \func{execve} è +suscettibile alla possibilità che fra il controllo e l'esecuzione il nome del +file o di una directory sovrastante venga cambiato. + +Per mitigare il problema nello standard POSIX.1-2008 è stata introdotta la +funzione \funcd{fexecve} che consente di eseguire un programma usando un file +descriptor al posto di un \textit{pathname}; il suo prototipo è: + +\begin{funcproto}{ +\fhead{unistd.h} +\fdecl{int fexecve(int fd, char *const argv[], char *const envp[])} +\fdesc{Esegue un programma da un file descriptor.} +} + +{La funzione non ritorna in caso di successo e ritorna $-1$ per un errore, + nel qual caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EINVAL}] \param{fd} non è un file descriptor, o \param{argv} + o \param{envp} sono \val{NULL}. + \item[\errcode{ENOSYS}] il filesystem \file{proc} non è disponibile (prima + del kernel 3.19). + \end{errlist} + oltre a tutti gli errori già visti per \func{execve}.} +\end{funcproto} + +La funzione esegue il programma contenuto nel file (su cui il chiamante abbia +il permesso di esecuzione) corrispondente a \param{fd}; questo deve essere +stato ottenuto aprendo il relativo eseguibile in sola lettura o con +\const{O\_PATH}. Questa funzione fino al kernel 3.19 veniva realizzata nella +\acr{glibc} usando il filesystem \file{proc} per ottenere da \param{fd} il +file corrispondente, in maniera analoga a quanto visto per l'esempio di +fig.~\ref{fig:initfile}. + +La funzione di sistema \funcd{execveat} è stata introdotta proprio per rendere +più sicura l'esecuzione ed evitare la necessità di avere disponibile +\file{proc} per poter usare \func{fexecve}, il suo prototipo è: +\begin{funcproto}{ +\fhead{unistd.h} +\fdecl{int execveat(int dirfd, const char *pathname, char *const argv[], \\ +\phantom{int execveat(}char *const envp[], int flags)} +\fdesc{Esegue un programma.} +} +{La funzione non ritorna in caso di successo e ritorna $-1$ per un errore, nel + qual caso \var{errno} assumerà, inoltre tutti gli errori già visti per + \func{execve}, uno dei valori: + \begin{errlist} + \item[\errcode{EBADF}] \param{fd} non è un file descriptor valido. + \item[\errcode{EINVAL}] \param{flags} non ha un valore valido. + \item[\errcode{ELOOP}] si è usato \const{AT\_SYMLINK\_NOFOLLOW} in + \param{flags} ma il file indicato è un link simbolico. + \item[\errcode{ENOENT}] il programma di cui si è richiesta l'esecuzione è + uno script, ma \func{dirfd} è aperto con il flag di + \textit{close-on-exec} e pertanto il programma non sarebbe accessibile + all'interprete. + \end{errlist} +} +\end{funcproto} +% TODO: manca prototipo e motivazione di fexecve, da trattare qui in quanto +% inserita nello stesso standard e da usare con openat, vedi +% http://pubs.opengroup.org/onlinepubs/9699939699/toc.pdf + +% TODO manca prototipo di execveat, introdotta nel 3.19, vedi +% https://lwn.net/Articles/626150/ cerca anche fexecve % TODO: trattare i nuovi AT_flags quando e se arriveranno, vedi @@ -5000,13 +5169,17 @@ con uno dei valori \const{FSETLOCKING\_INTERNAL} o % LocalWords: ENXIO NONBLOCK WRONLY EPERM NOATIME ETXTBSY EWOULDBLOCK PGRP SZ % LocalWords: EFAULT capabilities GETPIPE SETPIPE RESOURCE NFSv InitFile stx % LocalWords: Documentation Urlich Drepper futimesat times FullWrite major -% LocalWords: futimens fs Tread TMPFILE EDQUOT extN Minix UDF XFS mask +% LocalWords: futimens fs Tread TMPFILE EDQUOT extN Minix UDF XFS mask all' % LocalWords: shmem Btrfs ubifs tmpfile fchmod fchown fsetxattr fchdir PF -% LocalWords: fstatfs SIGTTIN EDESTADDRREQ datagram connect seal pag +% LocalWords: fstatfs SIGTTIN EDESTADDRREQ datagram connect seal pag l'I INO % LocalWords: dirty execveat execve scandirat statx AUTOMOUNT automount DAC -% LocalWords: wrapper EMPTY olddirfd oldpath newdirfd newpath capability +% LocalWords: wrapper EMPTY olddirfd oldpath newdirfd newpath capability ino % LocalWords: SEARCH flink choot oldirfd NOREPLACE EXCHANGE WHITEOUT union -% LocalWords: renamat syscall whiteout overlay filesytem Live +% LocalWords: renamat syscall whiteout overlay filesytem Live nell' sull' +% LocalWords: statbuf statxbuf IFMT nlink atime mtime fexecve argv envp +% LocalWords: blocks STATS btime RESERVED ctime ATTR dev ENOSYS +% LocalWords: timestamp attributes COMPRESSED immutable NODUMP +% LocalWords: dump ENCRYPTED rdev all'I dell'I %%% Local Variables: %%% mode: latex diff --git a/listati/statx_timestamp.h b/listati/statx_timestamp.h new file mode 100644 index 0000000..3408e67 --- /dev/null +++ b/listati/statx_timestamp.h @@ -0,0 +1,6 @@ +struct statx_timestamp { + __s64 tv_sec; /* Seconds since the Epoch (UNIX time) */ + __u32 tv_nsec; /* Nanoseconds since tv_sec */ + __s32 __reserved; /* Reserved for future uses */ + +}; diff --git a/system.tex b/system.tex index aa305f2..bd60d40 100644 --- a/system.tex +++ b/system.tex @@ -2056,13 +2056,14 @@ espressi con diversi tipi di dati, chiamati rispettivamente \textit{calendar time} e \textit{process time}, secondo le seguenti definizioni: \begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}} -\item[\textit{calendar time}] detto anche \textsl{tempo di calendario}, - \textsl{tempo d'orologio} o \textit{tempo reale}. Si tratta di un - tempo assoluto o di un intervallo di tempo come lo intende - normalmente per le misure fatte con un orologio. Per esprimere - questo tempo è stato riservato il tipo \type{time\_t}, e viene - tradizionalmente misurato in secondi a partire dalla mezzanotte del - primo gennaio 1970, data che viene chiamata \textit{the Epoch}. +\item[\textit{calendar time}] detto anche \textsl{tempo di calendario}, + \textsl{tempo d'orologio} o \textit{tempo reale}. Si tratta di un tempo + assoluto o di un intervallo di tempo come lo intende normalmente per le + misure fatte con un orologio. Per esprimere questo tempo è stato riservato + il tipo \type{time\_t}, e viene tradizionalmente misurato nel cosiddetto + \itindex{unix-time} \textit{unix-time}, espresso in secondi a partire dalla + mezzanotte del primo gennaio 1970, data che viene chiamata \textit{the + Epoch}. \item[\textit{process time}] detto anche \textsl{tempo di processore} o \textsl{tempo di CPU}. Si tratta del tempo impiegato da un processore -- 2.30.2