설명하다
6개의 SSD 드라이브가 포함된 IMSM RAID 5 어레이가 있습니다. 드라이브 중 하나가 몇 달 전에 고장이 나서 아직 교체할 수 없었습니다. (예, 저도 가끔 게으르다는 걸 압니다. 저를 판단하지 마세요.) 하지만 RAID에서 제거했습니다.
그러나 어제 또 다른 드라이브가 실패한 것으로 나타났습니다. 어레이가 조립되지 않았습니다. BIOS조차도 RAID를 구축할 수 없기 때문에 아무것도 부팅할 수 없습니다. 자세히 살펴보니 드라이브에는 아무런 문제가 없는 것 같았습니다. 나는 그것에 액세스하고 dd를 사용하여 백업을 만들 수 있습니다. 그런데 지금은 처음부터 MBR 레코드가 있었던 것 같습니다. 일부 프로세스가 MBR 테이블로 RAID 슈퍼 블록을 덮어썼을 수도 있습니다. 이 경우 데이터는 여전히 존재해야 합니다. mdadm
올바른 메타데이터를 말할 수 있으면 됩니다 . 내가 생각해 보면 아마도 첫 번째 "실패한" 드라이브에서도 같은 일이 일어났을 것입니다. 아직 읽을 수 있기 때문입니다. 하지만 당시에는 조사에 신경 쓰지 않았습니다.
그럼에도 불구하고, 나는 지금 (가능한 경우) 데이터에 접근하기 위해 배열을 재조립하는 방법을 찾으려고 노력하고 있습니다. 블록 크기, 드라이브의 정확한 순서, RAID 레벨을 알고 있습니다. 이 정보로는 충분하지 않나요?
몇가지 정보
dd
내가 한 첫 번째 일은 (named) 를 사용하여 나머지 5개 드라이브의 이미지를 만드는 것이었습니다 sd[a-e].backup
. 또한 --examine
출력을 사용하고 저장한 모든 드라이브를 확인했습니다 . 출력을 읽을 수 있습니다.이 점. 보시다시피 mdadm은 MBR 헤더를 읽고 sdb
RAID 정보를 감지하지 않고 다음 드라이브로 계속 진행합니다. 다른 모든 드라이브의 경우 mdadm은 올바른 메타데이터를 인쇄합니다. 이렇게 하면 다음과 같은 결과가 나옵니다.cat /proc/mdstat
Personalities:
md127 : inactive sda[3](S) sdd[2](S) sde[1](S) sdc[0](S)
13049 blocks super external:imsm
unused devices: <none>
내가 시도한 것
- 분명히 나는 "껐다가 다시 켜기"를 시도했습니다.
# mdadm --stop /dev/md127
mdadm: stopped /dev/md127
# mdadm --assemble /dev/md0 /dev/sdb missing /dev/sda /dev/sdc /dev/sde /dev/sdd
mdadm: Cannot assemble mbr metadata on /dev/sdb
mdadm: /dev/sdb has no superblock - assembly aborted
# mdadm --assemble --scan
mdadm을 마지막으로 호출한 후 /proc/mdstat
출력은 다시 위와 동일해 보입니다.
그런 다음 읽기 전용 루프 장치를 만들었습니다.
# losetup --show -rf /mnt/backup/sdX.backup
[...]
# losetup -a
/dev/loop1: [...] (/mnt/backup/sda.backup)
/dev/loop2: [...] (/mnt/backup/sdb.backup)
/dev/loop3: [...] (/mnt/backup/sdc.backup)
/dev/loop4: [...] (/mnt/backup/sdd.backup)
/dev/loop5: [...] (/mnt/backup/sde.backup)
--build
다음으로 슈퍼블록 정보가 필요하지 않고 모든 메타데이터를 수동으로 제공할 수 있으므로 사용해 보았습니다 .
# mdadm --build /dev/md0 --raid-devices=6 --level=5 --chunk=32 /dev/loop2 missing /dev/loop1 /dev/loop3 /dev/loop5 /dev/loop4
mdadm: Raid level 5 not permitted with --build
--build
하지만 분명히 레벨 5 RAID 환경에서는 사용할 수 없습니다 .
--assemble
다음으로 RAID에 대한 OROM 정보를 사용해 보았지만 사용하지 않았습니다.
# IMSM_NO_PLATFORM=1 mdadm --assemble /dev/md0 /dev/loop2 missing /dev/loop1 /dev/loop3 /dev/loop5 /dev/loop4
mdadm: Cannot assemble mbr metadata on /dev/loop2
mdadm: /dev/loop2 has no superblock - assembly aborted
그건 너무 쉬울 것 같아요. mdadm에게 이것이 loop2
어레이의 첫 번째 장치라고 가정하고 다른 드라이브의 메타데이터를 사용하도록 지시할 수 있습니까 ?
- 마지막으로 시도한 것은 루프 장치를 읽기-쓰기로 다시 설치하고 어레이를 다시 만드는 것이었습니다. 그러나 내가 찾은 모든 예는 (이와 같이또는이것) 배열이 mdadm을 사용하여 생성되었다고 가정합니다. 그러나 그것은 진실이 아니다. 원래 BIOS의 유틸리티에 의해 생성되었으며 IMSM 또는 Intel Rapid Storage Format이 있습니다. 레이아웃이나 데이터 오프셋과 같은 자세한 내용을 알아야 할 것 같습니다. IMSM의 기본 설정이 무엇인지, 어디서 찾을 수 있는지 잘 모르겠습니다. 하지만 더 중요한 것은 mdadm의 메타데이터 형식이 IMSM보다 더 많은 공간과 더 큰 슈퍼블록을 사용하고 메타데이터를 저장할 때 데이터를 덮어쓰게 된다는 점입니다. IMSM을 사용하여 어레이를 다시 생성할 수도 있습니까? 아니면 메타데이터를 외부에 저장할 수도 있습니다. 간단히 말해서 mdadm을 사용하여 IMSM 배열을 수동으로 다시 만드는 방법을 모르겠습니다.
StackExchange에 대한 기타 질문
답변1
유레카 - 소개
그래서 내 데이터에 다시 액세스하는 방법을 알아냈습니다. 불행히도 나는 그것을 사용하여 배열을 다시 만들 수 없습니다 mdadm
. 문제는 IMSM을 사용하려면 먼저 컨테이너를 만들어야 한다는 것입니다. 그러나 컨테이너는 분실된 장치를 수용하지 않습니다. 원래 6개의 하드 드라이브가 필요했는데 지금은 5개만 있습니다. 또한 RAID 컨트롤러에 연결해야 하기 때문에 가상 하드 디스크를 사용할 수 없습니다. 또한 mdadm
볼륨을 생성한 후 드라이브 동기화를 시작하는지 여부와 방법을 잘 모르겠습니다 . 그러나 나는 내 모든 파일에 다시 액세스할 수 있는 방법을 찾았습니다 dmsetup
.
작업할 드라이브를 여러 번 백업하는 동안 더 이상 어레이의 일부가 아닌 드라이브 하나가 때때로 IO 오류로 인해 실패한다는 사실도 깨달았습니다. 세 번째 호출마다 이러한 오류가 발생했기 때문에 여전히 백업을 만들 수 있었습니다 dd
. IO 오류가 발생하자마자 드라이브가 IMSM에 의해 어레이에서 제외되고 해당 메타데이터가 모두 삭제된 것으로 추측됩니다.
또한 드라이브가 어레이의 첫 번째 드라이브라는 것도 깨달았습니다. GPT 테이블이 있고 어레이의 데이터가 첫 번째 섹터에서 시작하므로 MBR로 시작하는 것도 논리적입니다. 따라서 드라이브의 슈퍼 섹터는 MBR에 의해 덮어쓰여지지 않습니다. 그것은 항상 거기에 있었습니다.
데이터 읽기
여기서는 프로세스에 사용되는 모든 명령을 설명하면서 단계별 솔루션을 제공하려고 했습니다. 이것이 누군가에게 도움이 되기를 바랍니다.
(선택 사항) 모든 드라이브 백업
이는 반드시 필요한 것은 아닙니다. 특히 나중에 읽기 전용 루프 장치를 사용할 것이기 때문입니다. 그러나 스토리지 솔루션에 심각한 오류가 발생한 후 저는 특히 편집증에 빠졌습니다. 그래서 실제 데이터를 사용하지 않으려고 노력합니다. 그 외에도 백업 파일을 사용하면 이 방법에는 원시 하드 드라이브나 BIOS가 전혀 필요하지 않음을 알 수 있습니다. 필요한 것은 dd 이미지뿐입니다. 이 섹션을 건너뛰는 경우 실제로 다음 섹션에서 루프 장치를 읽기 전용으로 생성해야 합니다. 그렇지 않으면 데이터 품질이 더욱 저하되고 영원히 손실될 위험이 있습니다.
그러나 하드 드라이브를 백업하는 명령은 다음과 같습니다. 이미 dd에 익숙할 수도 있습니다. 그러나 어레이의 모든 하드 드라이브에 대해 이 명령을 실행하지 않는 경우:
# dd if=/dev/sdX of=/path/to/backups/sdX.img status=progress
# dd if=/dev/sdY of=/path/to/backups/sdY.img status=progress
# [...]
입력 파일은 if=/dev/sdX
하드 드라이브입니다. 등 sdX
으로 교체하세요 sda
. sdb
출력 파일은 of=/path/to/backups/sdX.img
기록할 이미지를 가리킵니다. 적절하게 다시 sdX
교체하십시오 . status=progress
GNU 버전의 dd에게 현재 진행 상황을 stderr에 인쇄하도록 지시합니다.
루프 장치 만들기
다음으로 루프 장치를 생성하겠습니다. 백업 이미지를 사용하면 해당 이미지가 블록 파일로 인식됩니다. 이것이 필요하지 않을 수도 있습니다. 그러나 어쨌든 읽기 전용 플래그를 사용하므로 이미지는 읽기만 가능합니다.-r
# losetup --show -rf /path/to/backups/sdX.img
# losetup --show -rf /path/to/backups/sdY.img
[...]
-r
: 파일에서 읽기만 하고 쓰지 않습니다.-f
: 우리 스스로 추측할 필요가 없도록 루프 장치의 다음 사용 가능한 번호를 사용합니다.--show
: 실제 선택한 이름을 인쇄합니다-f
. 이것은 종종 매우 유용합니다. 어쨌든 다음 단계에서 이 값을 인쇄하겠습니다.
방금 만든 루프 장치를 더 잘 이해하려면 다음 명령을 사용할 수 있습니다.
# losetup -a
/dev/loop1: [2129]:251265027 (/path/to/backups/sdX.img)
/dev/loop2: [2129]:251265027 (/path/to/backups/sdY.img)
[...]
어떤 루프 장치가 어떤 이미지에 속하는지 기억해 보십시오.
메타데이터 수집
다음으로 RAID에 대한 몇 가지 정보를 알아야 합니다. 특히, RAID가 시작하는 섹터(특히 매트릭스 RAID의 경우), 확장된 섹터 수, 블록 크기 및 레이아웃, 드라이브가 어레이에 추가되는 순서를 알아내야 합니다.
하나 이상의 드라이브가 여전히 어레이의 일부이고 메타데이터가 첨부되어 있는 경우 이를 사용하여 필요한 대부분의 정보를 검색할 수 있습니다. sdX
여전히 어레이의 일부인 드라이브에서 다음 명령을 실행하십시오.
# mdadm --examine /dev/sdX
/dev/sdX:
Magic : Intel Raid ISM Cfg Sig.
Version : 1.3.00
Orig Family : aa0b2c12
Family : 48d867fb
Generation : 0018f99c
Attributes : All supported
UUID : 0312fa14:fa8db3c2:2a76dc3f:299ed5b4
Checksum : 084869b8 correct
MPB Sectors : 6
Disks : 6
RAID Devices : 1
Disk02 Serial : S21PNSBG710576N
State : active
Id : 00000000
Usable Size : 488391936 (232.88 GiB 250.06 GB)
Bad Block Management Log:
Log Size : 2040
Signature : abadb10c
Entry Count : 254
[NameOfYourArray]:
UUID : 24b1e785:14f37ee5:41f6a4ab:d8b89e11
RAID Level : 5
Members : 6
Slots : [__UUUU]
Failed disk : 1
This Slot : 2
Sector Size : 512
Array Size : 2441959424 (1164.42 GiB 1250.28 GB)
Per Dev Size : 488392200 (232.88 GiB 250.06 GB)
Sector Offset : 0
Num Stripes : 7631124
Chunk Size : 32 KiB
Reserved : 0
Migrate State : idle
Map State : failed
Dirty State : clean
RWH Policy : off
출력은 계속되지만 나머지는 무시할 수 있습니다. 위에 표시된 출력은 다음과 같은 중요한 정보를 생성합니다.
Sector Offset : 0 # Where the data starts
# (right at the first sector in my case)
Array Size : 2441959424 # Size of the volume (data) inside the array
Chunk Size : 32 KiB # Size of a single chunk
어레이 내에서 특정 드라이브의 위치를 확인할 수도 있습니다.
This Slot : 2
이는 해당 드라이브가 어레이의 세 번째 드라이브임을 의미합니다. (슬롯 번호는 0부터 시작합니다.) 또는 Disk## Serial : [...]
슬롯 번호도 묻는 메시지가 표시됩니다.
Disk02 Serial : S21PNSBG710576N
모든 드라이브에 대해 이 명령을 실행하십시오. 여전히 유효한 결과가 나오는 경우에는 슬롯 번호를 기록해 두십시오.
다른 방법을 사용하여 어레이의 첫 번째 드라이브를 결정할 수 있습니다. RAID는 바이트가 아닌 블록으로 쓰기 때문에 처음 32kiB는 첫 번째 드라이브에 상주합니다. 두 번째 드라이브의 두 번째 32kiB 등입니다. 이는 첫 번째 드라이브에 파티션 테이블의 시작 부분을 포함할 만큼 충분한 섹터가 있어야 함을 의미합니다. 이는 시작할 MBR이 있어야 함을 의미합니다(보호 MBR로 시작하므로 GPT를 사용하는 경우에도). mdadm --examine
메타데이터 없이 MBR을 찾았다고 알려왔습니다. 하지만 fdisk -l
.
제 경우에는 메타데이터를 통해 4개 드라이브의 슬롯 번호를 찾을 수 있었습니다. 다섯 번째 드라이브에 MBR이 포함되어 있어서 그것이 첫 번째 드라이브라는 것을 자동으로 알게 된 것은 행운입니다. 6개 드라이브 중 5개이면 어레이를 시작하는 데 충분합니다. 드라이브의 정확한 슬롯 번호를 충분히 알지 못하는 경우 이 방법이 성공할 때까지 다른 배열을 사용해 볼 수 있습니다.
이는 내 드라이브 및 루핑 장치의 올바른 순서가 다음과 같다는 것을 의미합니다.
코인 투입구 | 운전하다 | 순환 장치 |
---|---|---|
마스터 부트 레코드(0) | /dev/sdb | /dev/loop2 |
1 | 잃어버린 | - |
2 | /dev/sda | /개발/루프1 |
삼 | /dev/sdc | /dev/loop3 |
4 | /dev/sde | /dev/loop5 |
5 | /dev/sdd | /dev/loop4 |
마지막으로 알아보아야 할 것은 레이아웃입니다. 안타깝게도 mdadm
관련 정보를 제공하지 않았습니다. 그러나 우리가 볼 때인텔의 RAID 정의RAID 5 레이아웃은 항상 비대칭인 것 같습니다. IMSM 어레이를 다른 레이아웃으로 구성할 수 있는지는 확실하지 않지만 제 생각에는 그럴 것 같지 않습니다. 이 방법 중 어느 것도 효과가 없다면 다른 레이아웃을 시도해 볼 수 있습니다. 구경하다소스 코드에서다른 레이아웃에 대해 자세히 알아보세요.
다음은 IMSM에서 지원하는 모든 RAID 레벨의 개요입니다. dmsetup 키워드는 다음 장에서 사용됩니다.
RAID 레벨 | 공들여 나열한 것 | dmsetup 구문 |
---|---|---|
0 | 해당 없음 | 레이드 0 |
1 | 해당 없음 | 습격 1 |
5 | 왼쪽 비대칭 | 습격 5_la |
10 | 기본값(1E 또는 사본 없음) | 레이드 10 |
어떤 드라이브에서도 메타데이터를 수집할 수 없는 경우 값을 추측하거나 다른 조합을 시도해야 합니다. 이를 돕기 위해 IMSM은 다음과 같은 다양한 모드를 지원합니다.
정보 | 가능한 값 |
---|---|
RAID 레벨 | 0, 1, 5, 10 |
블록 크기 | 4kiB, 8kiB, 16kiB, 32kiB, 64kiB, 128kiB |
시작 섹터 및 크기에 대해 확실하지 않은 경우 0과 어레이에서 가장 작은 드라이브의 크기에 패리티가 없는 드라이브 수를 곱한 값을 가정하는 것이 가장 좋습니다. 다음 명령을 실행하여 드라이브의 섹터 크기를 얻을 수 있습니다.
blockdev --getsize /dev/sdX
데이터가 실제로 0에서 시작하지 않는 경우에도 나중에 다음을 통해 올바른 오프셋을 얻을 수 있습니다.파티션 헤더 검색아니면 합격이라도 하세요파일 시스템 검색.
dmsetup을 사용하여 어레이 조립
안타깝게도 mdadm
. 유일한 예외는사용 가능한 RAID 레벨 0 및 1--build
:
mdadm --build /dev/md0 --raid-devices=2 --level=0 --chunk=32 /dev/loop0 /dev/loop1
여기서는 운이 좋지 않으므로 다른 도구를 사용해야 합니다. 그래서 우리는 그것을 대신 사용할 것입니다 dmsetup
. dmsetup
실제 드라이브나 다른 소스에 매핑된 가상 하드 드라이브를 생성하는 명령입니다. 이러한 맵은 여러 부분으로 구성되어 있으며 각 부분은 다른 드라이브에 매핑될 수 있습니다. 우리의 경우 섹션 하나만 필요하며 이를 수동으로 제공할 메타데이터의 RAID에 매핑합니다.
하지만 먼저 숫자에 관해 이야기해야 합니다. 이전에 결정한 것처럼 제 경우의 블록 크기는 32kiB입니다. 그러나 dmsetup
부서는 필요합니다. 거의 모든 경우에 한 섹터는 512바이트와 같습니다. 안전한 편이 되려면 checkector size 를 사용할 수 있습니다 blockdev --getss /dev/sdX
. 내가 아는 한 그것은 32 kiB / (512 bytes/sector) = 64 sectors
. 우리는 이미 섹터 배열의 데이터 크기를 알고 있습니다(예: 2441959424). 하지만 문제가 있습니다. 6개의 장치가 있습니다. 스트라이프당 하나의 패리티 블록의 경우 블록 수는 5로 나누어야 합니다. 그러나 섹터 수는 5로 나눌 수 없습니다. 내 경우에는 적어도 블록당 섹터 수로 균등하게 나눌 수 있습니다. 하지만 그것이 보장되는지조차 확신할 수 없습니다. 마지막 스트립의 중간에 데이터가 중지된 것 같습니다. 불행하게도 dmsetup은 이를 허용하지 않습니다. 이는 5개의 드라이브와 64개의 섹터로 나눌 수 있는 가장 가까운 정수로 반올림해야 함을 의미합니다(이 숫자를 상황에 맞게 조정). 제 경우에는 2441959680입니다. 이는 fdisk
잘못된 드라이브 크기와 누락된 백업 테이블에 대한 불만이 있을 수 있음을 의미합니다. 하지만 dd 이미지를 자르면 이 문제를 해결할 수 있습니다.
table.txt
이제 한 줄이 포함된 섹션이 있는 파일(예: )을 만듭니다 .
<start> <size> raid <raid layout> 2 <chunk size> nosync <num devices>[ - /dev/loopN|-]*num_devices
먼저 섹터의 시작 위치와 크기를 지정해야 합니다. 다음 매개변수는 이것이 RAID임을 나타냅니다. RAID 레이아웃은 이전 섹션의 표를 참조하세요. 다음 매개변수의 "2"는 RAID의 두 가지 특수 매개변수를 나타냅니다. 첫 번째는 블록 크기입니다. 두 번째는 동기화를 방지합니다. 그런 다음 먼저 장치 수를 제공한 다음 각 장치에 대한 한 쌍의 메타데이터 및 장치 경로를 제공하여 드라이브를 설명해야 합니다. 메타데이터를 제공하고 싶지 않기 때문에 대시를 사용하여 이를 나타냅니다. 장치가 누락된 경우 메타데이터나 장치를 모두 사용할 수 없음을 나타내는 두 개의 대시를 씁니다. RAID 수준에서 허용하는 경우 하나 이상의 장치를 유지하는 것이 좋습니다. 드라이브에 잘못된 데이터가 포함되어 있을 수 있다고 이미 의심되는 경우 해당 드라이브를 선택하십시오.
예를 들어 제 경우에는 파일이 아래와 같습니다. 두 번째 장치가 없습니다.
0 2441959680 raid raid5_la 2 64 nosync 6 - /dev/loop2 - - - /dev/loop1 - /dev/loop3 - /dev/loop5 - /dev/loop4
이제 다음 명령을 실행하여 배열에 매핑된 새 청크 파일을 만듭니다.
# dmsetup create sdr /path/to/table.txt
이로 인해 많은 IO 오류가 발생할 수 있습니다. 이 경우 섹터 크기가 블록 크기로 균등하게 나누어지지 않을 수 있습니다. 다음을 사용하여 블록 파일을 제거하여 마지막 단계를 다시 실행할 수 있습니다.
# dmsetup remove sdr
이제 새로 생성된 장치 파일을 살펴보겠습니다. 당신이 달리면
# fdisk -l /dev/mapper/sdr
파티션 테이블을 볼 수 있어야 합니다. GPT 테이블이 있는 경우 이 두 가지 오류에 대해 걱정하지 마세요. 크기가 일치하지 않고 백업 테이블이 누락되는 이유는 RAID에 대해 선택한 크기가 너무 크기 때문입니다.
내 모습은 다음과 같습니다.
Device Start End Sectors Size Type
/dev/mapper/sdr-part1 2048 923647 921600 450M Windows recovery environment
/dev/mapper/sdr-part2 923648 1128447 204800 100M EFI System
/dev/mapper/sdr-part3 1128448 1161215 32768 16M Microsoft reserved
/dev/mapper/sdr-part4 1161216 679840003 678678788 323.6G Microsoft basic data
/dev/mapper/sdr-part5 679841792 680902655 1060864 518M Windows recovery environment
/dev/mapper/sdr-part6 680904704 2295472127 1614567424 769.9G Linux filesystem
/dev/mapper/sdr-part7 2295472128 2441957375 146485248 69.9G Linux swap
이 테이블의 시작 및 섹터 열을 사용하면 이러한 파티션 중 일부를 마운트할 수도 있습니다. 모든 숫자는 섹터에 속하며 바이트로 변환하려면 512를 곱해야 합니다.
# mount -o ro,noload,loop,offset=348623208448,sizelimit=826658521088 /dev/mapper/sdr /mnt
이는 내 Linux 파티션이 이제 /mnt에 마운트되었으며 ro
읽기 전용 모드에서 모든 파일을 탐색할 수 있음을 의미합니다. 필요한 noload
것은ext4가 쓰기 작업을 수행하지 못하도록 방지.
이제 마지막으로 dd를 사용하여 전체 백업을 수행하겠습니다.
# dd if=/dev/mapper/sdr of=/path/to/backups/raid.img status=progress
원래보다 약간 더 큰 RAID를 어떻게 생성했는지 기억하십니까? 이 기회를 이용하여 이미지를 올바른 크기로 잘라 이 오류를 수정할 수 있습니다. 섹터 수를 바이트로 변환해야 합니다 2441959424*512 = 1250283225088
.
# truncate -s 1250283225088 /path/to/backups/raid.img
이제 fdisk -l
더 이상 크기 불일치에 대한 불만이 없습니다.