Comment puis-je tester la pleine capacité d'une carte SD sous Linux?

17

J'ai acheté une carte SD de 64 Go sur eBay. Cela fonctionne bien lorsque je lui grave une image Arch Linux ARM et que je l'utilise pour démarrer mon Raspberry Pi.

Cependant, lorsque j'essaie de créer une seule partition ext4 dessus pour utiliser toute la capacité de la carte, des erreurs se produisent. mkfs.ext4finit toujours avec bonheur; cependant, la partition ne peut pas être mountéditée, générant toujours une erreur et dmesgaffichant les messages du noyau inclus Cannot find journal. Cela s'est avéré être le cas sur au moins deux plates-formes: Arch Linux ARM et Ubuntu 13.04.

D'un autre côté, je peux créer et monter une partition FAT32 sans erreur (une vérification de la pleine capacité n'a pas été effectuée).

J'ai entendu dire que certains méchants peuvent changer l'interface de la carte SD pour signaler une mauvaise capacité au système d'exploitation (c'est-à-dire que la carte n'est vraiment que de 2 Go mais elle se présente comme 64 Go) afin de vendre la carte à un meilleur prix.

Je sais que des outils comme celui-ci badblocksexistent pour moi de vérifier la carte SD pour les blocs défectueux. Peut badblocksdétecter des problèmes comme celui-ci? Sinon, quelles sont les autres solutions pour tester la carte?

J'aimerais idéalement savoir si j'ai été trompé ou non; si le résultat montre que je viens de recevoir un mauvais article, je peux retourner au vendeur uniquement, plutôt signaler à eBay que quelqu'un a essayé de me tromper.

MISE À JOUR

opérations et messages:

~$ sudo mkfs.ext4 /dev/sde1
mke2fs 1.42.5 (29-Jul-2012)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
4096000 inodes, 16383996 blocks
819199 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
500 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
4096000, 7962624, 11239424

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done   

~$ dmesg | tail
...
[4199.749118]...
~$ sudo mount /dev/sde1 /mnt
mount: wrong fs type, bad option, bad superblock on /dev/sde1,
   missing codepage or helper program, or other error
   In some cases useful info is found in syslog - try
   dmesg | tail  or so

~$ dmesg | tail
...
[ 4199.749118]...
[ 4460.857603] JBD2: no valid journal superblock found
[ 4460.857618] EXT4-fs (sde1): error loading journal

MISE À JOUR

J'ai couru badblocks /dev/sdemais il ne signale aucune erreur. Cela signifie que les causes restantes sont:

  • La voiture SD est bonne mais pour une raison mke2fsou mountune autre, le noyau a un bogue qui cause le problème.

  • J'ai été trompé d'une manière qui badblocksne puisse pas détecter la défaite. C'est plausible parce que je pense que badblocksc'est juste faire un test d'écriture-lecture sur place. Cependant, le tricheur peut relier l'accès aux zones sortantes à un bloc entrant. Dans ce cas, une vérification en lecture-écriture sur place n'est pas en mesure de détecter le problème.

S'il n'y a pas d'application qui puisse faire le bon test, je pense que je peux essayer d'écrire un simple programme C pour le tester.

Earth Engine
la source
L'avez-vous essayé dans un lecteur de carte SDXC USB?
Ignacio Vazquez-Abrams
De plus, des messages apparaissent-ils dans le journal système en même temps que les erreurs?
Ignacio Vazquez-Abrams
J'ai essayé à la fois avec le lecteur de carte natif Raspberry Pi et un lecteur de carte externe pour mon bureau Ubuntu. J'ai dit que cela dmesgmontre les messages du noyau et je suis sûr qu'il apparaît en même temps que les erreurs car je l'ai fait avant et après et les ai comparés. Je n'ai pas vérifié syslogparce que je crois dmesgaffichera les messages.
Earth Engine
Affiche-t-il d'autres messages?
Ignacio Vazquez-Abrams
Le lecteur de carte externe que j'ai utilisé fonctionne pour mes autres cartes, y compris les cartes SDXC. Cependant, cette problématique a une différence: c'est une carte micro SD avec un adaptateur SD.
Earth Engine

Réponses:

26

Si quelqu'un le voit plus tard: quelqu'un a écrit un outil open source appelé "F3" pour tester la capacité des cartes SD et autres supports de ce type. Il peut être trouvé sur l'hompage du projet et dans Github .

Radtoo
la source
En fait c'est LA référence dans ce sujet pour tester les SDCards ...
Philippe Gachoud
6

La tricherie a maintenant été confirmée par les étapes suivantes:

  • Générez un fichier de données aléatoire. (4194304 = 4 × 1024 × 1024 = 4 Mio, taille totale = 40 × 4 Mio = 160 Mio)

    Commander:

    dd if=/dev/urandom of=test.orig bs=4194304 count=40
    40+0 records in
    40+0 records out
    167772160 bytes (168 MB) copied, 11.0518 s, 15.2 MB/s
    
  • Copiez les données sur la carte SD. (2038340 × 4096 = 8153600 Kio = 7962,5 Mio)

    Commander:

    sudo dd if=test.orig of=/dev/sde seek=2038399 bs=4096
    40960+0 records in
    40960+0 records out
    167772160 bytes (168 MB) copied, 41.6087 s, 4.0 MB/s
    
  • Lisez les données de la carte SD.

    Commander:

    sudo dd if=/dev/sde of=test.result skip=2038399 bs=4096 count=40960
    40960+0 records in
    40960+0 records out
    167772160 bytes (168 MB) copied, 14.5498 s, 11.5 MB/s
    
  • Afficher le résultat

    Commander:

    hexdump test.result | less
    ...
    0000ff0 b006 fe69 0823 a635 084a f30a c2db 3f19
    0001000 0000 0000 0000 0000 0000 0000 0000 0000
    *
    1a81000 a8a5 9f9d 6722 7f45 fbde 514c fecd 5145
    
    ...
    

Qu'est-il arrivé? Nous avons observé un écart de zéros. Ceci indique que les données aléatoires n'ont pas été réellement écrites sur la carte. Mais pourquoi les données reviennent-elles après 1a81000? Évidemment, la carte a un cache interne.

Nous pouvons également essayer d'enquêter sur le comportement du cache.

hexdump test.orig | grep ' 0000 0000 '

ne fournit aucun résultat, ce qui signifie que les déchets générés n'ont pas un tel modèle. cependant,

hexdump test.result | grep ' 0000 0000 '
0001000 0000 0000 0000 0000 0000 0000 0000 0000
213b000 0000 0000 0000 0000 0000 0000 0000 0000
407b000 0000 0000 0000 0000 0000 0000 0000 0000
601b000 0000 0000 0000 0000 0000 0000 0000 0000

avoir 4 matchs.

C'est pourquoi il passe le badblockscontrôle. Des tests supplémentaires peuvent montrer que la capacité réelle est de 7962,5 Mo, soit un peu moins de 8 Go.

Je conclus qu'il est très peu probable qu'il s'agisse simplement d'une défaillance matérielle aléatoire, mais plus susceptible d'être une sorte de tricherie (c'est-à-dire de fraude). Je voudrais savoir quelles mesures je peux prendre pour aider d'autres victimes.

Mise à jour 11/05/2019

  • Les gens m'ont demandé comment j'ai trouvé le bon seekparamètre 2038399. J'ai fait beaucoup plus d'expérience que ce que j'ai montré ci-dessus. Fondamentalement, vous devez d'abord deviner. Vous devez deviner la taille appropriée des données et vous devez deviner où se trouvait la corruption des données. Mais vous pouvez toujours utiliser la méthode de la bissection pour vous aider.

  • Dans le commentaire ci-dessous, je pensais que j'étais supposé que la deuxième étape ci-dessus (copier les données sur la carte SD) ne copie qu'un secteur. Mais je n'ai pas fait cette erreur dans mon expérience. Au lieu de cela, le seekdevait montrer qu'à l'étape "afficher le résultat", le décalage 1000se produisait simplement dans le deuxième secteur des données. Si le secteur seekest 2038399, la corruption est au secteur 2038400e.

Earth Engine
la source
(1) D'où viennent les numéros 2038340 et 2038399? (2) Pourquoi utilisez-vous  bs=4194304 count=40 lors de la lecture, /dev/urandom mais   bs=4096 count=40960  lors de l'écriture et de la lecture sur la carte SD? (Ils sont mathématiquement équivalents; 167772160 octets chacun.)
Scott
1) J'ai utilisé bisec tecnique pour calculer le décalage. La procédure bisec étant trop verbeuse pour la réponse, je les mets simplement en évidence sans autre explication. 2) Oui, le calcul est équivalent; mais je ne sais pas si je dois correspondre à la taille de secteur de la carte, qui je crois est 4096.
Earth Engine
Oh, pour le point 2) que j'utilise seek, j'ai donc écrit seulement 1 secteur sur la carte, ce qui économise la quantité de transfert de données. Bien sûr, lors de l'expérimentation, j'ai utilisé un bloc de données plus gros, c'est pourquoi le fichier de données généré est de 160 Mo.
Earth Engine
Votre deuxième commentaire n'a aucun sens. La deuxième commande dans votre réponse - celle qui écrit sur la carte - est sudo dd if=test.orig of=/dev/sde seek=2038399 bs=4096. Et évidemment vous avez raison; il utilise seek. Et, oui, techniquement, ça n'utilise pas count. … (Suite)
Scott
(Suite)… Mais vous dites: «Je n'ai écrit qu'un seul secteur sur la carte, ce qui permet d'économiser le transfert de données.» C'est clairement faux; sans countspécification, ddtransfère la totalité de l'entrée (c'est-à-dire qu'elle transfère jusqu'à EOF ou une erreur). Cette commande transfère donc tout le contenu de test.orig, soit 40960 enregistrements de 4096 octets chacun, pour un total de 167772160 octets (comme je l'ai dit).
Scott
3

Tout d'abord, lisez la réponse F3 de @Radtoo. C'est la bonne façon.

Je l'ai en quelque sorte raté et j'ai essayé à ma façon:

  1. créer un fichier de test de 1 Go: dd if=/dev/urandom bs=1024k count=1024 of=testfile1gb

  2. écrire des copies de ce fichier sur sdcard (64 est la taille de la sdcard en Go): for i in $(seq 1 64); do dd if=testfile1gb bs=1024k of=/media/sdb1/test.$i; done

  3. vérifier md5 des fichiers (tous sauf le dernier, incomplets, doivent correspondre): md5sum testfile1gb /media/sdb1/test.*

domen
la source
Il s'agit d'une approche simple et rapide.
Earth Engine
Cette méthode est bien documentée ici ccollins.wordpress.com/2016/01/18/testing-sd-cards-with-linux
Philippe Gachoud
2

Le moyen le plus simple de tester la pleine capacité d'une carte SD est de la remplir de fichiers, puis de vérifier que les fichiers sont corrects: diff -qr /directory/on/computer /directory/on/SD

Vous pouvez également utiliser des programmes pour écrire des modèles ou des chaînes de hachage dans un fichier, puis vérifier qu'ils sont corrects.

Comme l'a souligné @Earthy Engine , il est important de remplir la carte SD, puis de lire les données, car les approches traditionnelles qui écrivent simplement un petit bloc de données, puis les lisent, sont trompées par de fausses cartes SSD.

Zaz
la source
2

J'ai écrit un petit script qui fait ce qui suit.

- crée un répertoire temporaire sur la carte USB ou SC cible

- crée un fichier de référence généré aléatoirement de 5 Mo avec la somme de contrôle md5sum

-copie le fichier de référence sur la cible et génère une vérification de somme md5 à partir de la cible pour confirmer la réussite de la lecture / écriture

-remplit la cible à sa capacité (100%) ou s'arrête lorsqu'une erreur de somme de contrôle se produit

-une fois que le script s'arrête naturellement, il affiche la taille cible déclarée, les montants utilisés et gratuits.

Avec ce script, j'ai conclu que j'ai été arnaqué par un vendeur ebay qui a passé un microSD de 8 Go pour un 64 Go

#!/bin/bash
#Save file as 'filltext' and remember to set the executable flag to run it
if [ -d "$1" ]; then
 if [ -d "$1/tmp" ]; then
  echo "."
 else
  mkdir $1/tmp
 fi

#Make a tmp file and fill it with 3MB of junk
 TMPTSTR=$(mktemp)      
 base64 </dev/urandom  | head -c 5000000 > $TMPTSTR

 TESTVAL=$(md5sum $TMPTSTR | awk '{ print $1 }')

 while $CHECKEDOK; do

  FL=$( tr -dc A-Za-z0-9 </dev/urandom  | head -c 5).TEST

  cp $TMPTSTR $1/tmp/$FL
  TESTTMP=$(md5sum $1/tmp/$FL | awk '{ print $1 }')
  if [ "$TESTVAL" != "$TESTTMP" ]; then   
   echo "Checksum ERROR"
   echo "Original: $TESTVAL Temp File:$TESTTMP"
   CHECKEDOK=false
   df $1 -Ph
   echo 
   echo 
   echo "Removing test files"
   rm $1/tmp -r
   rm $TMPTSTR
   df $1 -Ph
  else
   #echo -n "$FL..."
   clear
   df $1 -Ph
  fi
 done

else
 echo "Error: Directory $1 does not exists."
 echo "Usage: filltest [PATH]"
 echo
 echo "Try the PATH of a mounted USB dongle or SD card to confirm it's capacity"

fi
Robert Charest
la source
1
Cela donnera peut-être des résultats trompeurs. Étant donné que le système de fichiers du tampon du système d'exploitation écrit, vous testez principalement la mémoire de votre système, pas la carte SD.
Cerin
l'exécution de "hdparm -W 0 / dev / disk" devrait résoudre un problème d'écriture en mémoire tampon.
Michael
1

On peut écrire une séquence de nombres (chaque ligne fait 16 octets) puis vérifier le contenu:

dd if=<(seq -w 0 123456789012345) of=/dev/yourSdHere

Vérifiez ensuite la sortie skip == (en utilisant un petit échantillon de valeurs skip qui sont un plus petit nombre d'enregistrements écrits), par exemple skip = 9876 :

dd if=/dev/yourSdHere bs=16 count=1 skip=9876
000000000009876
1+0 records in
1+0 records out
16 bytes copied, ...

Ou, faites un échantillon de 20 emplacements avec un revêtement:

seq -w 000000000000000 NumberOfWrittenRecords | shuf | head -20 | while read i; do [[ $(dd if=/dev/yourSdHere bs=16 count=1 skip=$i) == $i ]] && echo ok || echo bad; done
  • Assurez-vous que vous écrivez sur la carte SD
  • Écrivez dans un fichier of=tempFileOnSD, si vous voulez éviter de détruire les données stockées sur votre carte (pertinent uniquement si ce n'est pas un faux)
  • Dans le cas d'une carte de 8 Go étiquetée comme 64 Go, la chance de réussir les 20 tests est de (8 Go / 64 Go) ** 20 <1e-18
karpada
la source
1
J'ai dû lire votre réponse trois fois avant de comprendre ce que vous disiez: «vérifier sauter == sortie» n'est pas clair. Et, sauf si je manque quelque chose, votre approche nécessite que l'utilisateur exécute les commandes 123456789012345 et  inspecte manuellement la sortie! C'est évidemment déraisonnable. Pourquoi ne pas simplement faire seq -w 0 123456789012345 > /dev/yourSdHereet seq -w 0 123456789012345 | cmp - /dev/yourSdHere?
Scott
Merci pour le commentaire :) J'ai édité ma réponse, j'espère que c'est mieux maintenant!
karpada
De plus, 123456789012345 est un nombre à 15 chiffres pour que chaque numéro utilise 16 octets. on peut utiliser le nombre de blocs de 16 octets sur le SD
karpada