Ontem, entrei em um pequeno debate com alguém sobre a lógica e / ou veracidade da minha resposta aqui , vis., Que registrar e manter metadados fs em um cartão SD de tamanho decente (GB +) nunca poderia ser significativo o suficiente para usar o cartão em um período de tempo razoável (anos e anos). O ponto principal do contra-argumento parecia ser que eu devo estar errado, pois existem muitas histórias on-line de pessoas usando cartões SD.
Como eu tenho dispositivos com cartões SD contendo sistemas de arquivos raiz rw que permanecem 24/7, testei a premissa antes para minha própria satisfação. Ajustei um pouco esse teste, o repeti (usando o mesmo cartão, de fato) e estou apresentando aqui. As duas perguntas centrais que tenho são:
- O método que eu usei para tentar destruir o cartão é viável, tendo em mente que ele pretende reproduzir os efeitos da reescrita contínua de pequenas quantidades de dados?
- O método que eu usei para verificar se o cartão ainda era viável?
Estou colocando a pergunta aqui em vez de SO ou SuperUser, porque uma objeção à primeira parte provavelmente teria que afirmar que meu teste não foi realmente gravado no cartão da maneira que tenho certeza, e afirmar que exigiria alguma conhecimento especial do linux.
[Também pode ser que os cartões SD usem algum tipo de buffer ou cache inteligente, de modo que gravações repetidas no mesmo local sejam armazenadas em buffer / em cache em algum lugar menos propenso a serem desgastadas. Não encontrei nenhuma indicação disso em nenhum lugar, mas estou perguntando sobre isso no SU]
A idéia por trás do teste é escrever no mesmo pequeno bloco no cartão milhões de vezes. Isso está muito além de qualquer reivindicação de quantos ciclos de gravação esses dispositivos podem suportar, mas presumindo que o nivelamento de desgaste seja eficaz, se o cartão for de tamanho decente, milhões dessas gravações ainda não serão importantes, pois "o mesmo bloco" literalmente não seja o mesmo bloco físico. Para fazer isso, eu precisava garantir que todas as gravações fossem realmente liberadas para o hardware e para o mesmo local aparente .
Para liberar o hardware, contei com a chamada da 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;
}
Eu executei isso por ~ 8 horas, até acumular mais de 2 milhões de gravações no início da /dev/sdb1
partição. 1 Eu poderia ter usado facilmente /dev/sdb
(o dispositivo bruto e não a partição), mas não consigo ver que diferença isso faria.
Em seguida, verifiquei o cartão tentando criar e montar um sistema de arquivos /dev/sdb1
. Isso funcionou, indicando que o bloco específico para o qual eu estava escrevendo a noite toda era viável. No entanto, isso não significa que algumas regiões do cartão não tenham sido desgastadas e deslocadas pelo nivelamento de desgaste, mas deixadas acessíveis.
Para testar isso, usei badblocks -v -w
na partição. Este é um teste de leitura e gravação destrutivo , mas com desgaste nivelado ou não, deve ser uma forte indicação da viabilidade do cartão, pois ele ainda deve fornecer espaço para cada gravação rotativa. Em outras palavras, é o equivalente literal de encher completamente o cartão e verificar se tudo estava bem. Várias vezes, desde que deixei os badblocks trabalharem em alguns padrões.
[Contra os comentários de Jason C abaixo, não há nada de errado ou falso em usar badblocks dessa maneira. Embora não seja útil para realmente identificar blocos defeituosos devido à natureza dos cartões SD, é bom fazer testes de leitura e gravação destrutivos de tamanho arbitrário usando as opções -b
e -c
, que é onde o teste revisado foi (veja minha própria resposta ) Nenhuma quantidade de mágica ou armazenamento em cache pelo controlador do cartão pode enganar um teste no qual vários megabytes de dados podem ser gravados no hardware e lidos novamente corretamente. Os outros comentários de Jason parecem baseados em uma leitura errada - a OMI é intencional , e é por isso que não me preocupei em discutir. Com essa ideia, deixo ao leitor decidir o que faz sentido e o que não faz .]
1 O cartão era um cartão Sandisk antigo de 4 GB (não possui um número de "classe") que eu mal usei. Mais uma vez, lembre-se de que não são 2 milhões de gravações no mesmo local físico; devido ao nivelamento do desgaste, o "primeiro bloco" será movido constantemente pelo controlador durante o teste para, como afirma o termo, nivelar o desgaste.
badblocks
para mostrar falhas de página em uma unidade flash (e alegar que isso é muito enganador). Esses são manipulados pelo controlador e mapeados para reservar espaço quando detectados. O layout físico dos dados na unidade não é o mesmo que você vê ao realizar E / S, é assim que o nivelamento de desgaste mantém sua transparência. Nada disso é visível para você durante a E / S. No máximo, se a unidade oferecer suporte ao SMART, você poderá obter algumas informações sobre falhas e espaço reservado restante do controlador./dev/sdb1
vs,/dev/sdb
não faz diferença para o seu programa, mas o que faz diferença (como descrito abaixo) é que o estado dos blocos não utilizados no seu dispositivo é desconhecido e inexplicado no seu teste, e a menos que você preencha todo o dispositivo (por exemplo,/dev/sdb
) com os dados primeiro, a quantidade de nivelamento de desgaste de espaço com a qual trabalhar é uma variável importante. Portanto, embora o dispositivo x partição seja irrelevante para o seu teste, isso é principalmente uma consequência de um teste defeituoso, pois após o preenchimento correto do dispositivo com dados, a partição por partição não seria uma opção disponível (a menos que você tenha formatado depois).Respostas:
Eu acho que o teste de estresse de um cartão SD é geralmente problemático, considerando duas coisas:
nivelamento de desgaste Não há garantias de que uma gravação para a próxima esteja realmente exercitando os mesmos locais físicos no SD. Lembre-se de que a maioria dos sistemas de SD instalados ativamente está bloqueando o que conhecemos e movendo o local físico que o suporta com base no "desgaste" percebido ao qual cada local foi submetido.
tecnologias diferentes (MLC vs. SLC) A outra questão que vejo com isso é a diferença de tecnologias. Tipos de SSD de SLC Eu esperaria ter uma vida muito mais longa do que a variedade MLC. Além disso, existem tolerâncias muito mais rígidas no MLC com as quais você não precisa lidar com os SLCs, ou pelo menos eles são muito mais tolerantes a falhas dessa maneira.
O problema com o MLC é que uma determinada célula pode armazenar vários valores, os bits são essencialmente empilhados usando uma tensão, em vez de serem apenas físicos + 5V ou 0V, por exemplo, para que isso possa levar a um potencial de taxa de falha muito maior do que o seu SLC equivalente.
Expectativa de vida
Encontrei este link que discute um pouco sobre quanto tempo o hardware pode durar. É intitulado: Conheça seus SSDs - SLC vs. MLC .
SLC
MLC
Comparações
fonte
fstrim
posteriormente, desabilitou totalmente o nivelamento dinâmico de desgaste [seria difícil encontrar um cartão SD de nível consumidor com nivelamento estático] por marcando cada página como usado).Existem vários problemas no seu teste, alguns confusos, outros não. Também depende do seu objetivo. Dois problemas sutis e confusos são:
No entanto, esses são indiscutivelmente pedantes. Mais sério é:
badblocks
para mostrar as páginas com falha na memória flash; todas as detecções de falhas e mapeamentos de páginas subsequentes são feitos pelo controlador e são transparentes para o sistema operacional. Você pode obter algumas informações da SMART se a unidade suportar (não conheço cartões SD compatíveis com isso, talvez haja pen drives de ponta).Nivelamento de desgaste: a questão principal é que o nivelamento de desgaste é uma variável importante em seu teste. Isso acontece no controlador (normalmente) e, em qualquer caso, é transparente, até o dispositivo direto busca + lê / escreve. No seu exemplo, você não conhece o estado de nivelamento de desgaste (em particular, os comandos TRIM foram emitidos para liberar blocos recentemente?) ...
Para o nivelamento dinâmico de desgaste (presente em praticamente todos os dispositivos de armazenamento de consumo) no seu dispositivo, ele pode estar em qualquer estado: Em um extremo, nenhuma das páginas é marcada como livre e, portanto, as únicas páginas em que o controlador precisa funcionar com são os que estão no espaço reservado (se houver). Note-se que se não é espaço reservado no dispositivo, ele vai ter que falhar completamente antes de começar a ficar garantida falha nas gravações de página (presumindo que não há outras páginas marcadas como permanecer livre). No outro extremo, todas as páginas são marcadas como livres; nesse caso, teoricamente, é necessário que todas as páginas do dispositivo falhem antes de começar a ver falhas de gravação.
Para nivelar o desgaste estático (que os SSDs costumam ter, os cartões SD tendem a não ter e os pen drives variam): Não há realmente nenhuma maneira de contornar isso, além de escrever repetidamente em todas as páginas do dispositivo.
... Em outras palavras, existem detalhes de nivelamento de desgaste que você não tem como saber e certamente não tem como controlar - particularmente se o nivelamento dinâmico está ou não em uso, se está em uso ou não o nivelamento estático e quantidade de espaço reservado no dispositivo para o nivelamento de desgaste (que não é visível após o controlador [ou driver em alguns casos, como o DiskOnChip antigo da M-Systems]).
SLC / MLC: quanto ao SLC vs. MLC, isso tem um impacto muito direto nos limites que você esperaria ver, mas o procedimento geral de nivelamento de desgaste e o procedimento de teste são os mesmos para ambos. Muitos fornecedores não publicam se seus dispositivos são ou não SLC ou MLC para seus produtos de consumo mais baratos, embora qualquer unidade flash que reivindique um limite de ciclo de 100k + por página seja provavelmente SLC (a troca simplificada é SLC = resistência, MLC = densidade).
Armazenamento em cache: quanto ao armazenamento em cache, é um pouco duvidoso. No nível do SO, no caso geral, é claro, o fsync / fdatasync não garante que os dados sejam realmente gravados. No entanto, acho que é seguro presumir que seja (ou pelo menos o controlador se comprometeu a fazê-lo, ou seja, a gravação não será engolida no cache) nesse caso, pois as unidades removíveis geralmente são projetadas para o padrão de uso comum de "ejetar" (desmontar> sincronizar) e remover (corte de energia). Embora não tenhamos certeza, um palpite instruído diz que é seguro assumir que a sincronização garante que a gravação ocorra absolutamente, especialmente em write -> sync -> read back (se não fosse, as unidades não seriam confiáveis) após a ejeção). Não há outro comando além de 'sync' que possa ser emitido na ejeção.
No controlador, tudo é possível, mas a suposição acima também inclui a suposição de que o controlador pelo menos não está fazendo algo "complicado" o suficiente para arriscar a perda de dados após uma sincronização. É concebível que o controlador possa, digamos, gravar em buffer e em grupo, ou não gravar dados se os mesmos dados estiverem sendo reescritos (em uma extensão limitada). No programa abaixo, alternamos entre dois blocos de dados diferentes e executamos uma sincronização antes da leitura especificamente para eliminar um mecanismo razoável de armazenamento em cache do controlador. Ainda assim, é claro, não há garantias nem meios de conhecimento, mas podemos fazer suposições razoáveis com base no uso normal desses dispositivos e mecanismos de cache comuns / sãos.
Teste:
Infelizmente, a verdade é que, a menos que você saiba que o dispositivo não possui espaço reservado e não está fazendo nivelamento estático, não há como testar definitivamente o limite de ciclo de uma página específica. No entanto, o mais próximo possível é o seguinte (presuma que não haja nivelamento estático do desgaste):
A primeira coisa que você precisa fazer é preencher o cartão inteiro com dados. Isso é importante e é a principal variável que foi deixada no seu teste original. Isso marca o maior número possível de blocos usados, além de qualquer espaço reservado (que você não tem como acessar). Observe que estamos trabalhando com um dispositivo inteiro (no qual isso destruirá todos os dados), pois trabalhar com uma única partição afeta apenas uma área específica do dispositivo:
Se você é do tipo barra de progresso:
Editar: Para cartões com blocos de apagamento de 4 MB, tente isso para uma gravação mais rápida:
Em seguida, você pode escrever um programa de teste de ciclo da seguinte forma, usando
O_DIRECT
eO_SYNC
(e possivelmente paranóico, uso redundante defsync()
) para reduzir o máximo possível de buffer e cache do sistema operacional e, teoricamente, gravar diretamente no controlador e aguarde até relatar que a operação foi concluída:Observe que
O_DIRECT
, para , os buffers devem estar adequadamente alinhados. Os limites de 512 bytes são geralmente suficientes. Você pode compilar com:Adicione
-D_POSIX_C_SOURCE=200112L
se necessário.Depois de encher o dispositivo completamente como acima, deixe-o funcionar durante a noite:
Gravações alinhadas de 512 bytes são perfeitas, o que fornecerá uma página inteira apagada e reescrita. Você pode acelerar significativamente o teste usando um tamanho de bloco maior, mas fica complicado obter resultados concretos.
Atualmente, estou testando um pen drive PNY PNB de 4 GB que encontrei na calçada ontem (parecia o que restava de um http://www3.pny.com/4GB-Micro-Sleek-Attach-- -Purple-P2990C418.aspx ).
O programa acima é essencialmente uma versão limitada
badblocks
e você não veria falhas até que todo o espaço reservado estivesse esgotado. Portanto, a expectativa (com 1 página gravada por iteração) é que o procedimento acima falhe, em média, nas iterações reservados_página_count * write_cycle_limit (novamente, o nivelamento de desgaste é uma variável importante). É pena que pen drives e cartões SD geralmente não suportam o SMART, que tem a capacidade de relatar o tamanho do espaço reservado.A propósito, o
fsync
vsfdatasync
não faz diferença para as gravações do dispositivo de bloco que você está fazendo, para os fins deste teste. Seusopen()
modos são importantes.Se você está curioso sobre detalhes técnicos; Aqui está tudo o que você pode querer saber (além de mais) sobre o funcionamento interno dos cartões SD: https://www.sdcard.org/downloads/pls/simplified_specs/part1_410.pdf
Edit: Bytes vs Páginas: No contexto desses tipos de testes, é importante pensar nas coisas em termos de páginas, não de bytes. Pode ser muito enganador fazer o oposto. Por exemplo, em um SanDisk de 8 GB SD, o tamanho da página de acordo com o controlador (acessível via
/sys/classes/mmc_host/mmc?/mmc?:????/preferred_erase_size
) é de 4 MB. Escrevendo 16 MB (alinhado aos limites de 4 MB), apague / grave 4 páginas. No entanto, escrever quatro bytes únicos, cada um com 4 MB de deslocamento, também apaga / grava 4 páginas.É impreciso dizer "testei com gravações de 16 MB", pois é a mesma quantidade de desgaste que "testei com gravações de 4 bytes". Mais precisamente, "testei com gravações de 4 páginas".
fonte
dd
falha após gravar 250 MB . O dano não apareceu até depois do ciclo de energia. O pen drive PNY permanece inalterado após ~ 30mil iterações. Eu modifiquei o programa acima (no entanto, não refletido no código acima) para gravar em locais aleatórios alinhados a 16kB de cada vez, em vez do mesmo, mas fiz isso depois de ~ 4mil iters no SD. Teste novamente com o novo cartão.dd
nesse cartão ultrapassou a marca de 250 MB e o desempenho de gravação aumentou novamente para os 4 MB / s completos em áreas após esse ponto. Espero que o desempenho seja imprevisível, pois os blocos continuam sendo embaralhados. Eu não diria que o cartão está destruído, mas certamente não está em 100%.Apenas adicionando alguns pontos à resposta da slm - observe que eles são mais úteis para SSDs do que para cartões SD "burros", pois os SSDs fazem truques muito mais sujos com seus dados (por exemplo, deduplicação):
você está escrevendo 64 KB no início do dispositivo - isso por si só tem dois problemas:
as células flash geralmente têm blocos de tamanho apagados a partir de 16 KB (mais provável na faixa de 128-512 KB). O que significa que ele precisa de cache de pelo menos esse tamanho. Portanto, escrever 64 KB não parece ser suficiente para mim.
para soluções low-end (leia-se "não empresariais") (e eu esperaria isso ainda mais para os cartões SD / CF do que para SSDs), os fabricantes podem optar por tornar o início do dispositivo mais resistente ao desgaste do que o resto, já que o estruturas importantes - a tabela de partições e o FAT na partição única no dispositivo (a maioria dos cartões de memória está usando essa configuração) - estão localizadas lá. Assim, testar o início do cartão pode ser tendencioso.
fdatasync()
realmente não garante que os dados sejam gravados no meio físico (embora provavelmente faça o melhor que está sob o controle do sistema operacional) - consulte a página de manual:Eu não ficaria surpreso se houvesse um pequeno capacitor capaz de fornecer energia para gravar dados em cache na memória flash em caso de perda de energia externa.
De qualquer forma, sob a suposição de que um cache esteja presente no cartão (veja minha resposta à sua pergunta na SU ), escrever 64 KB e sincronizar (com
fdatasync()
) não parece convincente o suficiente para esse fim. Mesmo sem nenhum "backup de energia", o firmware ainda pode reproduzi-lo sem segurança e manter os dados não gravados por um tempo mais longo do que o esperado (já que em casos de uso típicos não deve haver problemas).convém ler os dados antes de escrever um novo bloco e compará-lo, apenas para garantir que ele realmente funcione (e use um buffer limpo para a leitura, se você for paranóico o suficiente).
fonte
read
teste é desnecessário, não adiciona informações e não é relevante para um teste de ciclo de gravação. Para um teste verdadeiro, você deve ler novamente o bloco que acabou de escrever e validá-lo, a menos que saiba com certeza que o controlador pode detectar e relatar todos os modos de falha.A resposta de Peterph me fez considerar a questão de um possível cache adicional. Depois de cavar, ainda não posso dizer com certeza se algum, alguns ou todos os cartões SD fazem isso, mas acho que é possível.
No entanto, não acredito que o cache envolva dados maiores que o bloco de apagamento. Para ter certeza, repeti o teste usando um pedaço de 16 MB em vez de 64 kB. Isso representa 1/50 do volume total do cartão de 4 GB. Demorou ~ 8 horas para fazer isso 10.000 vezes. Se o nivelamento do desgaste fizer o possível para espalhar a carga, isso significa que cada bloco físico teria sido usado 40 vezes.
Isso não é muito, mas o objetivo original do teste era demonstrar a eficácia do nivelamento de desgaste , mostrando que eu não poderia danificar facilmente o cartão através de gravações repetidas de quantidades modestas de dados no mesmo local (aparente). Na IMO, o teste anterior de 64 kB provavelmente era real - mas o de 16 MB deve ser. O sistema liberou os dados para o hardware e o hardware relatou a gravação sem erro. Se isso fosse um engano, o cartão não seria bom para nada e não pode ser armazenado em cache 16 MB em qualquer outro lugar, exceto no armazenamento primário, que é o que o teste deve enfatizar.
Felizmente, 10.000 gravações de 16 MB cada são suficientes para demonstrar que, mesmo em um cartão de marca de baixo valor (valor: US $ 5 CDN), executar um sistema de arquivos raiz rw 24/7 que grava quantidades modestas de dados diariamente não desgastará o cartão. um período de tempo razoável. 10.000 dias são 27 anos ... e o cartão ainda está bom ...
Se eu estivesse sendo pago para desenvolver sistemas que funcionavam mais pesado que isso, gostaria de fazer pelo menos alguns testes para determinar quanto tempo um cartão pode durar. Meu palpite é que, com alguém assim, que tem uma velocidade de gravação baixa, pode levar semanas, meses ou anos de gravação contínua na velocidade máxima (o fato de não haver muitos testes comparativos desse tipo on-line fala com o fato de que seria um caso muito prolongado).
No que diz respeito a confirmar que o cartão ainda está bom, não acho mais
badblocks
apropriado usar a configuração padrão. Em vez disso, fiz desta maneira:O que significa testar usando um bloco de 512 kB repetido 8 vezes (= 4 MB). Como esse é um teste destrutivo de rw, provavelmente seria bom como um teste caseiro em relação à tensão do dispositivo se usado em um loop contínuo.
Também criei um sistema de arquivos nele, copiei em um arquivo de 2 GB, coloquei
diff
o arquivo no original e, em seguida - como o arquivo era um .iso - montei-o como uma imagem e naveguei no sistema de arquivos dentro dele.O cartão ainda está bom. O que provavelmente é esperado, afinal ...
;);)
fonte
badblocks
não mostrará as páginas com falha na memória flash. Não é a ferramenta certa para este trabalho e você não pode usá-lo para encontrar páginas com falha no flash. Quando o controlador detecta uma falha, ele marca internamente a página como incorreta e remapeia para uma página no espaço reservado. Tudo isso acontece atrás do controlador e não é visível para você, mesmo em um despejo bruto de dispositivo . Você pode obter algumas informações do controlador se o SMART for suportado. A ordem física dos dados no dispositivo não corresponde à ordem dos bytes que você vê ao executar E / S no dispositivo.dd
não conseguiu gravar os 250 MB marca. Na terceiradd
tentativa, ultrapassou os 250 MB e, quando o fez, o desempenho de gravação aumentou novamente nessas áreas. Eu não diria que o cartão está destruído, mas certamente não está em 100%.