Как я могу проверить полную емкость SD-карты в Linux?


17

Я купил карту SD на 64 ГБ у eBay. Он отлично работает, когда я записываю образ Arch Linux ARM и использую его для загрузки моего Raspberry Pi.

Однако, когда я пытаюсь создать на нем один раздел ext4 для использования всей емкости карты, возникают ошибки. mkfs.ext4всегда заканчивается счастливо; однако, раздел не может быть mountотредактирован, всегда выдает ошибку и dmesgпоказывает сообщения ядра Cannot find journal. Это подтвердилось как минимум на двух платформах: Arch Linux ARM и Ubuntu 13.04.

С другой стороны, я могу создать и смонтировать раздел FAT32 без ошибок (проверка полной емкости не была выполнена).

Я слышал, что некоторые плохие парни могут изменить интерфейс SD-карты, чтобы сообщить о неправильной емкости ОС (т. Е. Карта действительно всего 2 ГБ, но сообщает о себе как 64 ГБ), чтобы продать карту по более выгодной цене.

Я знаю, что подобные инструменты badblocksсуществуют для меня, чтобы проверить SD-карту на предмет плохих блоков. Может ли badblocksобнаружить такие проблемы? Если нет, то какие еще существуют решения для тестирования карты?

В идеале я хотел бы знать, был ли я обманут или нет; если результат показывает, что я только что получил плохой товар, я могу только вернуться к продавцу, а сообщить в eBay, что кто-то пытался меня обмануть.

ОБНОВИТЬ

операции и сообщения:

~$ 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

ОБНОВИТЬ

Я бежал, badblocks /dev/sdeно он не сообщает об ошибке. Это означает, что оставшиеся причины:

  • SD автомобиль хорош , но по какой - то причине mke2fsили mountили ядра есть ошибка , которая вызывает проблему.

  • Я был обманут таким образом, badblocksчто это не может обнаружить поражение. Это правдоподобно, потому что я думаю, что badblocksпросто делает некоторый тест записи-чтения на месте. Однако мошенник может связать доступ к исходящим областям с каким-либо входящим блоком. В этом случае проверка на запись-чтение на месте не может обнаружить проблему.

Если нет приложения, способного выполнить надлежащий тест, я думаю, что я могу попытаться написать простую C-программу для его тестирования.


Вы пробовали это в устройстве чтения карт SDXC USB?
Игнасио Васкес-Абрамс

Кроме того, появляются ли какие-либо сообщения в системном журнале одновременно с ошибками?
Игнасио Васкес-Абрамс

Я попробовал как с родным устройством для чтения карт Raspberry Pi, так и с внешним устройством для чтения карт для моего рабочего стола Ubuntu. Я сказал, что dmesgпоказывает сообщения ядра, и я уверен, что они появляются одновременно с ошибками, потому что я делал это до и после и сравнивал их. Я не проверю, syslogпотому что я верю dmesg, покажет сообщения.
Земля Двигатель

Это показывает какие-либо другие сообщения?
Игнасио Васкес-Абрамс

Внешний кардридер, который я использовал, работает для других моих карт, включая SDXC-карты. Однако у этого проблемного есть одно отличие: это карта micro SD с адаптером SD.
Земля Двигатель

Ответы:


26

Если кто-то увидит это позже: кто-то написал инструмент с открытым исходным кодом под названием «F3» для проверки емкости SD-карт и других подобных носителей. Его можно найти на сайте проекта и в Github .


На самом деле это ссылка в этой теме для тестирования SDCards ...
Филипп Гачу

6

Обман был подтвержден следующими шагами:

  • Создайте файл случайных данных. (4194304 = 4 × 1024 × 1024 = 4 МБ, общий размер = 40 × 4 МБ = 160 МБ)

    Команда:

    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
    
  • Скопируйте данные на SD-карту. (2038340 × 4096 = 8153600 КиБ = 7962,5 МиБ)

    Команда:

    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
    
  • Считайте данные обратно с SD-карты.

    Команда:

    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
    
  • Показать результат

    Команда:

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

Что произошло? Мы наблюдали разрыв нулей. Это показатель того, что случайные данные фактически не были записаны на карту. Но почему данные возвращаются после 1a81000? Очевидно, карта имеет внутренний кэш.

Мы также можем попытаться исследовать поведение кэша.

hexdump test.orig | grep ' 0000 0000 '

не дает результата, что означает, что сгенерированный мусор не имеет такой картины. Тем не мение,

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

есть 4 матча.

Вот почему он проходит badblocksпроверку. Дальнейшие тесты могут показать, что фактическая емкость составляет 7962,5 МБ или чуть меньше 8 ГБ.

Я пришел к выводу, что это очень маловероятно, что это просто случайный аппаратный сбой, но скорее всего это обман (т. Е. Мошенничество). Я хотел бы знать, какие действия я могу предпринять, чтобы помочь другим жертвам.

Обновление 11/05/2019

  • Люди спрашивали меня о том, как я выяснил, правильный seekпараметр 2038399. Я сделал намного больше опыта, чем я показал выше. В основном вы должны угадать в первую очередь. Вы должны угадать правильный размер данных, и вы должны угадать, где было повреждение данных. Но вы всегда можете использовать метод деления пополам .

  • В комментарии ниже я подумал, что предполагалось, что второй шаг выше (копирование данных на SD-карту) копирует только 1 сектор. Но я не ошибся в своем эксперименте. Вместо этого seekнужно было показать, что на этапе «показать результат» смещение 1000просто происходит во втором секторе данных. Если seek2038399 секторов, коррупция находится на 2038400-м секторе.


(1) Откуда берутся номера 2038340 и 2038399? (2) Почему вы используете  bs=4194304 count=40 при чтении с, /dev/urandom а   bs=4096 count=40960  при записи и чтении с SD-карты? (Они математически эквивалентны; 167772160 байтов каждый.)
Скотт

1) Я использовал Bisec Tecnique, чтобы выяснить смещение. Поскольку процедура bisec слишком многословна для ответа, я просто назвал ее очевидной без дальнейших объяснений. 2) Да, расчет эквивалентен; но я не знаю, должен ли я соответствовать размеру сектора карты, который, как я считаю, равен 4096.
Earth Engine

О, для пункта 2) Я использую seek, поэтому я записал только 1 сектор на карту, что экономит объем передаваемых данных. Конечно, при экспериментировании я использовал больший блок данных, поэтому сгенерированный файл данных имеет размер 160 МБ.
Земля Двигатель

Ваш второй комментарий не имеет никакого смысла. Вторая команда в вашем ответе - та, которая пишет на карту - есть sudo dd if=test.orig of=/dev/sde seek=2038399 bs=4096. И, очевидно, вы правы; он использует seek. И, да, технически это не использует count. … (Продолжение)
Скотт

(Продолжение)… Но вы говорите: «Я записал только 1 сектор на карту, что экономит объем передаваемых данных». Это явно неправильно; без countспецификации ddпередает весь ввод (т. е. передает до EOF или с ошибкой). Таким образом, эта команда передает весь контент test.orig, который составляет 40960 записей по 4096 байт каждая, в общей сложности 167772160 байт (как я уже говорил).
Скотт

3

Прежде всего, прочитайте ответ F3 от @Radtoo. Это правильный путь.

Я как-то пропустил это и попробовал по-своему:

  1. создать тестовый файл 1 ГБ: dd if=/dev/urandom bs=1024k count=1024 of=testfile1gb

  2. записать копии этого файла на SDCard (64 - размер SDCard в ГБ): for i in $(seq 1 64); do dd if=testfile1gb bs=1024k of=/media/sdb1/test.$i; done

  3. проверьте md5 файлов (все, кроме последнего, неполного, должны совпадать): md5sum testfile1gb /media/sdb1/test.*


Это простой и быстрый подход.
Земной двигатель

Этот метод хорошо документирован здесь. Ccollins.wordpress.com/2016/01/18/testing-sd-cards-with-linux
Филипп Гачу

2

Самый простой способ проверить полную емкость SD-карты - это заполнить ее файлами, а затем проверить правильность файлов: diff -qr /directory/on/computer /directory/on/SD

Кроме того, вы можете использовать программы для записи шаблонов или цепочек хэшей в файл, а затем проверять их правильность.

Как отметил @Earthy Engine , важно заполнить SD-карту, а затем прочитать данные, поскольку традиционные подходы, которые просто записывают небольшой блок данных, а затем читают их, одурачены поддельными картами SSD.


2

Я написал небольшой скрипт, который делает следующее.

-создание временного каталога на целевую карту USB или SC

-создает 5-мегабайтный случайно сгенерированный эталонный файл с контрольной суммой md5sum

-копирует справочный файл к цели и генерирует проверку md5sum из цели, чтобы подтвердить успех чтения / записи

- заполняет цель до емкости (100%) или останавливается при возникновении ошибки контрольной суммы

-Как только скрипт останавливается естественным образом, он отображает целевой размер сообщения, использованные и свободные суммы.

С помощью этого скрипта я пришел к выводу, что меня сорвал продавец eBay, который передал microSD 8 ГБ за 64 ГБ

#!/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

1
Это может дать ошибочные результаты. Поскольку ОС буферизует запись в файловую систему, вы в основном тестируете память вашей системы, а не SD-карту.
Церин

выполнение «hdparm -W 0 / dev / disk» должно решить проблему буферизованных записей.
Майкл

1

Можно написать последовательность чисел (каждая строка составляет 16 байтов), а затем проверить содержимое:

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

Затем проверьте пропустить == вывод (используя небольшую выборку пропущенных значений с меньшим количеством записанных записей), например пропустить = 9876 :

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

Или сделайте выборку из 20 мест с одним вкладышем:

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
  • Убедитесь, что вы пишете на SD-карту
  • Записать в файл of=tempFileOnSD, если вы хотите избежать уничтожения данных, хранящихся на вашей карте (актуально, только если это не подделка)
  • В случае карты на 8 ГБ, помеченной как 64 ГБ, вероятность прохождения всех 20 тестов составляет (8 ГБ / 64 ГБ) ** 20 <1e-18

1
Мне пришлось прочитать ваш ответ три раза, прежде чем я понял, что вы говорите: «проверить пропуск == вывод» не ясно. И, если я что-то упустил, ваш подход требует, чтобы пользователь выполнил команды 123456789012345 и  вручную проверил вывод! Очевидно, что это неразумно. Почему бы просто не сделать seq -w 0 123456789012345 > /dev/yourSdHereи seq -w 0 123456789012345 | cmp - /dev/yourSdHere?
Скотт

Спасибо за комментарий :) Я отредактировал свой ответ, надеюсь, теперь он лучше!
Карпада

Кроме того, 123456789012345 - это 15-значный номер, чтобы каждый номер использовал 16 байтов. можно использовать количество 16-ти байтовых блоков на SD
karpada
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.