terminal-comandos

En este artículo comparto un pequeño programa escrito en lenguaje C para verificar si un filesystem soporta direct I/O (flag O_DIRECT al abrir archivos).

Durante la instalación y configuración de un servidor de bases de datos Informix surgió un mensaje en el log indicando que no podía utilizar direct I/O en archivos de chunks:

13:18:22  Direct I/O cannot be used for the chunk file 'xyz'.

No se trata de un error fatal, ya que el servidor de bases de datos continúa abriendo los archivos normalmente, aunque sin soporte para direct I/O.

Direct I/O es una característica del sistema de archivos a través de la cual un proceso puede acceder directamente a un dispositivo, evitando pasar por las caches de lectura y escritura del sistema operativo. Generalmente es utilizada por sistemas de bases de datos, los cuales implementan sus propios mecanismos de caching internos, con lo cual tener una segunda caché de disco a nivel sistema operativo sería redundante e ineficiente. Sin embargo en los sistemas operativos Linux, esta característica no sólo puede ser utilizada para acceder directamente a un dispositivo, sino también a un archivo (se evita que los accesos al archivo pasen por la caché de disco del sistema operativo).

Ahora bien, no todos los sistemas de archivos soportan esta variante (especialmente dependiendo de cómo estén configurados). Con lo cual puede ser necesario verificar si efectivamente es posible abrir un archivo con el flag O_DIRECT (direct I/O).

A tal fin es posible crear un pequeño programa en lenguaje C que haga uso de la llamada al sistema open() (ya que fopen no soporta estos flags especiales).

[root@centos7 ~]# cd /tmp/
[root@centos7 tmp]# nano test-O_DIRECT.c

Crear el archivo test-O_DIRECT.c con el siguiente código fuente:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main() {

  char * a = "test-O_DIRECT.c";

  int fd = open(a,O_DIRECT|O_RDWR);

  printf("fd = %i\n",fd);

}

El programa invoca a la syscall open() para abrir el mismo archivo fuente en modo lectura/escritura, junto con el flag O_DIRECT.

Para poder compilar con el flag O_DIRECT en versiones recientes de glibc es necesario definir _GNU_SOURCE:

[root@centos7 tmp]# gcc -D_GNU_SOURCE -o test-O_DIRECT test-O_DIRECT.c

Al ejecutar el programa, éste retorna el número de descriptor de archivo asignado por el kernel:

[root@centos7 tmp]# ./test-O_DIRECT 
fd = 3

El sistema de archivos donde se encuentra el archivo /tmp/test-O_DIRECT soporta direct I/O.

De acuerdo al manual de open, si la llamada al sistema falla el kernel retorna el descriptor de archivo -1.

Veamos un ejemplo donde falla.

[root@centos7 tmp]# cp test-O_DIRECT* /zdata/
[root@centos7 tmp]# cd /zdata/
[root@centos7 zdata]# ./test-O_DIRECT 
fd = -1

Al abrir el mismo archivo, pero situado en un directorio perteneciente a un sistema de archivos que no soporta direct I/O, el descriptor de archivos es igual a -1. En este caso se trata de un sistema de archivos ZFS, el cual aún no soporta el flag O_DIRECT.

Algunos sistemas de archivos que soportan el flag O_DIRECT son ext2, ext3, ext4, xfs, NFS y otros. Los sistemas de archivos ext4 no soportan direct I/O si se montan con la opción data=journal:

data=journal		All data are committed into the journal prior to being
			written into the main file system.  Enabling
			this mode will disable delayed allocation and
			O_DIRECT support.

Para más información al respecto dejo unas interesantes referencias sobre direct I/O y el flag O_DIRECT.

Referencias

 

Fuente: linuxito

¿Quién está en línea?

Hay 23609 invitados y ningún miembro en línea