Verificar una tarjeta Micro SD en una Raspberry PI (2)

Lamentablemente, el esquema propuesto en Verificar una tarjeta Micro SD en una Raspberry PI tiene dos problemas relacionados entre sí:

  1. Es necesario crear dos ficheros más grandes que la memoria RAM disponible. Hasta ahora bastaba con ficheros de 1 Gigabyte, pero la aparición de la Raspberry PI 4 con hasta 4 GB de RAM hace necesario el uso de ficheros muy grandes.

    Actualización 20200528: Acaba de aparecer la Raspberry PI 4 con 8 GB de RAM.

  2. Relacionado con el punto anterior, el uso de ficheros muy grandes es problemático porque requiere mucho espacio libre en la tarjeta microSD.

Estos dos puntos se explican por la necesidad de asegurarse de que, a la hora de comparar los ficheros, se van a comparar los datos grabados en la tarjeta microSD, no informacion guardada en la caché en la memoria RAM.

No obstante, la información proporcionada por el artículo ¿Qué es y cómo limpiar la caché del sistema de ficheros en Linux? abre la puerta a usar ficheros de un tamaño más razonable, simplemente pidiéndole al sistema operativo que limpie los datos en la caché antes de utilizarlos para obligarle a recurrir a la tarjeta microSD.

El código original (extendido a varias líneas por legibilidad) era el siguiente:

root@raspberrypi:~# cd /tmp
root@raspberrypi:/tmp# for i in `seq 1 16`
do
  echo Intento $i
  dd if=/dev/urandom of=z1 bs=65536 count=32768 2>/dev/null
  cp z1 z2
  cmp z1 z2 && continue
  echo FALLO
  md5sum z1 z2
  break
done

Si estamos usando Linux en la Raspberry PI, podemos mejorar el código y hacer algo así:

root@raspberrypi:~# cd /tmp
root@raspberrypi:/tmp# for i in `seq 1 16`
do
  echo Intento $i
  h1=`dd if=/dev/urandom bs=65536 count=32768 2>/dev/null | tee z1 | md5sum -`
  sync; echo 3 >/proc/sys/vm/drop_caches
  cp z1 z2
  sync; echo 3 >/proc/sys/vm/drop_caches
  h2=`cat z2 | md5sum -`
  if [ "$h1" == "$h2" ]
  then
    continue
  fi
  echo FALLO
  echo z1: $h1
  echo z2: $h2
  break
done

Las dos líneas sync; echo 3 >/proc/sys/vm/drop_caches se aseguran de que hemos grabado todo en la tarjeta microSD antes de pedir que se borre la caché. Así nos aseguramos de que los datos se están leyendo de la tarjeta de memoria, no de la caché en RAM.

Una optimización que he hecho es que, en vez de comparar los ficheros como en la versión anterior, comparamos sus hashes. No parece ventajoso pero lo es, porque el hash del primer fichero se calcula al mismo tiempo que se está generando, lo que resulta básicamente gratis; solo tendremos que leer un fichero en vez de dos para comprobar si son iguales.

La versión propuesta genera dos ficheros de 2 GB, por lo que necesitamos al menos 4 GB de espacio libre en la tarjeta microSD. Lo ideal sería ver cuánto espacio libre queda en la tarjeta microSD y crear ficheros de algo menos de la mitad de ese valor. De esta forma comprobamos la tarjeta de memoria al máximo posible sin perjudicar los datos ya grabados.

Nota

Lo más efectivo es hacer todas estas comprobaciones con el mayor espacio libre posible para ejercitar mejor la tarjeta. Si la microSD está casi llena, estaremos escribiendo en pocas secciones de la tarjeta.

Lo importante ahora es recordar que el tamaño de los ficheros ya no tiene que ver con el tamaño de la RAM, podemos usar ficheros comparativamente pequeños.

Mi enfoque habitual es optar por algo del tipo: si la tarjeta de memoria mide 16 GB, debo grabar 64 GB (por decir algo) para ejercitarla. Ahora miro el espacio que tengo libre, digamos 1.2 GB (mal, tendría que haber hecho la comprobación con la tarjeta lo más vacía posible). Un espacio libre de 1.2 GB me permite utilizar dos ficheros de 512 MB, así que grabo 1 GB por pasada del bucle. Por tanto, para cumplir el objetivo de escribir 64 GB, debo ejecutar el bucle 64 veces.

Ajusto el tamaño de los ficheros y el número de vueltas en el bucle a los valores que he calculado y lanzo la prueba.

Advertencia

Aunque cuanto más ejercites la tarjeta microSD más probable es que encuentres un problema en ella (de existir), recuerda que las memorias flash se degradan poco a poco al escribir en ellas, así que si te pasas te cargarás la tarjeta.

Nota

La lectura de /dev/urandom puede ser lenta y frenar el proceso. En mis experimentos estoy viendo velocidades de entre 20 y 40 MB/s. Esto es lento, teniendo en cuenta que primero se genera el fichero en memoria y luego se vuelca a la tarjeta microSD. Podría ser más inteligente sacar del bucle la creación del fichero z1 y el cálculo de su hash, aún a costa de ejercitar menos la tarjeta microSD. Se puede compensar haciendo más verificaciones, pero entonces el rendimiento ganado grabando menos veces un fichero lo perdemos copiando y leyendo más veces el otro. Sería algo a evaluar.