Teste de estresse de cartões SD usando Linux

19

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:

  1. 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?
  2. 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/sdb1partiçã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 -wna 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 -be -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.

Cachinhos Dourados
fonte
Este é um teste não confiável pelas razões descritas abaixo. Além disso, você não pode usar badblockspara 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.
Jason C
Quanto ao /dev/sdb1vs, /dev/sdbnã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).
Jason C
Outro ponto que torna o teste irrealista é que uma página pode (e geralmente falha), mas ainda deixa o cartão SD 100% utilizável posteriormente. No caso em que uma falha é detectada e mascarada pelo controlador, mas os dados não podem ser lidos, os dados do sistema de arquivos podem ficar corrompidos quando o controlador tenta copiar o bloco.
Jason C
Eu lhe digo o que - descreva-me em termos específicos um teste reproduzível que gasta um cartão SD e, então, eu o levo a sério. Irreproduzíveis "reivindicações de autoridade" e histórias pessoais são exatamente isso. Argumentum ab auctoritate
goldilocks
1
Eu não sei sobre esse cartão em particular, mas a maioria deles já está pelo menos um pouco morta de qualquer maneira. Esses caras invadiram o microcontrolador em pelo menos uma marca de cartão SD: bunniestudios.com/blog/?p=3554 O horário que eles fizeram sobre o assunto foi muito bom.
mikeserv

Respostas:

11

Eu acho que o teste de estresse de um cartão SD é geralmente problemático, considerando duas coisas:

  1. 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.

  2. 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.

    • MLC - Célula de vários níveis
    • SLC - Célula de nível único

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

Os ssds SLC podem ser calculados, em sua maioria, para viver entre 49 e 149 anos, em média, pelas melhores estimativas. O teste Memoright pode validar o SSD de 128 GB com uma vida útil de duração de gravação superior a 200 anos, com uma gravação média de 100 GB por dia.

MLC

É aqui que o design do mlc fica aquém. Nenhum foi lançado até o momento. Ninguém realmente examinou que tipo de expectativa de vida é garantida com o mlc, exceto que será consideravelmente menor. Recebi várias crenças diferentes, com média de vida útil de 10 a 1 a favor do design slc. Um palpite conservador é que a maioria das estimativas de vida útil durará entre 7 e 10 anos, dependendo do avanço dos 'algoritmos de nivelamento de desgaste' nos controladores de cada fabricante.

Comparações

Para desenhar a comparação por meio de ciclos de gravação, um slc teria uma vida útil de 100.000 ciclos completos de gravação em comparação com o mlc que possui uma vida útil de 10.000 ciclos de gravação. Isso pode aumentar significativamente, dependendo do design do 'nivelamento de desgaste' utilizado.

slm
fonte
1
WRT wear leveling "Não há garantias de que uma gravação para a próxima esteja realmente exercitando os mesmos locais físicos no SD" - o que é assumido na pergunta slm! De maneira bem explícita, eu acho ... Sem o nivelamento de desgaste, eu nunca esperaria que esse teste passasse, pois estou indo além de qualquer duração máxima declarada do ciclo de gravação. O teste tem como objetivo provar a eficácia do nivelamento do desgaste , não ignorá-lo. O fato de eu poder escrever 2 milhões de vezes no mesmo local aparente indica que o nivelamento de desgaste está em vigor.
precisa
WRT # 2, é claro que qualidade e tecnologia diferenciarão uma placa da outra. O que quero dizer é que um cartão Sandisk barato ainda durará muito mais do que alguém realmente precisa, se a quantidade de dados gravados por dia for relativamente pequena.
Goldilocks
@goldilocks - OK, OK, não me fale sobre isso. 8-), então o que você está dizendo é que se eu escrever uma quantidade suficientemente grande de dados para eliminar efetivamente o nivelamento de desgaste da equação e executar badblocks nela, será suficiente para mostrar a eficácia do nivelamento de desgaste?
slm
1
@goldilocks - acabei de abrir a caixa da pandora?
slm
1
(Por exemplo: se você clona um cartão SD gravando uma imagem e não pode / não pode fstrimposteriormente, 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).
Jason C
6

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:

  • Você não está lendo na mesma área em que está escrevendo, seu teste de leitura efetivamente não faz nada (a menos que o controlador tenha lido a correção de perturbações, nesse caso, pode ocasionalmente mover a página que está sendo lida para outro lugar, mas isso ainda acontece não afeta seu teste).
  • Você assume (e é provável, mas não é garantido) que uma leitura / gravação em um bloco defeituoso é detectada e relatada pelo controlador - você deseja gravar dados, lê-los novamente e compará-los para uma verificação garantida.

No entanto, esses são indiscutivelmente pedantes. Mais sério é:

  • Você não pode usar badblockspara 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 complicado pelo seu teste, sem levar em consideração os comandos TRIM anteriores, o estado livre / usado da unidade durante o teste e o espaço reservado.

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:

dd if=/dev/urandom bs=512k of=/dev/sdb conv=fsync oflag=sync

Se você é do tipo barra de progresso:

pv -pterb -s <device_size> /dev/urandom | dd bs=512k of=/dev/sdb conv=fsync oflag=sync

Editar: Para cartões com blocos de apagamento de 4 MB, tente isso para uma gravação mais rápida:

dd if=/dev/urandom bs=4M of=/dev/sdb conv=fsync oflag=direct,sync iflag=fullblock

Em seguida, você pode escrever um programa de teste de ciclo da seguinte forma, usando O_DIRECTe O_SYNC(e possivelmente paranóico, uso redundante de fsync()) 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:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <cstdlib>
#include <cstdio>
#include <cstring>

using namespace std;

static const int BLOCK_SIZE = 512;
static const int ALIGNMENT = 512;
static const int OFFSET = 1024 * ALIGNMENT; // 1024 is arbitrary


int main (int argc, char **argv) {

    if (argc != 2) {
        fprintf(stderr, "usage: %s device\n", argv[0]);
        return 1;
    }

    int d = open(argv[1], O_RDWR | O_DIRECT | O_SYNC);
    if (d == -1) {
        perror(argv[1]);
        return 1;
    }

    char *block[2], *buffer;
    int index = 0, count = -1;

    // buffers must be aligned for O_DIRECT.
    posix_memalign((void **)&(block[0]), ALIGNMENT, BLOCK_SIZE);
    posix_memalign((void **)&(block[1]), ALIGNMENT, BLOCK_SIZE);
    posix_memalign((void **)&buffer, ALIGNMENT, BLOCK_SIZE);

    // different contents in each buffer
    memset(block[0], 0x55, BLOCK_SIZE);
    memset(block[1], 0xAA, BLOCK_SIZE);

    while (true) {

        // alternate buffers
        index = 1 - index;

        if (!((++ count) % 100)) {
            printf("%i\n", count);
            fflush(stdout);
        }

        // write -> sync -> read back -> compare
        if (lseek(d, OFFSET, SEEK_SET) == (off_t)-1)
            perror("lseek(w)");
        else if (write(d, block[index], BLOCK_SIZE) != BLOCK_SIZE)
            perror("write");
        else if (fsync(d))
            perror("fsync");
        else if (lseek(d, OFFSET, SEEK_SET) == (off_t)-1)
            perror("lseek(r)");
        else if (read(d, buffer, BLOCK_SIZE) != BLOCK_SIZE)
            perror("read");
        else if (memcmp(block[index], buffer, BLOCK_SIZE))
            fprintf(stderr, "memcmp: test failed\n");
        else
            continue;

        printf("failed after %i successful cycles.\n", count);
        break;

    }

}

Observe que O_DIRECT, para , os buffers devem estar adequadamente alinhados. Os limites de 512 bytes são geralmente suficientes. Você pode compilar com:

g++ -O0 test.cpp -o test

Adicione -D_POSIX_C_SOURCE=200112Lse necessário.

Depois de encher o dispositivo completamente como acima, deixe-o funcionar durante a noite:

./test /dev/sdb

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 badblockse 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 fsyncvs fdatasyncnão faz diferença para as gravações do dispositivo de bloco que você está fazendo, para os fins deste teste. Seus open()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".

Jason C
fonte
Eu adicionei um comentário sobre bytes x páginas.
Jason C #
O PNY parece indestrutível. No entanto, após ~ 8,1 milhões de iterações (mais de 8 horas) em um SanDisk de 8 GB MicroSD novinho em folha, seguido de um ciclo de energia, a taxa máxima de gravação (originalmente de 4 MB / s) caiu permanentemente para ~ 410 kB / s e ddfalha 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.
Jason C
A terceira tentativa ddnesse 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%.
Jason C
5

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:

    1. 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.

    2. 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:

    A chamada é bloqueada até o dispositivo relatar que a transferência foi concluída

    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).

peterph
fonte
+1 Para destacar a possibilidade de armazenamento em cache e o significado do bloco de apagamento. Mas ...
goldilocks
"testar o início do cartão pode ser tendencioso" Lembre-se, por causa do nivelamento de desgaste (que deve estar em jogo - excedi qualquer número razoável de ciclos de gravação neste momento) - este é apenas aparentemente o primeiro bloco. Ou seja, é o primeiro bloco virtual, não o primeiro bloco físico .
Goldilocks
"fdatasync () realmente não garante que os dados sejam gravados no meio físico" IMO, o dispositivo que relata que a transferência foi concluída indica que a gravação deve ter ocorrido se o dispositivo também passar nos testes de leitura e gravação (não foi falhou um ainda). O armazenamento em cache pode complicar isso, mas se usarmos um pedaço razoavelmente grande para contornar isso, simplesmente não será possível haver "gravações falsas" quando o dispositivo tiver relatado êxito. Seria inútil se fizesse isso.
Goldilocks
1
@goldilocks não, a leitura dos dados do dispositivo não garante nada. É razoável para esperar os dados para estar no meio físico, e provavelmente será, na maioria dos casos, mas não é garantido - pelo menos a menos que você ir além do tamanho do cache.
Peterph
1
@goldilocks peterph traz outra coisa que eu queria salientar; o readteste é 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.
Jason C
2

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 badblocksapropriado usar a configuração padrão. Em vez disso, fiz desta maneira:

badblocks -v -w -b 524288 -c 8

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 diffo 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 ...

;);)

Cachinhos Dourados
fonte
Eu não acho que sua matemática está certa. Uma placa Classe 2 possui taxa de transferência sustentada de 2 MB / s, o que significa que você colocará 20 TB em aproximadamente 4 meses. Claro, você mencionou que tem um cartão não classificado, mas realmente parece ter ordens de magnitude diferentes (como indicou Terdon em terdon unix.stackexchange.com/questions/84902/… ). Caso contrário, concordo plenamente com o slm.
Peterph
Acredito que podemos ter certeza razoável de que o cache tem um impacto mínimo, se houver, após uma sincronização da mídia projetada para ser removida com frequência e também é alimentada por barramento. Considere que esses dispositivos foram projetados para serem "ejetados" e removidos com segurança e que uma sincronização é a última coisa que um sistema operacional pode fazer com um dispositivo que não seja cortar a energia (se possível). É razoável supor que, por exemplo, uma unidade USB ou cartão SD seja gravada fisicamente após a sincronização ou, no mínimo, comprometida em fazer a gravação em um período extremamente curto após o desligamento.
Jason C
Além disso, btw, 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.
Jason C
Mais um comentário, mais um FYI: em um SanDisk 8GB MicroSD, para consumidor, a unidade de alocação (ou seja, tamanho da página) é de 4 MB, conforme relatado pelo controlador; o que significa que 16 MB nesse cartão tem 4 páginas (5 se não estiver alinhado). Você pode acelerar esse teste escrevendo 512 bytes com compensações de 4 MB em vez de alimentar 16 MB no cartão. Você não está fazendo uma distinção entre bytes e número de páginas, mas deveria estar - no seu exemplo, se estiver em um cartão SanDisk de 8 GB, "16 MB" coloca o mesmo desgaste no cartão que "2 KB". É altamente enganador fazer referência a bytes em vez de páginas.
Jason C
Após ~ 8,1 milhões de iterações (mais de 8 horas) no programa de teste que escrevi acima, seguido de um ciclo de energia em um SanDisk de 8 GB MicroSD novinho em folha, a velocidade de gravação é permanentemente limitada a cerca de 450 kB / s e ddnão conseguiu gravar os 250 MB marca. Na terceira ddtentativa, 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%.
Jason C