Linux guarda las fechas de creación y modificación de los archivos, al igual que la fecha del último acceso (conocido como "access time" o atime). Esto puede ser útil para saber cuándo un archivo fue un accedido o leído por última vez, por razones de auditoría o seguridad. Sin embargo hay un costo asociado a mantener el atime, ya que cada acceso de lectura implica una escritura del atime en el inodo del archivo.

Existe una opción especial de montaje muy utilizada denominada noatime. Si esta opción está definida para un sistema de archivos en /etc/fstab, Linux no registrará la fecha de acceso al momento de abrir un archivo perteneciente a dicho sistema de archivos. En otras palabras, los accesos de lectura no causan que se actualice la información de atime para los archivos. Por ende, utilizar la opción noatime puede resultar en ganancias de rendimiento significativas para sistemas de archivos con gran número de lecturas.

Sin embargo, los sistemas de archivos ext2 en adelante soportan el uso de un atributo especial que permite marcar a un archivo individual para que su fecha de acceso no sea actualizada. Esto permite deshabilitar el atime a nivel archivo o directorio en un sistema de archivos donde se mantiene la fecha de acceso de los archivos (montado sin la opción noatime o explícitamente con la opción atime).

Veamos directamente un ejemplo: el sistema de archivos raíz de cierto servidor Web no está montado con la opción noatime.

root@linuxito:~# mount | grep ' / '
/dev/vda1 on / type ext4 (rw,relatime,errors=remount-ro)

Esto hace que se utilicen las opciones de montaje por defecto del kernel Linux, la cual en esta versión emplea relatime (registrar la fecha de acceso relativa a la última fecha de modificación).

Es interesante destacar que los sistemas de archivos ext4 permiten setear opciones de montaje por defecto específicas para el sistema de archivos:

root@linuxito:~# tune2fs -l /dev/vda1 | grep 'Default mount options'
Default mount options:    user_xattr acl

Por supuesto, tanto las opciones por defecto del kernel como las del sistema de archivos son sobrescritas por la configuración estática en /etc/fstab:

root@linuxito:~# cat /etc/fstab 
# /etc/fstab: static file system information.
UUID=b51b7170-e13c-41cf-a5f1-3e55b99c7fe4	/	ext4	errors=remount-ro	0	1
/var/swap                 none  swap sw

En este caso vemos que se agrega solo errors=remount-ro.

En definitiva el sistema de archivos raíz registra la fecha de acceso (más allá de que sea relativa a la fecha de modificación). Es posible comprobarlo corriendo stat sobre cualquier archivo o directorio:

root@linuxito:~# stat /backup/
  File: /backup
  Size: 4096      	Blocks: 8          IO Block: 4096   directory
Device: fe01h/65025d	Inode: 2621441     Links: 6
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-11-10 15:09:40.019104018 +0000
Modify: 2019-12-04 15:48:37.305760929 +0000
Change: 2019-12-04 15:48:37.305760929 +0000
 Birth: -

Como mencionaba al comienzo del artículo, los sistemas de archivos ext2, ext3, ext4 soportan un atributo extendido para indicar que la fecha de acceso de un archivo o directorio no debe ser actualizada. Se trata del atributo 'A'.

Extracto del manual de chattr:

    When a file with the 'A' attribute set is accessed, its atime record is not modified.
    This avoids a certain amount of disk I/O for laptop systems.

Con lsattr es posible comprobar que este atributo no está en uso en el directorio /backup/:

root@linuxito:~# lsattr /backup/
--------------e---- /backup/tmp
--------------e---- /backup/etc.tar.gz
--------------e---- /backup/mysql.sql
--------------e---- /backup/drive
--------------e---- /backup/scripts
-----------I--e---- /backup/data

Para agregar o eliminar atributos extendidos sobre archivos o directorios se utilizan los símbolos + ó - respectivamente junto con el caracter que identifica al atributo (de forma similar al comando chmod):

root@linuxito:~# chattr -R +A /backup

La opción -R es idéntica a la de chmod e indica que se aplique recursivamente en todo el directorio.

De esta forma el directorio y todo su contenido hacen uso del atributo extendido 'A', el cual especifica que no se actualice el access time:

root@linuxito:~# lsattr -d /backup/
-------A------e---- /backup/
root@linuxito:~# lsattr /backup/
-------A------e---- /backup/tmp
-------A------e---- /backup/etc.tar.gz
-------A------e---- /backup/mysql.sql
-------A------e---- /backup/drive
-------A------e---- /backup/scripts
-------A---I--e---- /backup/data

Las ventajas de este atributo extendido frente a emplear la opción de montaje noatime son varias: permite mayor granularidad al configurar noatime a nivel archivo o directorio; implementar una mezcla de atime y noatime dentro de un mismo filesystem sin necesidad de aplicarlo globalmente para todo el FS; y que además no requiere remontar el filesystem para aplicar el cambio.

Experimento

Veamos ahora si el kernel y el sistema de archivos ext4 honran a este atributo extendido.

Primero veamos qué ocurre al listar un directorio donde está en uso la opción relatime. Se observa que la fecha de acceso del directorio /etc/ssh/ es "2020-02-17 11:15:18.637332773 +0000":

root@linuxito:~# stat /etc/ssh/ | grep Access
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-02-17 11:15:18.637332773 +0000

Listar el directorio implica acceder al mismo (lectura de su contenido):

root@linuxito:~# ls /etc/ssh/ >/dev/null

Como era de esperarse, la fecha de acceso fue actualizada y ahora es "2020-11-10 16:36:07.117163210 +0000":

root@linuxito:~# stat /etc/ssh/ | grep Access
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-11-10 16:36:07.117163210 +0000

Ahora repitamos el experimento en el directorio /backup/, donde se ha agregado el atributo extendido A (el cual indica que no se debe actualizar el access time):

root@linuxito:~# stat /backup/ | grep Access
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-11-10 16:31:14.169286538 +0000

Se observa que la fecha de acceso es "2020-11-10 16:31:14.169286538 +0000". Pero, al listar el directorio (acceder) y volver a consultar, ésta no resulta modificada:

root@linuxito:~# ls /backup/ > /dev/null
root@linuxito:~# stat /backup/ | grep Access
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-11-10 16:31:14.169286538 +0000

¡Éxito!

Peeeeeero...

Existen herramientas como touch que, por alguna razón que desconozco (la página de manual de touch no da detalles acerca de su implementación), ignoran este atributo y modifican la fecha de acceso de todos modos:

root@linuxito:~# touch -a /backup/
root@linuxito:~# stat /backup/ | grep Access
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-11-10 16:34:40.549199902 +0000

Para más información, consultar las siguientes páginas de manual:

man mount
man tune2fs
man fstab
man stat
man lsattr
man chattr
man touch

Compartí este artículo