Lobsters

NetBSD Playing with disklabels

NetBSD 디스크 레이블 살펴보기

NetBSD 11 x86_64 가상 머신에서 디스크 레이블(disklabel)의 위치와 바이너리 구조를 직접 확인합니다. 헤더 파일과 헥스 덤프를 대조하고 체크섬을 검산한 뒤 파티션 항목을 직접 수정해 disklabel 명령의 출력과 비교합니다.

AI 요약

DOS와 Linux를 주로 써 온 글쓴이가 NetBSD 11 x86_64 가상 머신에서 BSD 디스크 레이블(disklabel)의 구조를 살펴봅니다. 디스크 레이블이 디스크의 어느 위치에 저장되는지부터 확인하고, 헤더 정보와 파티션 테이블의 각 바이트가 무엇을 뜻하는지 헥스 덤프와 시스템 도구의 출력으로 대조합니다.

디스크 레이블 위치 확인

글쓴이는 먼저 매뉴얼 페이지 disklabel(5)와 /usr/include/sys/disklabel.h를 살펴봅니다. 매뉴얼에 나온 getlabelsector()와 getlabeloffset() 값을 확인하려고 작은 C 프로그램을 작성해 실행합니다. 결과는 각각 1과 0입니다. 테스트 디스크의 섹터 크기는 512바이트이므로 레이블은 바이트 오프셋 512, 즉 두 번째 섹터에서 시작합니다.

헤더와 파티션 항목 읽기

레이블 앞부분에는 디스크 종류와 이름, 기하 정보, 하드웨어 관련 값이 들어갑니다. 예시 디스크의 섹터 크기는 512바이트이고 트랙당 63섹터, 실린더당 16트랙입니다. 실린더당 섹터 수는 1,008이며, 전체 크기는 262,144섹터, 즉 128MiB입니다. 회전 속도는 3,600rpm으로 표시됩니다. 글쓴이는 이 중 상당수가 현대 x86_64 환경에서는 오래된 정보처럼 보이며, 실제 값도 0으로 비어 있는 항목이 많다고 설명합니다.

메타데이터 뒤에는 파티션 항목이 이어집니다. 각 항목은 16바이트이며 크기, 시작 위치, 파일시스템 유형 같은 정보를 담습니다. 예시의 파티션 a는 262,144섹터 전체를 차지하고 파일시스템 유형은 4.2BSD입니다. disklabel 명령 출력과 바이트를 직접 읽어 얻은 값이 일치합니다. 출력에는 a와 d만 나타납니다. 글쓴이는 d가 x86_64에서 항상 존재하며 디스크 전체를 가리킨다는 메일 내용을 인용하고, 비어 있는 c 항목은 크기·오프셋·유형이 모두 0이라 표시되지 않는 것 같다고 추정합니다.

체크섬 확인과 파티션 추가

disklabel.h는 체크섬을 파티션을 포함한 데이터의 XOR 값으로 설명합니다. 글쓴이는 레이블의 16비트 값들을 XOR하는 gawk 명령을 실행합니다. 체크섬 필드까지 포함하면 결과는 0이고, 체크섬 필드를 제외하면 1dc6이 나옵니다. 이는 디스크에 저장된 리틀엔디언 값 c61d와 대응합니다.

이후 헥스 에디터에서 아홉 번째 파티션 항목을 직접 작성합니다. 레이블 시작 위치 512바이트, 첫 파티션 항목의 오프셋 0x94, 항목 크기 16바이트를 이용해 시작 위치를 512 + 0x94 + (9 - 1) * 16 = 788로 계산합니다. 파티션 크기는 1,234섹터, 시작 위치는 5,678섹터, 파일시스템 유형은 ZFS로 설정합니다. d_npartitions도 9로 바꾸고 체크섬을 다시 계산해 리틀엔디언 바이트 160f를 기록합니다.

가상 머신을 다시 부팅해 disklabel 출력을 확인하자 파티션 i가 크기 1,234, 오프셋 5,678, 유형 ZFS로 나타납니다. 기존 파티션 a가 디스크 전체를 차지하기 때문에 a와 i가 겹친다는 경고도 출력됩니다. 글쓴이는 직접 디스크 레이블을 수정하고 결과를 확인하는 과정을 통해 구조를 익혔다고 설명하며, 의미를 확신하지 못한 필드는 다음에 더 살펴볼 수 있다고 덧붙입니다.

원문: Lobsters / 번역·요약: Trawling