Finita statx, inizio execvat e fexecve
authorSimone Piccardi <piccardi@gnulinux.it>
Wed, 21 Aug 2019 17:39:53 +0000 (19:39 +0200)
committerSimone Piccardi <piccardi@gnulinux.it>
Wed, 21 Aug 2019 17:39:53 +0000 (19:39 +0200)
.gitignore
fileio.tex
listati/statx_timestamp.h [new file with mode: 0644]
system.tex

index f29054c..710a9f0 100644 (file)
@@ -13,6 +13,8 @@
 *.tgz
 *.toc
 *.out
+*.o
+*.so
 *.html
 *.eps
 *~
\ No newline at end of file
index a99960a..b41f6bc 100644 (file)
@@ -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 (file)
index 0000000..3408e67
--- /dev/null
@@ -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 */
+
+};
index aa305f2..bd60d40 100644 (file)
@@ -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