오늘날 스토리지는 대부분 눈에 보이지 않는 곳에서 알아서 동작한다. 그러나 40여 년 전, 고성능·대용량 저장장치의 표준은 지금은 이름조차 낯선 SMD(Storage Module Device) 디스크였다. OpenBSD 개발자 miod가 정리한 이 회고는 단순한 옛 하드웨어 자랑이 아니라, 문서가 부실하고 테스트가 거의 없던 드라이버 코드를 실제 장비 위에서 하나씩 검증해 나가는 과정에 대한 기록이다. 레거시 시스템을 다루거나 저수준 버그를 추적해 본 실무자라면 익숙한 종류의 고생담이다.
SMD라는 물건
SMD 인터페이스는 5년간의 작업을 거쳐 1982년 ANSI X3.91M-1982로 표준화됐고 1987년에 개정됐다. 1980년대에 ESDI(1984년)나 SCSI(1986년) 같은 후발 기술이 등장했지만, 가장 용량이 큰 디스크는 여전히 SMD 인터페이스를 사용했다. 초기에는 11인치, 이후 8인치 플래터를 썼고 회전 속도는 3600rpm, 즉 초당 60회전이 표준이었다(후지쓰는 일부 드라이브를 3961rpm으로 더 빠르게 돌리기도 했다). 이 정도 디스크를 돌리는 데는 상당한 전력이 필요했고, 그 비용은 전기 요금 고지서로 돌아왔다. 무게도 상당해서 11인치 모델은 사람이 옮기기 어려워 운반 도구가 필요할 정도였다.
선 마이크로시스템즈는 자일로직스(Xylogics) 컨트롤러를 얹은 SMD 디스크를 고급 서버와 워크스테이션에 함께 출하했다. 다만 이런 장비가 취미가들의 지하실로 흘러들 무렵에는 이미 대용량 SCsi 디스크가 나와 있었다. 필자는 2000년대 초 Sun-3/260에 2GB짜리 마이크로폴리스 1924 SCSI 디스크를 썼는데, 알려진 한 가장 큰 SMD 드라이브 용량이 약 1.25GB였으니 그 SCSI 디스크의 3분의 2에도 못 미쳤다.
버려진 장비를 되살리기까지
필자가 2000년 OpenBSD/sun3 작업을 시작했을 때는 SMD 드라이브가 없어 자일로직스 드라이버를 시험할 수 없었다. 이 상황은 2001년 여름, 어느 방 구석에서 폐기된 Sun-4/260 캐비닛과 규격이 맞는 SMD 디스크 캐비닛을 발견하면서 바뀌었다. 두 장비를 차 트렁크로 옮길 수 있도록 관계자를 설득하는 데만 1년이 걸렸다고 한다. 이 시스템의 메인보드는 16.67MHz SPARC 프로세서와 FPU를 얹은 9U 크기의 대형 보드로, 온보드 메모리가 없어 최대 4장의 VME 메모리 보드(장당 8·16·32MB)를 P2 전용 버스로 연결해 최대 128MB를 구성했다. 스토리지 컨트롤러 역시 VME 보드로 추가됐고, 슬롯마다 미묘한 차이가 있어 선은 배치와 백플레인 점퍼 설정을 다룬 100쪽 넘는 매뉴얼을 따로 만들 정도였다.
보관함에 있던 두 SMD 디스크는 원시 용량 약 368MB, 포맷 후 280MB에 불과했고 그나마 한 대만 동작하는 듯 보였다. 온보드 이더넷이 고장 나 활용이 제한됐는데, 2011년 스웨덴의 페터 에릭손이 폐기 직전 구해낸 VME 보드들을 동료 개발자가 배송해 준 덕에 인텔 82586 기반 이더넷 보드를 확보해 다시 네트워크에 연결할 수 있었다. 그런데 이때 필자는 그동안 SMD 데이터 케이블을 잘못 연결해 왔다는 사실을 깨달았다. 케이블을 바로잡자 죽은 줄 알았던 두 번째 드라이브가 정상으로 인식됐다.
8216바이트의 함정
문제는 그다음이었다. 2단계 부트 블록이 있는 섹터를 읽으려 하면 PROM 모니터가 뱉는 정체불명의 "xy: error A" 메시지가 떴다. 옛 PROM 모니터에는 디버깅 수단이 거의 없어, 8KB 한계에 걸리지 않도록 1단계 부트로더의 메시지를 한 글자로 줄여 가며 어디까지 진행되는지 추적해야 했다. 원인은 파일시스템 블록 크기였다. 2003년 7월 OpenBSD가 FreeBSD를 따라 기본 블록 크기를 8KB에서 16KB로 바꾸면서, 재설치로 생성된 새 파일시스템의 부트로더가 16KB를 한 번에 읽으려 한 것이다. 그러나 PROM 모니터의 I/O 크기 한계는 8192가 아닌 8216바이트라는 묘한 값이었고, 다행히 그 값은 공개된 데이터 구조에 명시돼 있었다. I/O 요청을 그 한계로 잘라 여러 번 나눠 읽게 하자 부트 블록이 정상 동작했다.
이 사례는 레거시 유지보수의 핵심을 잘 보여준다. "바뀐 게 없다"는 확신이 대개 틀리며, 문제의 실마리는 몇 년 전 무심코 병합된 상위 계층의 기본값 변경에 숨어 있다는 점이다. 부트로더가 단일 I/O로 항상 충분하다고 가정하지 않고 하위 계층이 광고하는 한계를 존중해야 한다는 교훈은 지금의 코드에도 그대로 통한다.
남은 결함과 다음 과제
불량 섹터 처리도 문제였다. 현대 디스크는 컨트롤러가 예비 섹터로 알아서 재배치하지만, SMD에서는 그 관리가 소프트웨어 드라이버의 책임이다. 자일로직스 드라이버의 해당 경로는 거의 시험된 적이 없어 오류 메시지를 쏟아냈고, 파일시스템을 서서히 손상시켜 커널 패닉을 일으키는 미묘한 버그는 이틀 뒤에야 수정됐다. 필자는 이 김에 SMD 디스크에서 disklabel -A 자동 파티셔닝을 지원하는 ioctl 핸들러도 구현했다. OpenBSD와 NetBSD에는 SMD용 저수준 포맷 도구가 없어, SunOS 4.1을 부팅해 그 포맷 프로그램으로 디스크당 한 시간 넘게 저수준 포맷을 돌려야 했다. 그럼에도 CDC 9720 디스크는 불량 섹터가 계속 늘어 결국 2017년 4월 은퇴시켰다. 참고로 이 디스크의 매뉴얼에는 기동 시 순간적으로 최대 6암페어를 끌어 쓴다는 전류 그래프가 실려 있다.
아직 남은 과제는 SunOS용 시프리코(Ciprico) 림파이어(Rimfire) 드라이버를 BSD로 이식하는 일이다. 림파이어 SMD 컨트롤러는 512KB의 캐시 메모리와 적극적인 선행 읽기 덕에 자일로직스보다 훨씬 빨랐고, 시프리코가 드라이버 소스를 공개해 둔 점도 이식을 돕는다. SunOS 4는 DMA 전송을 위한 IOMMU(선의 DVMA) 처리를 빼면 4.2BSD와 매우 가까워 이식이 비교적 수월할 것으로 보인다. 오랫동안 케이블 커넥터가 맞지 않아 손대지 못했지만, 림파이어 3224의 커넥터가 멀티버스 자일로직스 451과 동일하다는 사실을 뒤늦게 깨달으며 실마리를 찾았다. 사라져 가는 하드웨어를 굳이 되살리는 이런 작업의 가치는 결과물보다 과정에 있다. 문서와 테스트가 부실한 코드가 실제 장비 앞에서 어떻게 무너지고 무엇을 통해 복구되는지, 그 구체성이 곧 엔지니어링 지식으로 남는다.