Test de résistance des cartes SD avec Linux

19

J'ai eu un petit débat avec quelqu'un hier concernant la logique et / ou la véracité de ma réponse ici , vis., Que la journalisation et la maintenance des métadonnées fs sur une carte SD de taille décente (GB +) ne pourraient jamais être suffisamment importantes pour porter la carte dans un délai raisonnable (années et années). L'essentiel du contre-argument semblait être que je dois me tromper car il y a tellement d'histoires en ligne de personnes utilisant des cartes SD.

Étant donné que j'ai des appareils avec des cartes SD contenant des systèmes de fichiers racine rw qui sont laissés en place 24 heures sur 24, 7 jours sur 7, j'avais testé le local avant à ma propre satisfaction. J'ai légèrement modifié ce test, je l'ai répété (en utilisant la même carte, en fait) et je le présente ici. Les deux questions centrales que j'ai sont:

  1. La méthode que j'ai utilisée pour tenter de détruire la carte est-elle viable, en gardant à l'esprit qu'elle est destinée à reproduire les effets d'une réécriture continue de petites quantités de données?
  2. La méthode que j'ai utilisée pour vérifier que la carte était toujours correcte est-elle viable?

Je pose la question ici plutôt que SO ou SuperUser car une objection à la première partie devrait probablement affirmer que mon test n'a pas vraiment écrit sur la carte comme je suis sûr qu'il le fait, et affirmer que cela nécessiterait une certaine connaissance particulière de linux.

[Il se peut également que les cartes SD utilisent une sorte de tampon ou de cache intelligent, de sorte que les écritures répétées au même endroit soient mises en mémoire tampon / mises en cache dans un endroit moins sujet à l'usure. Je n'ai trouvé aucune indication de cela nulle part, mais je pose la question à ce sujet sur SU]

L'idée derrière le test est d'écrire dans le même petit bloc sur la carte des millions de fois. C'est bien au-delà de toute affirmation du nombre de cycles d'écriture que ces appareils peuvent supporter, mais en supposant que le nivellement de l'usure est efficace, si la carte est d'une taille décente, des millions de telles écritures ne devraient toujours pas avoir beaucoup d'importance, comme le ferait le "même bloc". pas littéralement le même bloc physique. Pour ce faire, je devais m'assurer que chaque écriture était vraiment purgée sur le matériel et au même endroit apparent .

Pour le vidage sur le matériel, je me suis appuyé sur l'appel à la bibliothèque 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;
}                                 

J'ai exécuté cela pendant environ 8 heures, jusqu'à ce que j'aie accumulé plus de 2 millions d'écritures au début de la /dev/sdb1partition. 1 J'aurais pu facilement utiliser /dev/sdb(le périphérique brut et non la partition) mais je ne vois pas quelle différence cela ferait.

J'ai ensuite vérifié la carte en essayant de créer et de monter un système de fichiers /dev/sdb1. Cela a fonctionné, indiquant que le bloc spécifique sur lequel j'avais écrit toute la nuit était faisable. Cependant, cela ne signifie pas que certaines régions de la carte n'ont pas été usées et déplacées par le nivellement de l'usure, mais laissées accessibles.

Pour tester cela, j'ai utilisé badblocks -v -wsur la partition. Il s'agit d'un test de lecture-écriture destructif , mais le nivellement par l'usure ou non, il devrait être une forte indication de la faisabilité de la carte car elle doit toujours fournir un espace pour chaque écriture continue. En d'autres termes, c'est l'équivalent littéral de remplir complètement la carte, puis de vérifier que tout cela allait bien. Plusieurs fois, car j'ai laissé les badblocks fonctionner à travers quelques modèles.

[Contra les commentaires de Jason C ci-dessous, il n'y a rien de mal ou de faux à utiliser les badblocks de cette façon. Bien qu'il ne soit pas utile d'identifier réellement les blocs défectueux en raison de la nature des cartes SD, il convient parfaitement pour effectuer des tests de lecture-écriture destructifs d'une taille arbitraire à l'aide des commutateurs -bet -c, qui est le test révisé (voir ma propre réponse ). Aucune quantité de magie ou de mise en cache par le contrôleur de la carte ne peut tromper un test par lequel plusieurs mégaoctets de données peuvent être écrits sur le matériel et relus correctement. Les autres commentaires de Jason semblent basés sur une mauvaise lecture - l'OMI est intentionnelle , c'est pourquoi je n'ai pas pris la peine de discuter. Avec cette tête haute, je laisse au lecteur le soin de décider ce qui a du sens et ce qui ne l'est pas .]

1 La carte était une ancienne carte Sandisk de 4 Go (elle n'a pas de numéro de "classe") que j'ai à peine utilisée. Encore une fois, gardez à l'esprit qu'il ne s'agit pas de 2 millions d'écritures au même endroit physique; en raison de la mise à niveau d'usure, le "premier bloc" aura été constamment déplacé par le contrôleur pendant le test pour, comme le terme l'indique, niveler l'usure.

boucle d'or
la source
Il s'agit d'un test peu fiable pour les raisons décrites ci-dessous. De plus, vous ne pouvez pas utiliser badblockspour afficher les échecs de page sur un lecteur flash (et prétendre que c'est très trompeur). Celles-ci sont gérées par le contrôleur et mappées pour réserver de l'espace lorsqu'elles sont détectées. La disposition physique des données sur le lecteur n'est pas la même que la disposition physique que vous voyez lorsque vous effectuez des E / S, c'est ainsi que le niveau d'usure maintient sa transparence. Rien de tout cela n'est visible pour vous lors des E / S. Tout au plus, si le lecteur prend en charge SMART, vous pouvez obtenir des informations sur les pannes et l'espace réservé restant sur le contrôleur.
Jason C
Quant à /dev/sdb1vs, /dev/sdbcela ne fait aucune différence pour votre programme, mais ce qui fait la différence (comme décrit ci-dessous), c'est que l'état des blocs inutilisés sur votre appareil est inconnu et non pris en compte dans votre test, et à moins que vous ne remplissiez tout l'appareil (par exemple /dev/sdb) avec les données en premier lieu, la quantité de nivellement d'usure de l'espace avec laquelle travailler doit être une variable majeure. Ainsi, alors que le périphérique par rapport à la partition n'est pas pertinent pour votre test, cela est principalement la conséquence d'un test défectueux, car après avoir correctement rempli le périphérique avec des données, la partition par partition ne serait pas une option disponible (sauf si vous avez formaté après).
Jason C
Encore un autre point qui rend votre test irréaliste, c'est qu'une page peut (et le fait généralement) échouer mais laisser la carte SD 100% utilisable par la suite. Dans le cas où une défaillance est détectée et masquée par le contrôleur mais que les données ne peuvent pas être lues, les données du système de fichiers peuvent devenir corrompues lorsque le contrôleur tente de copier le bloc.
Jason C
Je vous dis quoi - décrivez-moi en termes spécifiques un test reproductible qui porte une carte SD, puis je vous prendrai au sérieux. Les «déclarations d'autorité» irréprochables et les anecdotes personnelles ne sont que cela. Argumentum ab auctoritate
goldilocks
1
Je ne connais pas cette carte en particulier, mais la plupart d'entre eux sont au moins déjà un peu morts de toute façon. Ces gars ont piraté le microcontrôleur sur au moins une marque de carte SD: bunniestudios.com/blog/?p=3554 L'heure de conversation qu'ils ont faite sur le sujet était plutôt bonne.
mikeserv

Réponses:

11

Je pense que le test de stress d'une carte SD est en général problématique étant donné 2 choses:

  1. nivellement de l'usure Il n'y a aucune garantie qu'une écriture sur l'autre exerce réellement les mêmes emplacements physiques sur le SD. N'oubliez pas que la plupart des systèmes SD en place prennent activement un bloc tel que nous le connaissons et déplacent l'emplacement physique qui le recule en fonction de «l'usure» perçue à laquelle chaque emplacement a été soumis.

  2. différentes technologies (MLC vs SLC) L'autre problème que je vois avec cela est la différence de technologies. Types de SSD SLC Je m'attendrais à avoir une durée de vie beaucoup plus longue que la variété MLC. De plus, il y a des tolérances beaucoup plus strictes sur MLC que vous n'avez tout simplement pas à traiter avec les SLC, ou du moins ils sont beaucoup plus tolérants à l'échec de cette manière.

    • MLC - Cellule à plusieurs niveaux
    • SLC - Cellule à niveau unique

Le problème avec MLC est qu'une cellule donnée peut stocker plusieurs valeurs, les bits sont essentiellement empilés en utilisant une tension, plutôt que d'être simplement un + 5V ou 0V physique, par exemple, donc cela peut conduire à un potentiel de taux de défaillance beaucoup plus élevé que leur SLC équivalent.

Espérance de vie

J'ai trouvé ce lien qui discute un peu de la durée du matériel. Il s'intitule: Connaissez vos SSD - SLC vs MLC .

SLC

Les ssds SLC peuvent être calculés, pour la plupart, pour vivre entre 49 ans et 149 ans, en moyenne, selon les meilleures estimations. Les tests Memoright peuvent valider le SSD de 128 Go ayant une durée de vie en endurance en écriture supérieure à 200 ans avec une écriture moyenne de 100 Go par jour.

MLC

C'est là que le design mlc échoue. Aucun n'a encore été libéré. Personne n'a vraiment examiné quel type d'espérance de vie est assuré avec le mlc, sauf qu'il sera considérablement plus bas. J'ai reçu plusieurs convictions différentes qui s'étalent en moyenne sur une durée de vie de 10 à 1 en faveur de la conception slc. Une estimation prudente est que la plupart des estimations de la durée de vie se situeront entre 7 et 10 ans, en fonction de l'avancement des «algorithmes de nivellement d'usure» au sein des contrôleurs de chaque fabricant.

Comparaisons

Pour établir une comparaison au moyen de cycles d'écriture, un slc aurait une durée de vie de 100 000 cycles d'écriture complets par rapport au mlc qui a une durée de vie de 10 000 cycles d'écriture. Cela pourrait augmenter considérablement en fonction de la conception du «nivellement d'usure» utilisé.

slm
la source
1
Nivellement d'usure WRT "Il n'y a aucune garantie qu'une écriture sur l'autre exerce réellement les mêmes emplacements physiques sur le SD" - c'est supposé dans la question slm! Très explicitement, je pense ... Sans nivellement d'usure, je ne m'attendrais jamais à ce que ce test passe, car je vais bien au-delà de la durée de vie maximale du cycle d'écriture. Le test vise à prouver l'efficacité du nivellement de l'usure , et non à l'ignorer. Le fait que je puisse écrire 2 millions de fois au même endroit apparent indique que le nivellement de l'usure est en vigueur.
goldilocks
WRT # 2, la qualité et la technologie différencieront bien sûr une carte d'une autre. Ce que je veux dire, c'est qu'une carte Sandisk bon marché ordinaire durera encore bien plus longtemps que quiconque en a vraiment besoin si la quantité de données écrites par jour est relativement faible.
goldilocks
@goldilocks - OK, OK, ne me bat pas à ce sujet. 8-), donc ce que vous dites est que si j'écris une quantité de données suffisamment importante pour éliminer efficacement le nivellement d'usure de l'équation et y exécuter des blocs défectueux, est-ce suffisant pour montrer l'efficacité du nivellement d'usure?
slm
1
@goldilocks - est-ce que je viens d'ouvrir la boîte de pandora?
slm
1
(Par exemple: si vous clonez une carte SD en y écrivant une image et que vous ne pouvez pas / ne pouvez pas fstrimpar la suite, vous avez entièrement désactivé la mise à niveau dynamique de l'usure [vous auriez du mal à trouver une carte SD de qualité grand public avec une mise à niveau statique] par marquant chaque page comme utilisée.)
Jason C
6

Il y a un certain nombre de problèmes avec votre test, certains flous, d'autres non. Cela dépend aussi de votre objectif. Deux types subtils de problèmes flous sont:

  • Vous ne lisez pas à partir de la même zone dans laquelle vous écrivez, votre test de lecture ne fait donc rien (à moins que le contrôleur n'ait corrigé la perturbation de lecture, auquel cas il peut occasionnellement déplacer la page lue ailleurs, mais cela continue n'affecte pas votre test).
  • Vous supposez (et il est probable, mais non garanti) qu'une lecture / écriture sur un bloc défectueux est détectée et signalée par le contrôleur - vous voudriez écrire des données, les relire et les comparer pour une vérification garantie.

Cependant, ceux-ci sont sans doute pédantes. Plus grave est:

  • Vous ne pouvez pas utiliser badblockspour afficher les pages ayant échoué sur la mémoire flash; toutes les détections d'échecs et les mappages de pages ultérieurs sont effectués par le contrôleur et sont transparents pour le système d'exploitation. Vous pouvez obtenir des informations de SMART si le lecteur le prend en charge (je ne connais aucune carte SD qui le prend en charge, peut-être qu'il existe des clés USB haut de gamme qui le font).
  • Nivellement d'usure, compliqué par votre test ne tenant pas compte des commandes TRIM antérieures, de l'état libre / utilisé du lecteur pendant le test et de l'espace réservé.

Nivellement d'usure: Le principal problème est que le nivellement d'usure est une variable majeure dans votre test. Cela se produit sur le contrôleur (généralement), et dans tous les cas, il est transparent, même direct, de rechercher + lire / écrire. Dans votre exemple, vous ne connaissez pas réellement l'état de nivellement de l'usure (en particulier, des commandes TRIM ont-elles été émises récemment pour libérer des blocs?) ...

Pour le nivellement d'usure dynamique (présent dans pratiquement tous les périphériques de stockage grand public) sur votre appareil, il peut alors être dans n'importe quel état: à une extrémité, aucune des pages n'est marquée comme libre, et donc les seules pages que le contrôleur doit travailler avec sont ceux dans l'espace réservé (le cas échéant). Notez que s'il est un espace réservé sur l'appareil, il sera avoir à l' échec tout à fait avant de commencer à se garanti échoue sur la page écrit ( en supposant qu'il n'y a pas d' autres pages marquées comme libre restant). À l'autre extrême, chaque page est marquée comme libre, auquel cas vous devez théoriquement faire échouer chaque page de l'appareil avant de commencer à voir les échecs d'écriture.

Pour le nivellement de l'usure statique (que les SSD ont tendance à avoir, les cartes SD ont tendance à ne pas avoir et les clés USB varient): Il n'y a vraiment aucun moyen de le contourner, à part écrire plusieurs fois sur chaque page de l'appareil.

... En d'autres termes, il y a des détails de nivellement d'usure que vous n'avez aucun moyen de connaître et certainement aucun moyen de contrôler - en particulier si le nivellement d'usure dynamique est utilisé, si le nivellement d'usure statique est utilisé ou non, et quantité d'espace réservé sur l'appareil pour le nivellement de l'usure (qui n'est pas visible au-delà du contrôleur [ou du pilote dans certains cas, comme l'ancien DiskOnChip de M-Systems]).

SLC / MLC: Comme pour SLC vs MLC, cela a un impact très direct sur les limites que vous attendez, mais la procédure générale de nivellement de l'usure et la procédure de test sont les mêmes pour les deux. De nombreux fournisseurs ne publient pas si leurs appareils sont SLC ou MLC pour leurs produits de consommation moins chers, bien que tout lecteur flash qui revendique une limite de cycle de 100k + par page soit probablement SLC (le compromis simplifié est SLC = endurance, MLC = densité).

Caching: Quant à la mise en cache, c'est un peu incertain. Au niveau du système d'exploitation, dans le cas général, bien entendu, fsync / fdatasync ne garantit pas que les données sont réellement écrites. Cependant, je pense qu'il est prudent de supposer que c'est le cas (ou du moins le contrôleur s'est engagé à le faire, c'est-à-dire que l'écriture ne sera pas avalée dans le cache) dans ce cas, car les lecteurs amovibles sont généralement conçus pour le modèle d'utilisation courant de "éjecter" (démonter> synchroniser) puis retirer (coupure de courant). Bien que nous ne sachions pas avec certitude, une supposition éclairée dit qu'il est sûr de supposer que la synchronisation garantit que l'écriture aura absolument lieu, en particulier en écriture -> sync -> relecture (si ce n'était pas le cas, les lecteurs ne seraient pas fiables). après éjection). Il n'y a pas d'autre commande que 'sync' qui puisse être émise lors de l'éjection.

Au niveau du contrôleur, tout est possible, mais l'hypothèse ci-dessus inclut également l'hypothèse selon laquelle le contrôleur au moins ne fait rien de «suffisamment compliqué» pour risquer de perdre des données après une synchronisation. Il est concevable que le contrôleur puisse, disons, tamponner et grouper les écritures, ou ne pas écrire de données si les mêmes données sont en cours de réécriture (dans une mesure limitée). Dans le programme ci-dessous, nous alternons entre deux blocs de données différents et effectuons une synchronisation avant la relecture spécifiquement pour vaincre un mécanisme de mise en cache de contrôleur raisonnable. Bien sûr, il n'y a aucune garantie et aucun moyen de savoir, mais nous pouvons faire des hypothèses raisonnables sur la base d'une utilisation normale de ces appareils et de mécanismes de mise en cache sains / communs.

Essai:

Malheureusement, la vérité est que, sauf si vous savez que l'appareil n'a pas d'espace réservé et ne fait pas de mise à niveau statique, il n'y a aucun moyen de tester définitivement la limite de cycle d'une page spécifique. Cependant, le plus proche que vous pouvez obtenir est le suivant (supposons qu'il n'y ait pas de mise à niveau statique):

La première chose que vous devez faire est de remplir la carte entière de données. C'est important, et c'est la variable principale qui a été laissée dans votre test d'origine. Cela marque autant de blocs que possible, en dehors de tout espace réservé (auquel vous n'avez aucun moyen d'accéder). Notez que nous travaillons avec un appareil entier (sur lequel cela détruira toutes les données), car travailler avec une seule partition n'affecte qu'une zone spécifique de l'appareil:

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

Si vous êtes du type barre de progression:

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

Modifier: pour les cartes avec des blocs d'effacement de 4 Mo, essayez ceci pour une écriture plus rapide:

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

Ensuite, vous pouvez écrire un programme de test de cycle comme suit, en utilisant O_DIRECTet O_SYNC(et éventuellement paranoïaque, redondant fsync()) pour réduire autant que possible la mise en mémoire tampon et la mise en cache du système d'exploitation de l'image et, théoriquement, écrire directement sur le contrôleur et attendez qu'il signale que l'opération est terminée:

#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;

    }

}

Notez que pour O_DIRECT, les tampons doivent être convenablement alignés. Des limites de 512 octets sont généralement suffisantes. Vous pouvez compiler avec:

g++ -O0 test.cpp -o test

Ajoutez -D_POSIX_C_SOURCE=200112Lsi nécessaire.

Ensuite, après avoir entièrement rempli l'appareil comme ci-dessus, laissez-le fonctionner toute la nuit:

./test /dev/sdb

512 octets, les écritures alignées sont très bien, ce qui vous donnera une page entière effacée et réécrite. Vous pouvez accélérer considérablement le test en utilisant une taille de bloc plus grande, mais il devient alors compliqué d'arriver à des résultats concrets.

Je teste actuellement une clé USB PNY de 4 Go plutôt battue que j'ai trouvée hier sur le trottoir (il semblait être ce qui restait d'une http://www3.pny.com/4GB-Micro-Sleek-Attach-- -Purple-P2990C418.aspx ).

Le programme ci-dessus est essentiellement une version limitée de badblockset vous ne verrez pas d'échecs tant que tout l'espace réservé n'aura pas été épuisé. Par conséquent, l'attente (avec 1 page écrite par itération) est que la procédure ci-dessus, en moyenne, échoue dans les itérations réservé_page_count * write_cycle_limit (encore une fois, le niveau d'usure est une variable majeure). Il est dommage que les clés USB et les cartes SD ne prennent généralement pas en charge SMART, qui a la capacité de signaler la taille de l'espace réservé.

Soit dit en passant, fsyncvs fdatasyncne fait aucune différence pour les écritures de périphérique de bloc que vous effectuez, aux fins de ce test. Vos open()modes sont importants.

Si vous êtes curieux de connaître les détails techniques; voici tout ce que vous pourriez vouloir savoir (et plus) sur le fonctionnement interne des cartes SD: https://www.sdcard.org/downloads/pls/simplified_specs/part1_410.pdf

Edit: Bytes vs Pages: Dans le cadre de ces types de tests, il est important de penser les choses en termes de pages, pas d'octets. Il peut être très trompeur de faire le contraire. Par exemple, sur une carte SD SanDisk 8 Go, la taille de la page en fonction du contrôleur (accessible via /sys/classes/mmc_host/mmc?/mmc?:????/preferred_erase_size) est de 4 Mo complets. Écriture de 16 Mo (aligné sur les limites de 4 Mo), puis effacement / écriture de 4 pages. Cependant, l'écriture de quatre octets simples chacun à des décalages de 4 Mo les uns des autres efface / écrit également 4 pages.

C'est inexact, alors de dire "J'ai testé avec des écritures de 16 Mo", car c'est la même quantité d'usure que "J'ai testé avec des écritures de 4 octets". Plus précisément, "J'ai testé avec des écritures de 4 pages".

Jason C
la source
J'ai ajouté un commentaire concernant les octets par rapport aux pages.
Jason C
Le PNY apparaît indestructible. Cependant, après ~ 8,1 mil d'itérations (sur environ 8 heures) sur un tout nouveau SanDisk 8 Go MicroSD, suivi d'un cycle d'alimentation, la vitesse d'écriture maximale (à l'origine 4 Mo / s) est définitivement tombée à ~ 410 Ko / sec, et ddéchoue après avoir écrit 250 Mo . Les dommages ne sont apparus qu'après le cycle d'alimentation. La clé USB PNY reste inchangée après ~ 30mil itérations. J'ai modifié le programme ci-dessus (non reflété dans le code ci-dessus, cependant) pour écrire dans des emplacements aléatoires alignés à 16 Ko à chaque fois au lieu du même, mais je l'ai fait après environ 4 mil iters sur SD. Réessayera avec une nouvelle carte.
Jason C
La troisième tentative ddsur cette carte a dépassé la barre des 250 Mo et les performances d'écriture ont de nouveau augmenté jusqu'à 4 Mo / s dans les zones après ce point. Je m'attends à ce que les performances soient imprévisibles, car les blocs continuent d'être mélangés. Je ne dirais pas que la carte est détruite, mais ce n'est certainement pas à 100%.
Jason C
5

Ajoutons simplement quelques points à la réponse de slm - notez que ceux-ci sont plus en place pour les SSD que pour les cartes SD "stupides", car les SSD jouent des tours beaucoup plus sales avec vos données (par exemple la déduplication):

  • vous écrivez 64 Ko au début de l'appareil - cela lui-même a deux problèmes:

    1. les cellules flash ont généralement des blocs de taille effaçables à partir de 16 Ko (plus probablement dans la plage de 128 à 512 Ko, cependant). Ce qui signifie qu'il a besoin d'un cache d'au moins cette taille. Par conséquent, écrire 64 Ko ne me semble pas suffisant.

    2. pour les solutions bas de gamme (lire "non-entreprise") (et je m'attendrais à ce que cela soit encore plus pour les cartes SD / CF que pour les SSD), les fabricants peuvent choisir de rendre le début de l'appareil plus résistant à l'usure que le reste depuis le les structures importantes - la table de partition et FAT sur la partition unique de l'appareil (la plupart des cartes mémoire utilisent cette configuration) - y sont situées. Ainsi, tester le début de la carte peut être biaisé.

  • fdatasync() ne garantit pas vraiment que les données soient écrites sur le support physique (bien qu'il fasse probablement de son mieux ce qui est sous le contrôle du système d'exploitation) - voir la page de manuel:

    L'appel se bloque jusqu'à ce que l'appareil signale que le transfert est terminé

    Je ne serais pas trop surpris s'il s'avérait qu'il y avait un petit condensateur, capable de fournir de l'énergie pour écrire des données en cache dans la mémoire flash en cas de perte d'alimentation externe.

    En tout cas, dans l'hypothèse d'un cache présent sur la carte (voir ma réponse à votre question sur SU ), écrire 64Ko et synchroniser (avec fdatasync()) ne semble pas assez convaincant à cet effet. Même sans aucune "sauvegarde de puissance", le micrologiciel peut toujours le jouer de manière dangereuse et garder les données non écrites pendant un peu plus longtemps que prévu (car dans des cas d'utilisation typiques, cela ne devrait pas créer de problème).

  • vous voudrez peut-être lire les données avant d'écrire un nouveau bloc et de le comparer, juste pour vous assurer qu'il fonctionne vraiment (et utilisez un tampon effacé pour la lecture, si vous êtes assez paranoïaque).

peterph
la source
+1 Pour mettre en évidence la possibilité de mise en cache et la signification du bloc d'effacement à cet égard. Mais ...
goldilocks
"tester le début de la carte peut être biaisé" Rappelez-vous, en raison du niveau d'usure (qui doit être en jeu - j'ai dépassé un nombre raisonnable de cycles d'écriture à ce stade) - ce n'est apparemment que le premier bloc. C'est à dire, c'est le premier bloc virtuel, pas le premier bloc physique .
goldilocks
"fdatasync () ne garantit pas vraiment que les données soient écrites sur le support physique" IMO, le périphérique signalant que le transfert est terminé indique que l'écriture doit avoir eu lieu si le périphérique réussit également les tests de lecture-écriture (il n'a pas échoué encore). La mise en cache peut compliquer cela, mais si nous utilisons un morceau raisonnablement grand pour contourner cela, il n'est tout simplement pas possible qu'il y ait de "fausses écritures" lorsque l'appareil a signalé le succès. Ce serait inutile s'il le faisait.
goldilocks
1
@goldilocks no, la lecture des données de l'appareil ne garantit rien. Il est raisonnable de s'attendre à ce que les données soient sur le support physique, et ce le sera probablement dans la plupart des cas, mais ce n'est pas garanti - du moins à moins que vous ne dépassiez la taille du cache.
peterph
1
@goldilocks peterph soulève une autre chose que je voulais souligner; le readdans votre test est inutile, il n'ajoute aucune information et n'est pas pertinent pour un test de cycle d'écriture. Pour un vrai test, vous voudrez relire le bloc que vous venez d'écrire et le valider, à moins que vous ne soyez certain que le contrôleur peut détecter et signaler tous les modes de défaillance.
Jason C
2

La réponse de Peterph m'a fait réfléchir davantage à la question de la mise en cache possible. Après avoir fouillé, je ne peux toujours pas dire avec certitude si certaines, certaines ou toutes les cartes SD font cela, mais je pense que c'est possible.

Cependant, je ne pense pas que la mise en cache impliquerait des données plus grandes que le bloc d'effacement. Pour être vraiment sûr, j'ai répété le test en utilisant un bloc de 16 Mo au lieu de 64 Ko. C'est 1 / 250e du volume total de la carte de 4 Go. Cela a pris environ 8 heures pour le faire 10 000 fois. Si le nivellement de l'usure fait de son mieux pour répartir la charge, cela signifie que chaque bloc physique aurait été utilisé 40 fois.

Ce n'est pas grand-chose, mais le point de départ du test était de démontrer l'efficacité du nivellement de l'usure en montrant que je ne pouvais pas facilement endommager la carte par des écritures répétées de petites quantités de données au même endroit (apparent). OMI, le précédent test de 64 Ko était probablement réel - mais celui de 16 Mo devait l'être. Le système a vidé les données sur le matériel et le matériel a signalé l'écriture sans erreur. Si c'était une tromperie, la carte ne serait bonne à rien, et elle ne peut pas mettre en cache 16 Mo ailleurs que dans le stockage principal, ce que le test est censé souligner.

Espérons que 10 000 écritures de 16 Mo chacune suffiront à démontrer que même sur une carte de marque de bas de gamme (valeur: 5 $ CDN), l'exécution d'un système de fichiers racine rw 24/7 qui écrit de modestes quantités de données quotidiennement n'usera pas la carte dans un délai raisonnable. 10000 jours, c'est 27 ans ... et la carte est toujours bien ...

Si j'étais payé pour développer des systèmes plus lourds que cela, je voudrais faire au moins quelques tests pour déterminer combien de temps une carte peut durer. Mon intuition est qu'avec un tel modèle, qui a une faible vitesse d'écriture, cela pourrait prendre des semaines, des mois ou des années d'écriture continue à la vitesse maximale (le fait qu'il n'y ait pas beaucoup de tests comparatifs de ce type en ligne parle à la fait que ce serait une affaire très prolongée).

En ce qui concerne la confirmation que la carte est toujours correcte, je ne pense plus que l'utilisation badblocksdans sa configuration par défaut soit appropriée. Au lieu de cela, je l'ai fait de cette façon:

badblocks -v -w -b 524288 -c 8

Ce qui signifie tester en utilisant un bloc de 512 Ko répété 8 fois (= 4 Mo). Puisqu'il s'agit d'un test rw destructif, il serait probablement bon que celui de mon homepun en ce qui concerne la contrainte de l'appareil s'il est utilisé dans une boucle continue.

J'ai également créé un système de fichiers dessus, copié dans un fichier de 2 Go, diffle fichier par rapport à l'original, puis - puisque le fichier était un .iso - l'a monté en tant qu'image et parcouru le système de fichiers à l'intérieur.

La carte est toujours bien. Ce qui est probablement à prévoir, après tout ...

;);)

boucle d'or
la source
Je ne pense pas que vos calculs soient corrects. Une carte de classe 2 a un débit soutenu de 2 Mo / s, ce qui signifie que vous mettrez 20 To en environ 4 mois. Bien sûr, vous avez mentionné que vous avez une carte non classée, mais vous semblez vraiment avoir des ordres de grandeur (comme l'a souligné terdon dans unix.stackexchange.com/questions/84902/… ). Sinon, je suis entièrement d'accord avec slm.
peterph
Je pense que nous pouvons être raisonnablement sûrs que la mise en cache a un impact minimal, voire nul, après une synchronisation pour les supports conçus pour être fréquemment supprimés et également alimentés par bus. Considérez que ces périphériques sont conçus pour être "éjectés" et supprimés de manière fiable, et qu'une synchronisation est la dernière chose absolue qu'un système d'exploitation peut faire à un périphérique autre que de couper sa puissance (si possible). Il est raisonnable de supposer que, par exemple, une clé USB ou une carte SD est soit physiquement écrite après la synchronisation, soit au minimum engagée à effectuer l'écriture dans un délai extrêmement court après la mise hors tension.
Jason C
De plus, btw, badblocksne vous montrera pas les pages ayant échoué sur la mémoire flash. Ce n'est pas le bon outil pour ce travail et vous ne pouvez pas l'utiliser pour trouver des pages en échec sur flash. Lorsque le contrôleur détecte une panne, il marque en interne la page comme mauvaise et la remappe sur une page dans l'espace réservé. Tout cela se produit derrière le contrôleur et n'est pas visible du tout, même dans un vidage de périphérique brut . Vous pouvez obtenir des informations du contrôleur si SMART est pris en charge. L'ordre physique des données sur le périphérique ne correspond pas à l'ordre des octets que vous voyez lorsque vous effectuez des E / S sur le périphérique.
Jason C
Un autre commentaire, plus d'un FYI: sur une carte MicroSD SanDisk 8 Go, de qualité grand public, l'unité d'allocation (c'est-à-dire la taille de la page) est de 4 Mo, comme indiqué par le contrôleur; ce qui signifie que 16 Mo sur cette carte correspondent à 4 pages (5 si elle n'est pas alignée). Vous pouvez accélérer ce test en écrivant 512 octets à des décalages de 4 Mo les uns des autres au lieu de fournir 16 Mo à la carte. Vous ne faites pas de distinction entre les octets et le nombre de pages, mais vous devriez l'être - dans votre exemple, s'il s'agissait d'une carte SanDisk 8 Go, «16 Mo» met la même usure sur la carte que «2 Ko». Il est très trompeur de faire référence à des octets plutôt qu'à des pages.
Jason C
Après environ 8,1 mil d'itérations (plus de 8 heures) dans le programme de test que j'ai écrit ci-dessus, suivi d'un cycle d'alimentation, sur un tout nouveau SanDisk 8 Go MicroSD, la vitesse d'écriture est limitée en permanence à environ 450 Ko / s et ddn'a pas réussi à écrire au-delà des 250 Mo marque. À la troisième ddtentative, il a dépassé 250 Mo et une fois qu'il l'a fait, les performances d'écriture ont de nouveau augmenté dans ces domaines. Je ne dirais pas que la carte est détruite mais elle n'est certainement pas à 100%.
Jason C