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.
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./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).Respuestas:
Creo que la prueba de esfuerzo de una tarjeta SD es en general problemática debido a 2 cosas:
nivelación de desgaste No hay garantías de que una escritura a la siguiente realmente esté ejerciendo las mismas ubicaciones físicas en la SD. Recuerde que la mayoría de los sistemas SD en el lugar toman activamente un bloque tal como lo conocemos y mueven la ubicación física que lo respalda en función del "desgaste" percibido al que se ha sometido cada ubicación.
diferentes tecnologías (MLC vs. SLC) El otro problema que veo con esto es la diferencia en las tecnologías. Tipos de SSD SLC Esperaría tener una vida mucho más larga en comparación con la variedad MLC. También hay tolerancias mucho más estrictas en MLC con las que simplemente no tiene que lidiar con las SLC, o al menos son mucho más tolerantes a fallar de esta manera.
El problema con MLC es que una celda determinada puede almacenar múltiples valores, los bits se apilan esencialmente usando un voltaje, en lugar de ser simplemente un físico + 5V o 0V, por ejemplo, por lo que esto puede conducir a un potencial de tasa de falla mucho mayor que su SLC equivalente.
Esperanza de vida
Encontré este enlace que discute un poco sobre cuánto tiempo puede durar el hardware. Se titula: Conozca sus SSD: SLC vs. MLC .
SLC
MLC
Comparaciones
fuente
fstrim
después, has desactivado por completo la nivelación de desgaste dinámica [sería difícil encontrar una tarjeta SD de grado de consumidor con nivelación de desgaste estática] marcando cada página como se usa.)Hay una serie de problemas con su prueba, algunos difusos, otros no. También depende de tu objetivo. Dos cuestiones sutiles y poco claras son:
Sin embargo, esos son posiblemente pedantes. Más serio es:
badblocks
para mostrar páginas fallidas en la memoria flash; el controlador realiza todas las detecciones de fallas y las asignaciones de páginas subsiguientes y son transparentes para el sistema operativo. Puede obtener información de SMART si la unidad lo admite (no conozco ninguna tarjeta SD que lo admita, tal vez haya unidades de memoria USB de extremo superior que lo hagan).Nivelación de desgaste: el problema principal es que la nivelación de desgaste es una variable importante en su prueba. Sucede en el controlador (generalmente) y, en cualquier caso, es transparente para incluso buscar / leer / escribir en el dispositivo. En su ejemplo, en realidad no conoce el estado de nivelación del desgaste (en particular, ¿se han emitido comandos TRIM para bloques libres recientemente?) ...
Para la nivelación de desgaste dinámica (presente en prácticamente todos los dispositivos de almacenamiento de grado de consumo) en su dispositivo, entonces, podría estar en cualquier estado: en un extremo, ninguna de las páginas está marcada como libre, por lo que las únicas páginas que el controlador tiene que funcionar con son los que están en el espacio reservado (si corresponde). Tenga en cuenta que si hay es espacio reservado en el dispositivo, que se tiene que fallar por completo antes de empezar a recibir garantizado no en las escrituras de página (suponiendo que no hay otras páginas marcadas como permanecer libre). En el otro extremo, cada página se marca como libre, en cuyo caso, teóricamente, debe hacer que todas las páginas del dispositivo fallen antes de comenzar a ver fallas de escritura.
Para nivelar el desgaste estático (que los SSD tienden a tener, las tarjetas SD tienden a no tener, y las unidades de memoria varían): Realmente no hay forma de evitarlo, aparte de escribir repetidamente en cada página del dispositivo.
... En otras palabras, hay detalles de nivelación de desgaste que no tiene forma de conocer y, desde luego, no hay forma de controlar, especialmente si la nivelación de desgaste dinámica está en uso o no, si la nivelación de desgaste estática está o no en uso, y cantidad de espacio reservado en el dispositivo para nivelar el desgaste (que no es visible más allá del controlador [o controlador en algunos casos, como el antiguo DiskOnChip de M-Systems]).
SLC / MLC: En cuanto a SLC vs. MLC, esto tiene un impacto muy directo en los límites que esperaría ver, pero el procedimiento general de nivelación de desgaste y el procedimiento de prueba es el mismo para ambos. Muchos proveedores no publican si sus dispositivos son SLC o MLC para sus productos de consumo más baratos, aunque cualquier unidad flash que afirme tener un límite de ciclo de 100k + por página es probablemente SLC (la compensación simplificada es SLC = resistencia, MLC = densidad).
Almacenamiento en caché: en cuanto al almacenamiento en caché, es un poco dudoso. A nivel del sistema operativo, en el caso general, por supuesto, fsync / fdatasync no garantiza que los datos estén realmente escritos. Sin embargo, creo que es seguro suponer que lo es (o al menos el controlador se ha comprometido a hacerlo, es decir, la escritura no se tragará en la memoria caché) en este caso, ya que las unidades extraíbles generalmente están diseñadas para el patrón de uso común de "expulsar" (desmontar> sincronización) y luego eliminar (corte de energía). Si bien no estamos seguros, una suposición educada dice que es seguro asumir que la sincronización garantiza que la escritura se llevará a cabo absolutamente, especialmente en escritura -> sincronización -> lectura (si no fuera así, las unidades no serían confiables) después de expulsar). No hay otro comando más allá de 'sincronización' que pueda emitirse al expulsar.
En el controlador todo es posible, pero la suposición anterior también incluye la suposición de que el controlador al menos no está haciendo nada lo suficientemente "complicado" como para arriesgar la pérdida de datos después de una sincronización. Es concebible que el controlador pueda, por ejemplo, escribir en el búfer y en grupo, o no escribir datos si se reescriben los mismos datos (hasta cierto punto). En el siguiente programa, alternamos entre dos bloques diferentes de datos y realizamos una sincronización antes de la lectura específica para vencer un mecanismo razonable de almacenamiento en caché del controlador. Aún así, por supuesto, no hay garantías ni forma de saberlo, pero podemos hacer suposiciones razonables basadas en el uso normal de estos dispositivos y mecanismos de almacenamiento en caché sanos / comunes.
Pruebas:
Desafortunadamente, la verdad es que, a menos que sepa que el dispositivo no tiene espacio reservado y no está haciendo nivelación estática, no hay forma de probar definitivamente el límite de ciclo de una página específica. Sin embargo, lo más cercano que puede obtener es el siguiente (supongamos que no hay nivelación de desgaste estático):
Lo primero que debe hacer es llenar toda la tarjeta con datos. Esto es importante y es la variable principal que quedó en su prueba original. Esto marca tantos bloques como sea posible, aparte de cualquier espacio reservado (al que no tiene forma de acceder). Tenga en cuenta que estamos trabajando con un dispositivo completo (que destruirá todos los datos), ya que trabajar con una sola partición solo afecta a un área específica del dispositivo:
Si eres el tipo de barra de progreso:
Editar: para tarjetas con bloques de borrado de 4 MB, intente esto para una escritura más rápida:
Luego, puede escribir un programa de prueba de ciclo de la siguiente manera, haciendo uso de
O_DIRECT
yO_SYNC
(y posiblemente paranoico, uso redundante defsync()
) para cortar la mayor cantidad de almacenamiento en el sistema operativo y almacenamiento en caché de la imagen como sea posible y, en teoría, escribir directamente en el controlador y espere hasta que informe que la operación ha finalizado:Tenga en cuenta que para
O_DIRECT
, los buffers deben estar adecuadamente alineados. Los límites de 512 bytes son generalmente suficientes. Puedes compilar con:Añadir
-D_POSIX_C_SOURCE=200112L
si es necesario.Luego, después de llenar el dispositivo por completo como se indicó anteriormente, simplemente déjelo funcionando durante la noche:
512 bytes, las escrituras alineadas están bien, eso le dará una página completa borrada y reescrita. Podría acelerar significativamente la prueba utilizando un tamaño de bloque más grande, pero luego se vuelve complicado llegar a resultados concretos.
Actualmente estoy probando en una unidad de disco duro de 4GB PNY bastante destartalada que encontré ayer en la acera (parecía ser lo que quedaba de un http://www3.pny.com/4GB-Micro-Sleek-Attach-- -Púrpura-P2990C418.aspx ).
El programa anterior es esencialmente una versión limitada
badblocks
y no verá fallas hasta que se agote todo el espacio reservado. Por lo tanto, la expectativa (con 1 página escrita por iteración) es que el procedimiento anterior, en promedio, debe fallar en las iteraciones reserved_page_count * write_cycle_limit (nuevamente, la nivelación del desgaste es una variable importante). Es una memoria USB demasiado mala y las tarjetas SD no suelen admitir SMART, que tiene la capacidad de informar el tamaño de espacio reservado.Por cierto,
fsync
vsfdatasync
no hace ninguna diferencia para las escrituras del dispositivo de bloque que está haciendo, para los fines de esta prueba. Tusopen()
modos son importantes.Si tiene curiosidad acerca de los detalles técnicos; Aquí está todo lo que le gustaría saber (y más) sobre el funcionamiento interno de las tarjetas SD: https://www.sdcard.org/downloads/pls/simplified_specs/part1_410.pdf
Editar: Bytes vs páginas: en el contexto de este tipo de pruebas, es importante pensar las cosas en términos de páginas, no bytes. Puede ser muy engañoso hacer lo contrario. Por ejemplo, en un SanDisk 8GB SD, el tamaño de página de acuerdo con el controlador (accesible a través de
/sys/classes/mmc_host/mmc?/mmc?:????/preferred_erase_size
) es un total de 4 MB. Escribiendo 16MB (alineado con los límites de 4MB), luego, borra / escribe 4 páginas. Sin embargo, escribir cuatro bytes individuales cada uno a 4MB de compensación entre sí también borra / escribe 4 páginas.Es incorrecto, entonces decir "Probé con escrituras de 16MB", ya que es la misma cantidad de desgaste que "Probé con escrituras de 4 bytes". Más exactamente, "Probé con 4 páginas escritas".
fuente
dd
falla después de escribir 250MB . El daño no apareció hasta después del ciclo de energía. La memoria USB PNY no se ve afectada después de ~ 30mil iteraciones. Sin embargo, modifiqué el programa anterior (no se refleja en el código anterior) para escribir en ubicaciones aleatorias alineadas a 16kB en lugar de lo mismo, pero lo hice después de ~ 4mil iters en SD. Volverá a probar con nueva tarjeta.dd
esa tarjeta superó la marca de 250 MB, y el rendimiento de escritura aumentó nuevamente a 4 MB / s completos en las áreas después de ese punto. Sin embargo, espero que el rendimiento sea impredecible, ya que los bloques continúan barajándose. No diría que la tarjeta está destruida, pero ciertamente no está al 100%.Simplemente agregue algunos puntos a la respuesta de slm: tenga en cuenta que estos son más adecuados para las SSD que para las tarjetas SD "tontas", ya que las SSD juegan trucos mucho más sucios con sus datos (por ejemplo, desduplicación):
está escribiendo 64 KB al comienzo del dispositivo; esto tiene dos problemas:
Las celdas flash generalmente tienen bloques de tamaño de borrado de 16 KB en adelante (aunque es más probable en el rango de 128-512 KB). Lo que significa que necesita caché de al menos este tamaño. Por lo tanto, escribir 64 KB no me parece suficiente.
para soluciones de gama baja (léase "no empresarial") (y esperaría esto aún más para las tarjetas SD / CF que para las SSD) los fabricantes pueden optar por hacer que el comienzo del dispositivo sea más resistente al desgaste que el resto desde el resto estructuras importantes - la tabla de particiones y FAT en la partición única en el dispositivo (la mayoría de las tarjetas de memoria están usando esta configuración) - se encuentran allí. Por lo tanto, probar el comienzo de la tarjeta puede estar sesgado.
fdatasync()
en realidad no garantiza que los datos se escriban en el medio físico (aunque probablemente haga lo mejor que está bajo el control del sistema operativo); consulte la página del manual:No me sorprendería demasiado si resultara que hay un pequeño condensador, que puede proporcionar energía para escribir datos almacenados en caché en la memoria flash en caso de pérdida de energía externa.
En cualquier caso, bajo el supuesto de que hay un caché presente en la tarjeta (vea mi respuesta a su pregunta en SU ), escribir 64 KB y sincronizar (con
fdatasync()
) no parece ser lo suficientemente convincente para este propósito. Incluso sin ninguna "copia de seguridad de energía", el firmware podría reproducirse de forma insegura y mantener los datos sin escribir durante un tiempo más largo de lo que cabría esperar (ya que en casos de uso típicos no debería crear ningún problema).es posible que desee leer los datos antes de escribir un nuevo bloque y compararlo, solo para asegurarse de que realmente funcione (y use un búfer despejado para la lectura, si es lo suficientemente paranoico).
fuente
read
en su prueba es innecesario, no agrega información y no es relevante para una prueba de ciclo de escritura. Para una prueba verdadera, querrá volver a leer el bloque que acaba de escribir y validarlo, a menos que sepa con certeza que el controlador puede detectar e informar todos los modos de falla.La respuesta de Peterph me hizo considerar aún más el problema del posible almacenamiento en caché. Después de investigar, todavía no puedo decir con certeza si alguna, algunas o todas las tarjetas SD hacen esto, pero creo que es posible.
Sin embargo, no creo que el almacenamiento en caché implique datos más grandes que el bloque de borrado. Para estar realmente seguro, repetí la prueba usando un fragmento de 16 MB en lugar de 64 kB. Esto es 1/ 250 del volumen total de la tarjeta de 4 GB. Le tomó ~ 8 horas hacer esto 10,000 veces. Si la nivelación del desgaste hace todo lo posible para repartir la carga, esto significa que cada bloque físico se habría utilizado 40 veces.
Eso no es mucho, pero el punto original de la prueba fue demostrar la eficacia de la nivelación de desgaste al mostrar que no podía dañar fácilmente la tarjeta a través de escrituras repetidas de cantidades modestas de datos en la misma ubicación (aparente). En mi opinión, la prueba anterior de 64 kB probablemente fue real, pero la de 16 MB debe serlo. El sistema ha vaciado los datos al hardware y el hardware ha informado la escritura sin error. Si esto fuera un engaño, la tarjeta no sería buena para nada, y no puede almacenar en caché 16 MB en ningún otro lugar que no sea el almacenamiento primario, que es lo que la prueba pretende enfatizar.
Afortunadamente, 10,000 escrituras de 16 MB cada una son suficientes para demostrar que incluso en una tarjeta de marca de extremo inferior (valor: $ 5 CDN), ejecutar un sistema de archivos raíz rw 24/7 que escribe cantidades modestas de datos diariamente no desgastará la tarjeta en un período de tiempo razonable 10,000 días son 27 años ... y la tarjeta aún está bien ...
Si me pagaran por desarrollar sistemas que hicieran un trabajo más pesado que eso, me gustaría hacer al menos algunas pruebas para determinar cuánto tiempo puede durar una tarjeta . Mi presentimiento es que con uno como este, que tiene una velocidad de escritura baja, podría llevar semanas, meses o años de escritura continua a la velocidad máxima (el hecho de que no haya montones de pruebas comparativas de este tipo en línea habla del hecho de que sería un asunto muy prolongado).
Con respecto a confirmar que la tarjeta todavía está bien, ya no creo
badblocks
que sea apropiado usar su configuración predeterminada. En cambio, lo hice de esta manera:Lo que significa probar usando un bloque de 512 kB repetido 8 veces (= 4 MB). Dado que esta es una prueba destructiva de rw, probablemente sería buena como mi prueba casera con respecto al estrés del dispositivo si se usa en un bucle continuo.
También he creado un sistema de archivos en él, copiado en un archivo de 2 GB,
diff
el archivo se comparó con el original y luego, dado que el archivo era un .iso, lo monté como una imagen y examiné el sistema de archivos dentro de él.La tarjeta aún está bien. Lo que probablemente sea de esperar, después de todo ...
;);)
fuente
badblocks
no le mostrará páginas fallidas en la memoria flash. No es la herramienta adecuada para este trabajo y no puede usarla para encontrar páginas fallidas en flash. Cuando el controlador detecta una falla, marcará internamente la página como incorrecta y la reasignará a una página en un espacio reservado. Todo esto sucede detrás del controlador y no es visible para usted, incluso en un volcado de dispositivo sin formato, en absoluto . Puede obtener información del controlador si SMART es compatible. El orden físico de los datos en el dispositivo no coincide con el orden de bytes que ve al hacer IO en el dispositivo.dd
no pudo superar los 250MB marca. En el tercerdd
intento, superó los 250 MB y una vez que lo hizo, el rendimiento de escritura aumentó nuevamente en esas áreas. No diría que la tarjeta está destruida, pero ciertamente no está al 100%.