Ayer tuve un pequeño debate con alguien sobre la lógica y / o la veracidad de mi respuesta aquí , vis., Que registrar y mantener metadatos fs en una tarjeta SD decente (GB +) nunca podría ser lo suficientemente importante como para usar la tarjeta fuera en un tiempo razonable (años y años). La esencia del contraargumento parecía ser que debo estar equivocado ya que hay muchas historias en línea de personas que usan tarjetas SD.
Como tengo dispositivos con tarjetas SD que contienen sistemas de archivos raíz rw que se dejan encendidos las 24 horas, los 7 días de la semana, ya había probado la premisa para mi propia satisfacción. He ajustado un poco esta prueba, la he repetido (de hecho, usando la misma tarjeta) y la presento aquí. Las dos preguntas centrales que tengo son:
- ¿Es viable el método que usé para intentar destruir la tarjeta, teniendo en cuenta que está destinado a reproducir los efectos de reescribir continuamente pequeñas cantidades de datos?
- ¿Es viable el método que utilicé para verificar que la tarjeta estaba bien?
Estoy haciendo la pregunta aquí en lugar de SO o SuperUser porque una objeción a la primera parte probablemente tendría que afirmar que mi prueba realmente no escribió en la tarjeta de la manera que estoy seguro, y afirmar que eso requeriría algo de Conocimientos especiales de Linux.
[También podría ser que las tarjetas SD usen algún tipo de almacenamiento en búfer inteligente o caché, de modo que las escrituras repetidas en el mismo lugar se almacenen en la memoria intermedia en un lugar menos propenso al desgaste. No he encontrado ninguna indicación de esto en ninguna parte, pero estoy preguntando sobre eso en SU]
La idea detrás de la prueba es escribir en el mismo bloque pequeño en la tarjeta millones de veces. Esto está más allá de cualquier afirmación de cuántos ciclos de escritura pueden soportar dichos dispositivos, pero suponiendo que la nivelación de desgaste sea efectiva, si la tarjeta es de un tamaño decente, millones de tales escrituras aún no deberían importar mucho, como "el mismo bloque" literalmente no será el mismo bloque físico. Para hacer esto, necesitaba asegurarme de que cada escritura estuviera realmente enjuagada al hardware, y al mismo lugar aparente .
Para el vaciado al hardware, confié en la llamada a la biblioteca POSIX fdatasync()
:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
// Compile std=gnu99
#define BLOCK 1 << 16
int main (void) {
int in = open ("/dev/urandom", O_RDONLY);
if (in < 0) {
fprintf(stderr,"open in %s", strerror(errno));
exit(0);
}
int out = open("/dev/sdb1", O_WRONLY);
if (out < 0) {
fprintf(stderr,"open out %s", strerror(errno));
exit(0);
}
fprintf(stderr,"BEGIN\n");
char buffer[BLOCK];
unsigned int count = 0;
int thousands = 0;
for (unsigned int i = 1; i !=0; i++) {
ssize_t r = read(in, buffer, BLOCK);
ssize_t w = write(out, buffer, BLOCK);
if (r != w) {
fprintf(stderr, "r %d w %d\n", r, w);
if (errno) {
fprintf(stderr,"%s\n", strerror(errno));
break;
}
}
if (fdatasync(out) != 0) {
fprintf(stderr,"Sync failed: %s\n", strerror(errno));
break;
}
count++;
if (!(count % 1000)) {
thousands++;
fprintf(stderr,"%d000...\n", thousands);
}
lseek(out, 0, SEEK_SET);
}
fprintf(stderr,"TOTAL %lu\n", count);
close(in);
close(out);
return 0;
}
Ejecuté esto durante ~ 8 horas, hasta que acumulé más de 2 millones de escrituras al comienzo de la /dev/sdb1
partición. 1 Podría haber utilizado fácilmente /dev/sdb
(el dispositivo sin formato y no la partición) pero no puedo ver qué diferencia haría.
Luego verifiqué la tarjeta tratando de crear y montar un sistema de archivos /dev/sdb1
. Esto funcionó, indicando que el bloque específico en el que había estado escribiendo toda la noche era factible. Sin embargo, esto no significa que algunas regiones de la tarjeta no se hayan desgastado y desplazado por la nivelación del desgaste, sino que se hayan dejado accesibles.
Para probar eso, utilicé badblocks -v -w
en la partición. Esta es una prueba destructiva de lectura y escritura, pero la nivelación de desgaste o no, debería ser una fuerte indicación de la viabilidad de la tarjeta, ya que aún debe proporcionar espacio para cada escritura continua. En otras palabras, es el equivalente literal de llenar la tarjeta por completo y luego verificar que todo estaba bien. Varias veces, desde que dejé que los bloques defectuosos funcionaran con algunos patrones.
[Contra los comentarios de Jason C a continuación, no hay nada de malo o falso en usar bloques malos de esta manera. Si bien no sería útil para identificar bloques defectuosos debido a la naturaleza de las tarjetas SD, está bien realizar pruebas destructivas de lectura y escritura de un tamaño arbitrario utilizando los interruptores -b
y -c
, que es donde se realizó la prueba revisada (vea mi propia respuesta ) Ninguna cantidad de magia o almacenamiento en caché por parte del controlador de la tarjeta puede engañar a una prueba en la que varios megabytes de datos se pueden escribir en el hardware y volver a leer correctamente. Los otros comentarios de Jason parecen estar basados en una lectura errónea: la OMI es intencional , por eso no me he molestado en discutir. Con esa cabeza en alto, le dejo al lector que decida qué tiene sentido y qué no .]
1 La tarjeta era una antigua tarjeta Sandisk de 4 GB (no tiene un número de "clase") que apenas he usado. Una vez más, tenga en cuenta que esto no es 2 millones de escrituras literalmente en el mismo lugar físico; debido a la nivelación del desgaste, el "primer bloque" habrá sido movido constantemente por el controlador durante la prueba para, como dice el término, nivelar el desgaste.
/dev/sdb1
vs /dev/sdb
no hace ninguna diferencia para su programa, pero lo que sí hace una diferencia (como se describe a continuación) es que el estado de los bloques no utilizados en su dispositivo es desconocido y no se tiene en cuenta en su prueba, y a menos que llene todo el dispositivo (por ejemplo, /dev/sdb
) con los datos primero, la cantidad de nivelación de desgaste del espacio con la que tiene que trabajar es una variable importante. Por lo tanto, si bien el dispositivo frente a la partición es irrelevante para su prueba, eso es principalmente una consecuencia de una prueba defectuosa, ya que después de llenar correctamente el dispositivo con datos, por partición no sería una opción disponible (a menos que haya formateado después).
badblocks
para mostrar fallas de página en una unidad flash (y afirmar que es muy engañoso). Esos son manejados por el controlador y mapeados para reservar espacio cuando se detectan. El diseño físico de los datos en el disco no es el mismo que el diseño físico que se ve al hacer E / S, así es como la nivelación del desgaste mantiene su transparencia. Nada de esto es visible para usted durante la E / S. A lo sumo, si la unidad admite SMART, puede obtener una pequeña información sobre fallas y el espacio reservado restante del controlador.