 |
|
난이도 : 중급 M. Tim Jones, 컨설턴트 엔지니어, Emulex Corp.
2008 년 3 월 04 일 SCSI(Small Computer System Interface)는 (주로 저장 장치와 관련된) 상당히 많은 종류의 디바이스와 통신하도록 인터페이스와 프로로콜을 정의한 표준 모음입니다. 리눅스(Linux®)는 이런 디바이스와 통신을 허용하기 위해 SCSI 하위 시스템을 제공합니다. 리눅스는 CD-ROM 드라이버와 같은 고차원 드라이버에서 시작해 광 채널이나 직렬 연결 SCSI(SAS)와 같은 물리적인 인터페이스에 이르기까지 다양한 장비를 아우르는 계층화된 아키텍처라는 좋은 예를 보여줍니다. 이 기사에서는 리눅스 SCSI 하위 시스템을 소개하고 하위 시스템 발전 방향에 대해 논의합니다.
GNU/리눅스와 SCSI는 각자 환경에서 비슷한 특징이 있기에 자연스러운 한 쌍으로 자리잡았다. GNU/리눅스는 안전하고 신뢰성이 높은 무정지 환경에 적합한 운영체제다. SCSI는 신뢰성이 높고 고성능 저장 장치를 위한 확실한 선택이다. 또한 둘 다 오픈 소스다. INCITS(International Committee on Information Technology Standards)에서 T10 기술 위원회가 만든 다양한 SCSI 명세를 내려받아 읽을 수 있다. 이와 비슷하게, 구현 방식을 이해하기 위해 GNU/리눅스 원시 코드를 내려받을 수 있다. 두 기술 모두 자기 분야에서 두각을 나타내므로 GNU/리눅스는 다른 어떤 운영체제보다 SCSI를 제대로 지원한다.
SCSI 발전 과정
SCSI가 흥미로운 연구 대상인 이유는 오늘날까지 끊임없이 발전 중인 가장 오래된 인터페이스 중 하나이기 때문이다. 첫 SCSI 표준인 SCSI-1은 1979년 경 슈가르트 어소시에이츠가 만들었다. SCSI-1은 5Mhz 자료 클럭을 사용한 8비트 병렬 인터페이스를 정의했으며, 최대 지원 자료 전송률이 초당 5메가바이트(MB/s)였다.
SCSI-2 표준은 1985년에 시작했으며 더 빠른 자료 전송률(10Mhz)과 더 넓은 버스(16비트)로 확장되었다. 패스트/와이드라고 불리는 SCSI-2는 20MB/s까지 자료 전송률을 높였을 뿐 아니라 SCSI-1과 하위 호환성을 유지하기 위해 기존 SCSI-1 자료 전송률도 지원했다.
SCSI-3 개발은 1993년에 시작해 실제로 프로토콜, 명령어 집합, 시그널 처리 방법을 아우르는 표준 집합으로 발전했다. SCSI-3 기술군은 울트라라는 이름이 붙은 병렬 SCSI 표준, IEEE 1394(파이어와이어)와 같은 현대적인 직렬 SCSI 기반 프로토콜, 광 채널, 인터넷 SCSI(iSCSI), 그리고 혜성처럼 등장한 SAS를 포함하는 대가족을 거느리고 있다. 이런 표준은 (FC-AL이나 iSCSI와 같은) 저장 장치 네트워크 기술을 선보이며 저장 장치 지도를 바꿨으며, 자료 전송률을 초당 1기가비트를 능가하도록 확장했으며, 주소 지정 가능한 최대 디바이스 주소 숫자를 100개까지 늘였고, 최대 케이블 길이도 25미터까지 확장했다. 그림 1은 1986년에서 2007년까지 SCSI 규약과 관련한 자료 전송률 발전 단계를 보여준다.
그림 1. SCSI 자료 전송률 발전사
SCSI 디바이스
SCSI는 클라이언트/서버 스타일로 통신 아키텍처를 구현한다. 출발지 디바이스는 목적지 디바이스에 명령 요청을 보낸다. 목적지 디바이스는 요청을 처리해 출발지 디바이스에 결과를 돌려준다. 출발지 디바이스는 호스트 컴퓨터에 있는 SCSI 디바이스이며 SCSI 목적지 디바이스는 디스크 드라이브, CD-ROM, 테이프 드라이버, 인클로저 서비스와 같은 특수한 디바이스가 될 수 있다.
SCSI 명령
SCSI를 전송하는 프로토콜이 여러 해에 걸쳐 변화되어 왔음에도 불구하고 SCSI 명령어 집합은 거의 원래 형식을 그대로 유지하고 있다. SCSI 명령은 CDB(Command Description Block) 내부에 정의되어 있다. CDB는 수행을 위한 특별한 연산을 정의하는 연산 코드와 연산에 밀접한 매개변수를 포함한다.
SCSI 명령은 (각각 변종 네 가지가 있는) 자료 읽기와 쓰기, 그리고 (디바이스 준비를 확인하는) test-unit-ready, (목적지 디바이스에 대한 기본적인 정보를 알아내는) inquiry, (목적지 디바이스 저장소 용량을 알아내는) read-capacity 같은 자료와 무관한 명령어 몇 가지를 지원한다. 목적지 디바이스가 지원하는 특별한 명령은 디바이스 종류에 따라 달라진다. 출발지 디바이스는 inquiry 명령을 통해 디바이스 유형을 인식한다. 표 1은 흔히 쓰는 일반적인 SCSI 명령을 열거한다.
표 1. 일반적인 SCSI 명령
| 명령 | 목적 |
|---|
| Test unit ready | 디바이스가 전송 준비가 되었는지 질문 |
|---|
| Inquiry | 디바이스에 대한 기본적인 정보 요청
|
|---|
| Request sense | 직전 명령어에 대한 오류 정보 요청 |
|---|
| Read capacity | 저장소 용량 정보 요청 |
|---|
| Read | 디바이스에서 자료 읽기 |
|---|
| Write | 디바이스에 자료 쓰기 |
|---|
| Mode sense | (SCSI 디바이스 매개변수를 담고 있는) 모드 페이지 요청 |
|---|
| Mode select | 모드 페이지에서 디바이스 매개변수 설정 |
|---|
WSCSI는 60여 가지 명령어로 (디스크와 같은 임의 접근 디바이스와 테이프와 같은 순차적 접근 저장 디바이스를 포함하여) 다양한 디바이스를 다룬다. SCSI는 또한 (스토리지 내부에 있는 전류와 온도 센서와 같은) 인클로저 서비스에 접근하는 특별한 명령어도 제공한다. 세부 정보를 확인하려면 참고 자료 절을 살펴보기 바란다.
리눅스 커널에서 SCSI 아키텍처
그림 2는 리눅스 커널 내부에서 SCSI 하위 시스템이 위치한 장소를 보여준다. 커널 상위에 시스템 호출 인터페이스가 있으며 이는 (open, read, write와 같은) 커널 내부의 적절한 목적지로 사용자 영역 호출을 전달한다. 가상 파일 시스템(VFS)은 커널에서 지원하는 다양한 파일 시스템을 다루기 위한 추상화 계층이다. VFS는 요청을 적절한 파일 시스템 쪽으로 전달한다. 대다수 파일 시스템은 버퍼 캐시를 통해 통신하며, 이 캐시는 최근에 변경된 자료를 캐시하는 방법으로 물리 디바이스에 대한 접근을 최적화한다. 다음은 블록 디바이스 드라이버 계층으로 하부 디바이스를 위한 다양한 블록 드라이버를 포함한다. SCSI 하위 시스템은 이런 블록 디바이스 드라이버 중 하나다.
그림 2. 리눅스 커널에서 SCSI 하위 시스템이 위치한 장소
리눅스 커널에 들어있는 다른 주요 하위 시스템과는 달리 SCSI 하위 시스템은 뚜렷히 차이나는 세 가지 계층 구조로 되어 있다. 상단에는 SCSI를 위한 커널 최상위 인터페이스와 주요 디바이스 유형을 처리하는 드라이버가 들어있는 상위 단계가 위치한다. 다음으로 공통이나 통합 계층으로 불리는 중간 단계가 있다. 중간 단계에서는 SCSI 스택의 상위와 하위 단계 양쪽을 위한 공통 서비스를 제공한다. 마지막으로 SCSI에 들어맞는 물리적인 인터페이스를 위한 실제 드라이버가 들어있는 하위 단계가 위치한다. 그림 3을 살펴보기 바란다.
그림 3. 리눅스 SCSI 하위 시스템의 계층화 아키텍처
(SCSI 상위 단계, 중간 단계, 엄청난 숫자의 드라이버를 포함한) SCSI 하위 시스템을 위한 원시 코드를 ./linux/drivers/scsi에서 찾을 수 있다. SCSI 자료 구조는 SCSI 원시 코드 디렉터리와 ./linux/include/scsi에서 찾을 수 있다.
SCSI 상위 단계
SCSI 하위 시스템의 상위 단계는 (디바이스 단계) 커널에서 최상위 단계 인터페이스를 대표한다. 이 단계는 (SCSI 디스크나 SCSI CD-ROM과 같은) 블록 디바이스나 (SCSI 테이프나 SCSI 일반과 같은) 문자 디바이스와 같은 드라이버 집합을 포함한다. 상위 단계는 (VFS와 같은) 위쪽에서 들어오는 요청을 받아 이를 SCSI 요청으로 변환한다. 상위 단계는 또한 SCSI 명령을 완료한 상태를 상위 계층에 알려준다.
SCSI 디스크 드라이버는 ./linux/drivers/scsi/sd.c에 구현되어 있다. SCSI 디스크 드라이버는 register_blkdev를 통해 (블록 드라이버로) 자기 자신을 초기화하며, scsi_register_driver로 모든 SCSI 디바이스를 대표하는 공통 함수 집합을 제공한다. 여기서 두 가지 흥미로운 함수는 sd_probe와 sd_init_command다. 새로운 SCSI 디바이스를 시스템에 붙일 때마다, sd_probe 함수는 SCSI 중간 계층에서 호출된다. sd_probe 함수는 디바이스가 SCSI 디스크 드라이버가 관리할지를 결정하며, 그렇다면 이를 표현하도록 새로운 scsi_disk 구조체를 생성한다. sd_init_command는 파일 시스템 계층에서 요청을 받아 이 요청을 SCSI 읽기나 쓰기 명령으로 바꾼다(이런 I/O 요청을 완료하기 위해 sd_rw_intr을 호출한다).
SCSI 테이프 드라이버는 ./linux/drivers/scsi/st.c에 구현되어 있다. 테이프 드라이버는 순차적인 접근 디바이스이며 register_chrdev_region을 통해 문자 디바이스로 자신을 등록한다. SCSI 테이프 드라이버는 또한 st_probe로 불리는 탐색 함수를 제공한다. 이 함수는 새로운 테이프 디바이스를 생성해 scsi_tapes라는 벡터에 추가한다. SCSI 테이프 드라이버는 가능하다면 사용자 영역에서 직접 I/O 전송을 수행한다는 점에서 특이하다. 그렇지 않으면 자료는 드라이버 버퍼를 통해 몇 단계를 거처 전달되어야 한다.
마지막으로 SCSI 일반(generic) 드라이버가 ./linux/drivers/scsi/sg.c에 구현되어 있다. 이 드라이버는 사용자 응용 프로그램이 (포맷, 모드 감지, 진단 명령과 같은) SCSI 명령을 디바이스에 전달하도록 허용한다. sg3utils 패키지를 사용해 사용자 영역에서 SCSI 일반 드라이버를 활용할 수 있다. 이 사용자 영역 패키지는 SCSI 명령어를 전달하고 결과를 해석하는 다양한 유틸리티를 포함한다.
SCSI 중간 단계
SCSI 중간 단계는 SCSI 상위 단계와 하위 단계를 위한 공통 서비스 계층이다(일부 /linux/drivers/scsi/scsi.c에 구현되어 있다). 이 계층은 상위 단계와 하위 단계 드라이버에서 사용하는 여러 함수를 제공하므로 뚜렷히 구분되는 두 계층 구조를 연결하는 접착체 구실을 한다. 이 계층이 중요한 이유는 이 계층이 하위 단계 드라이버(LLD) 구현을 추상화해 일부를 ./linux/drivers/scsi/hosts.c에 구현하고 있기 때문이다. 이는 인터페이스가 다른 광 채널 호스트 버스 어뎁터(HBA)를 동일한 방식으로 사용할 수 있음을 의미한다.
저수준 드라이버 등록과 오류 처리는 SCSI 중간 단계가 제공한다. 중간 단계는 또한 상위 단계와 하위 단계 사이에 일어나는 SCSI 명령 큐 처리 기능을 제공한다. SCSI 중간 단계의 핵심적인 측면은 상위 단계에서 내려온 명령 요청을 SCSI 요청으로 변환하는 기능에 있다. 중간 단계는 또한 SCSI에 밀접한 오류 복구를 관리한다.
중간 계층은 기본적으로 SCSI 하위 시스템의 상위 단계와 하위 단계 사이에서 중간자 구실을 한다. 중간 계층은 SCSI 트랜잭션과 트랜잭션 처리를 위한 큐 요청을 받아들인다(./linux/drivers/scsi/scsi_lib.c). 이런 명령 처리가 끝나면 중간 계층은 LLD에서 SCSI 결과를 받아 요청 완료를 상위 단계로 알려준다.
중간 계층의 가장 중요한 측면 중 하나는 오류와 타임 아웃 처리다. SCSI 명령이 특정 시간 동안 완료되지 않거나 SCSI 요청에 오류가 반환될 경우, 중간 단계는 오류를 관리하거나 요청을 재시도한다. 중간 계층은 또한 HBA(LLD)에 대한 요청이나 SCSI 디바이스 재기동과 같은 고차원 복구를 관리한다. SCSI 오류와 타임 아웃 처리기는 ./linux/drivers/scsi/scsi_error.c에 구현되어 있다.
SCSI 하위 단계
가장 낮은 단계에 SCSI 하위 단계 드라이버라고 부르는 드라이버 집합이 존재한다. 이는 HBA와 같은 물리 디바이스와 인터페이스를 맡는 구체적인 드라이버다. LLD는 공통 중간 계층에서 시작해 디바이스에 밀접한 HBA에서 끝나는 추상화를 제공한다. 각 LLD는 특정 기반 하드웨어에 인터페이스를 제공하지만 중간 계층으로 이어지는 표준 인터페이스 집합을 사용한다.
하위 단계에 속한 코드가 가장 방대한 이유는 다양한 SCSI 어댑터 유형이 있기 때문이다. 예를 들어, 광 채널 프로토콜은 Emulex와 Qlogic에서 나온 어댑터를 위한 LLD를 포함한다. SAS 어댑터를 위한 LLD는 Adaptec과 LSI에서 나온 드라이버를 포함한다.
리눅스와 SCSI 미래
확실한 사실이 하나 있다면 SCSI에는 미래가 있으며 리눅스에 둥지를 틀 것이다. SCSI가 발전함에 따라 리눅스는 최신 발전 속도에 맞춰 지원을 강화할 것이다. 리눅스는 여러 HBA(Host Bus Adaptor)를 위한 드라이버로 새로운 SAS 프로토콜을 지원한다. 프로토콜이 (6Gb SAS나 8Gb FC와 같이) 좀더 빠른 속력을 달성함에 따라 리눅스 역시 개발과 배포 부문에서 선두를 놓치지 않을 것이다.
또한 새로운 SCSI 프로토콜이라는 최첨단 부문에서 리눅스를 찾을 수 있다. 언급하고 넘어갈 중요한 사항 중 하나는 FCoE(Fibre Channel over Ethernet)이다. FCoE는 광 채널 프레임을 (일반적으로 1Gb나 10Gb 이더넷인) 전 이중 이더넷 네트워크 위에 사상하는 방식이다. FCoE가 중요한 이유는 가장 지배적인 엔터프라이즈 저장소 프로토콜을 가장 지배적인 네트워크 매체와 결합하기 때문이다. 이런 새로운 기술은 확실히 주목할 만하며, 여기에는 리눅스가 중심에 있다.
T10이 새롭게 자료 무결성 표준으로 내세운 종단간(End-to-End) 자료 보호 또한 SCSI가 갈 길이다. 이 표준은 매체에 자료 보호를 유지하기 위해 각 섹터별로 자료 무결성 필드(DIF, Data Integrity Field)를 추가한다. 새로운 8바이트짜리 DIF 필드는 CRC(Cyclical Redundancy Code)로 자료를 보호하고, 참조 태그를 붙여 잘못된 쓰기를 방지하며, 응용 프로그램 태그까지 지원한다. 응용 프로그램 태그는 응용 프로그램에 밀접한 정보를 담고 있으며, 예를 들어 PDF 문서 일부처럼 자료 이면에 숨어있는 용도를 정의한다. 세부 정보는 참고 자료 절을 읽어보기 바란다.
정리
리눅스 커널은 추상화된 계층화 아키텍처라는 또 다른 모형을 예제로 보여준다. 리눅스는 본질적으로 다른 파일 시스템을 다양한 물리 저장 매체와 결합한다. 이 저장 매체가 SCSI와 연관이 있을 때, SCSI 하위 시스템은 공통 리눅스 블록 요청을 특정 기반 디바이스를 위한 SCSI 요청으로 변환한다. SCSI 하위 시스템 자체는 여러 해에 걸쳐 수 많은 변화를 겪어 왔고, 여전히 변화하는 중이다. 종단간 자료 보호처럼 새로운 기술은 리눅스에서 갈 길을 찾고 있으며, FCoE와 같은 새로운 프로토콜 역시 마찬가지다.
참고자료 교육
제품 및 기술 얻기
-
DB2®, Lotus®, Rational®, Tivoli®, WebSphere®와 같은 최신 IBM 시험판 소프트웨어를 포함하는 두 장짜리 DVD 세트인 SEK for Linux를 주문하자.
-
IBM 평가판 소프트웨어: developerWorks에서 직접 내려 받아 다음번 프로젝트에 활용하자.
토론
필자소개  | |  | M. Tim Jones는 임베디드 소프트웨어 아키텍트이자 GNU/Linux Application Programming, AI Application Programming, BSD Sockets Programming from a Multilanguage Perspective의 저자이기도 한다. Jones의 공학 배경은 정지 위성을 위한 커널 개발에서 시작해 임베디드 시스템 아키텍처와 네트워크 프로토콜 개발에 이르기까지 다양한 분야를 아우른다. Jones는 콜로라도 주, 롱몬트 소재 Emulex 사에서 컨설턴트 엔지니어로 활약한다. |
기사에 대한 평가
 |
| 이 문서 북마킹 하기
|
|