Skip to content

Instantly share code, notes, and snippets.

@mgarciaisaia
Created September 15, 2016 19:23
Show Gist options
  • Save mgarciaisaia/147c02ea412d115b43b328e872bb3c57 to your computer and use it in GitHub Desktop.
Save mgarciaisaia/147c02ea412d115b43b328e872bb3c57 to your computer and use it in GitHub Desktop.
Siguiendo la conversación que arrancó en https://github.com/sisoputnfrba/foro/issues/460

Me quedé pensando en lo que te decía de los límites de los FS, y quise ver si ext4 (el FS que usa la VM que les damos) tenía algún límite de entradas de directorios.

Armé un script de Bash bastante simple:

#!/bin/bash 
COUNTER=0
while [  $? -eq 0 ]; do
  let COUNTER=COUNTER+1
  mkdir "dir${COUNTER}"
done

Declara una variable COUNTER inicializada en 0, y, mientras que el último comando haya ejecutado bien ($? es una variable que guarda el código de salida del último comando - el valor del return de la función main del programa, digamos), incrementa esa variable COUNTER y crea un directorio (mkdir) llamado dirN, donde N es el valor del contador.

Lo puse a correr en un directorio de ejemplo y... corrió. Corrió un rato largo.

Esperaba que al llegar a 64k directorios empezara a fallar - pero no. Desde otra consola hacía ls -l | wl -l para obtener la cantidad de directorios que se habían creado hasta el momento, y eventualmente me pasó que el comando ese tardaba minutos en correr, porque el ls tardaba una bocha.

Eventualmente me aburrí y maté al script. Listando el directorio que contiene al mío, veo que la entrada de directorio pesa:

$ ls -l
drwxrwxr-x  1 utnso utnso 28127232 sep 15 16:01 ejemplo/

Así es: 27MB.

27MB de entradas de archivos en el directorio.

En general, los directorios pesan 4096 (un bloque), porque con eso les sobra para listar todos los archivos que contienen. En mi máquina "física", que vengo usando todos los días desde hace unos 2 o 3 años, mi directorio Downloads (donde se guarda todo lo que bajo de Internet) pesa 78710 bytes para guardar 2316 archivos. Está bien - es otro filesystem (es HFS+, el FS de MacOS X) -, pero tiene poco que ver con 27MB eso.

Intenté listar todo ese directorio, contando cuántas entradas había, y tomando el tiempo que tardaba en hacerlo:

$ time ll | wc -l
ls: memoria agotada
0

real	12m31.595s
user	0m0.144s
sys	8m48.868s

¡Ja! Me quedé sin memoria antes de poder contar todos. Cierro eclipse y atom, y pruebo de nuevo con el formato menos largo de ls:

$ time ls -1 | wc -l
971182

real	0m8.583s
user	0m6.988s
sys	0m0.096s

Eso fue rápido. Casi un millón de directorios creé - y eso pesa 27MB.

A ver si ahora que cerré eclipse y atom puedo listar en formato largo:

$ time ls -l | wc -l
971183

real	1m28.753s
user	0m9.760s
sys	0m33.796s

It works!

Bueno, eso. Si hay un límite, parece ser estúpidamente grande. Después seguiré jugando - ahora, a trabajar.

@mgarciaisaia
Copy link
Author

Me puse a ver por qué tardaba tanto el ls -1. Corrí strace -C ls -1 en el directorio para listar todas las syscalls que ls -1 hace (eso es lo que strace hace), y tener un resumen de llamadas, tiempos de ejecución, etc (eso hace -C).

Los resultados me llamaron la atención:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 71.98    0.288209           0   1683121           write
 27.52    0.110193          67      1645           getdents64
  0.50    0.002020         202        10           mremap
  0.00    0.000000           0         8           read
  0.00    0.000000           0         9           open
  0.00    0.000000           0        12           close
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         8         8 access
  0.00    0.000000           0       203           brk
  0.00    0.000000           0         2           ioctl
  0.00    0.000000           0         3           munmap
  0.00    0.000000           0         8           mprotect
  0.00    0.000000           0        24           mmap2
  0.00    0.000000           0        10           fstat64
  0.00    0.000000           0         1           set_thread_area
  0.00    0.000000           0         2         2 statfs64
  0.00    0.000000           0         1           openat
------ ----------- ----------- --------- --------- ----------------
100.00    0.400422               1685068        10 total

Acá no queda tan claro, pero corriéndolo se nota al toque: casi todo el tiempo se va en los writes. Listar los directorios llevó (según esto) el 30% del tiempo del proceso, mientras que el 70% restante fue imprimir entrada por entrada.

time dijo que todo esto tardó:

real    2m33.460s
user    0m25.216s
sys 0m20.280s

En paralelo seguía corriendo el script que crea directorios. Meh.

@mgarciaisaia
Copy link
Author

Llené el FS.

3042411 directorios creados, el directorio pesa 86487040 bytes (83MB).

El error con el que falló fue:

$ ../llenar_directorio.bash
mkdir: no se puede crear el directorio «dir3042412»: No queda espacio en el dispositivo

Pero sí hay espacio en disco:

$ df -h
S.ficheros     Tamaño Usados  Disp Uso% Montado en
/dev/sda1         49G    17G   30G  36% /
none             4,0K      0  4,0K   0% /sys/fs/cgroup
udev             239M   4,0K  239M   1% /dev
tmpfs             50M   920K   49M   2% /run
none             5,0M      0  5,0M   0% /run/lock
none             248M    80K  248M   1% /run/shm
none             100M    36K  100M   1% /run/user
/dev/sr0          58M    58M     0 100% /media/utnso/VBOXADDITIONS_5.0.16_105871

Ese error corresponde al errno ENOSPC.

Al principio pensé que había llenado el directorio, nomás, pero no:

$ mkdir sarasa
mkdir: no se puede crear el directorio «sarasa»: No queda espacio en el dispositivo
$ mkdir ../sarasa
mkdir: no se puede crear el directorio «../sarasa»: No queda espacio en el dispositivo

Pero sigo teniendo espacio en disco:

$ ll ../sali*
-rw-rw-r-- 1 utnso utnso 1389191 oct 31  2015 ../salida-no-opt.txt
-rw-rw-r-- 1 utnso utnso  110592 oct 31  2015 ../salida.txt
$ cat ../salida-no-opt.txt >> ../salida.txt
$ ll ../sali*
-rw-rw-r-- 1 utnso utnso 1389191 oct 31  2015 ../salida-no-opt.txt
-rw-rw-r-- 1 utnso utnso 1499783 sep 15 17:47 ../salida.txt

No se qué estará pasando...

@mgarciaisaia
Copy link
Author

Mati del pasado: probablemente te hayas quedado sin inodos libres.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment