Linux에서 SD 카드의 전체 용량을 어떻게 테스트 할 수 있습니까?


17

eBay에서 64GB SD 카드를 구입했습니다. Arch Linux ARM 이미지를 레코딩하고 Raspberry Pi를 부팅하는 데 사용할 때 정상적으로 작동합니다.

그러나 카드의 모든 용량을 사용하기 위해 단일 ext4 파티션을 만들려고하면 오류가 발생합니다. mkfs.ext4항상 행복하게 끝납니다. 그러나 파티션을 종료 할 수 없으며 mount항상 오류가 발생하고 dmesg커널 메시지에 포함됨이 표시됩니다 Cannot find journal. Arch Linux ARM과 Ubuntu 13.04의 두 가지 플랫폼에서 이러한 경우가 발생했습니다.

반면에, 오류없이 FAT32 파티션을 생성하고 마운트 할 수 있습니다 (전체 용량 검사가 수행되지 않았습니다).

더 나쁜 가격으로 카드를 판매하기 위해 일부 나쁜 사람들이 SD 카드 인터페이스를 변경하여 OS에 잘못된 용량을보고 할 수 있습니다 (예 : 카드가 실제로 2GB이지만 64GB로보고 됨).

badblocksSD 카드에 불량 블록이 있는지 확인할 수있는 도구가 있다는 것을 알고 있습니다. 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 카드가 포함되어 있습니다. 그러나이 문제는 하나의 차이점이 있습니다. SD 어댑터가있는 마이크로 SD 카드입니다.
어스 엔진

답변:


26

누군가 나중에 이것을 본다면 : 누군가가 "F3"라는 오픈 소스 도구를 작성하여 SD 카드 및 기타 미디어의 용량을 테스트했습니다. 프로젝트 홈 페이지Github에서 찾을 수 있습니다 .


실제로 SDCard를 테스트하는 것은 해당 주제의 참조입니다.
필립 Gachoud

6

부정 행위는 이제 다음 단계에 의해 확인되었습니다.

  • 무작위 데이터 파일을 생성하십시오. (4194304 = 4 × 1024 × 1024 = 4MiB, 총 크기 = 40 × 4MiB = 160MiB)

    명령:

    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 KiB = 7962.5MiB)

    명령:

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

어떻게 된 거예요? 우리는 0의 갭을 관찰했습니다. 이것은 무작위 데이터가 실제로 카드에 기록되지 않았 음을 나타냅니다. 그러나 왜 데이터가 다시 돌아 옵니까 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.5MB 또는 8GB보다 약간 작음을 알 수 있습니다.

나는 이것이 무작위 하드웨어 고장 일 가능성은 거의 없지만 일종의 부정 행위 (예 : 사기) 일 가능성이 있다고 결론을 내렸다. 다른 피해자를 돕기 위해 어떤 조치를 취할 수 있는지 알고 싶습니다.

2019 년 11 월 5 일 업데이트

  • 사람들은 올바른 seek매개 변수가 무엇인지 어떻게 알 수 있는지 물었습니다 2038399. 위에서 보여준 것보다 더 많은 경험을했습니다. 기본적으로 당신은 처음에 추측해야합니다. 적절한 크기의 데이터를 추측해야하며 데이터 손상이 발생한 위치를 추측해야합니다. 그러나 항상 이분법을 사용 하여 도움을 줄 수 있습니다.

  • 아래의 의견에서 나는 위의 두 번째 단계 (데이터를 SD 카드에 복사)가 1 섹터 만 복사한다고 가정했습니다. 그러나 나는 나의 실험에서이 실수를하지 않았다. 대신 seek"결과 표시"단계에서 오프셋 1000이 단순히 데이터의 두 번째 섹터에서 발생 한다는 것을 보여주었습니다 . (가) 경우 seek2,038,399 분야이며, 부패는 2,038,400번째 부문에 있습니다.


(1) 2038340과 2038399는 어디에서 왔습니까? (2) 왜 사용합니까  bs=4194304 count=40 에서 읽을 때 /dev/urandom 하지만,   bs=4096 count=40960  쓰기 및 SD 카드에서 읽을 때? (수학적으로 동일합니다. 각 167772160 바이트입니다.)
Scott

1) bisec tecnique를 사용하여 thie 오프셋을 계산했습니다. bisec 절차가 대답하기에는 너무 장황하므로, 나는 더 이상의 설명없이 분명하게 설명합니다. 2) 그렇습니다. 계산은 동등합니다. 하지만 4096이라고 생각되는 카드의 섹터 크기와 일치해야하는지 모르겠습니다.
Earth Engine

오, 포인트 2)의 경우을 사용 seek하므로 카드에 하나의 섹터 만 작성하여 데이터 전송량을 절약합니다. 원인은 실험 할 때 더 큰 데이터 블록을 사용했을 때 생성 된 데이터 파일이 160MiB 인 이유입니다.
어스 엔진

두 번째 의견은 말이되지 않습니다. 답안의 두 번째 명령 (카드에 쓰는 명령)은 sudo dd if=test.orig of=/dev/sde seek=2038399 bs=4096입니다. 그리고 분명히 당신이 맞습니다. 사용합니다 seek. 그리고 기술적으로는 사용하지 않습니다 count. … (계속)
Scott

(계속)… 그러나 당신은“나는 단지 1 개의 섹터를 카드에 썼고, 이는 데이터 전송량을 절약 해줍니다”라고 말합니다. 분명히 틀 렸습니다. count사양이 없으면 dd전체 입력을 전송합니다 (즉, EOF 또는 오류까지 전송 함). 따라서이 명령 test.orig은 4096 바이트의 40960 레코드 인 전체 내용을 총 167772160 바이트로 전송합니다.
Scott

3

우선 @Radtoo 의 F3 답변을 읽으십시오. 올바른 방법입니다.

나는 어떻게 든 그것을 놓치고 내 자신의 길을 시도했다.

  1. 1GB 테스트 파일 생성 : dd if=/dev/urandom bs=1024k count=1024 of=testfile1gb

  2. 해당 파일의 사본을 sdcard에 씁니다 (64는 sdcard 크기 (GB)). 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
Philippe Gachoud

2

SD 카드의 전체 용량을 테스트하는 가장 간단한 방법은 파일로 파일을 채우고 파일이 올바른지 확인하는 것입니다. diff -qr /directory/on/computer /directory/on/SD

또는 프로그램을 사용하여 패턴 또는 해시 체인을 파일에 쓴 다음 패턴이 올바른지 확인할 수 있습니다.

으로 @Earthy 엔진 지적, 그것을 읽은 다음, 단순히 데이터의 작은 블록을 쓰기 전통적인 방법으로, 다음, SD 카드를 작성하여 데이터를 읽는 것이 중요합니다, 가짜의 SSD 카드에 속지된다.


2

나는 다음을 수행하는 작은 스크립트를 작성했습니다.

대상 USB 또는 SC 카드에 임시 디렉토리를 만듭니다.

-md5sum 체크섬으로 5MB의 무작위로 생성 된 참조 파일을 만듭니다.

-참조 파일을 대상에 복사하고 대상에서 md5sum 검사를 생성하여 읽기 / 쓰기 성공을 확인합니다.

-체크섬 오류 발생시 대상을 용량 (100 %)으로 채우거나 중지

-스크립트가 자연스럽게 중지되면보고 된 대상 크기, 사용 및 무료 금액이 표시됩니다.

이 스크립트를 사용하여 64GB에 8GB microSD를 전달한 이베이 판매자가 찢어 졌다고 결론지었습니다.

#!/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
이로 인해 잘못된 결과가 발생할 수 있습니다. OS는 파일 시스템 쓰기를 버퍼링하기 때문에 대부분 SD 카드가 아닌 시스템 메모리를 테스트하고 있습니다.
Cerin

"hdparm -W 0 / dev / disk"를 실행하면 버퍼 된 쓰기 문제가 해결됩니다.
Michael

1

일련의 숫자 (각 행은 16 바이트 임)를 작성한 다음 내용을 확인할 수 있습니다.

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

그런 다음 skip == 출력을 확인하십시오 (기록 된 레코드 수가 적은 작은 스킵 값 샘플 사용). skip = 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카드에 저장된 데이터를 파괴하지 않으려면 파일에 쓰기 하십시오 (가짜가 아닌 경우에만 해당)
  • 64GB로 표시된 8GB 카드의 경우 20 개의 테스트를 모두 통과 할 확률은 (8GB / 64GB) ** 20 <1e-18입니다.

1
나는 당신이 말하는 것을 이해하기 전에 세 번 당신의 대답을 읽어야했습니다 : "확인 건너 뛰기 == 출력"이 명확하지 않습니다. 그리고, 내가 빠진 것이 없다면, 당신의 접근 방식은 사용자가 123456789012345 명령을 실행하고  수동으로 출력을 검사해야합니다! 분명히 그것은 합리적이지 않습니다. 왜 바로 안 seq -w 0 123456789012345 > /dev/yourSdHereseq -w 0 123456789012345 | cmp - /dev/yourSdHere?
Scott

의견 주셔서 감사합니다 :) 내 답변을 편집했습니다, 지금 더 나아지기를 바랍니다!
karpada

또한 123456789012345는 각 숫자가 16 바이트를 사용하도록하는 15 자리 숫자입니다. 하나는 SD에 16 바이트 블록의 수를 사용할 수 있습니다
karpada
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.