간단하게 뜯어보는 nbd(network block device)
Posted on 08/15/2011 in tech
nbd는 소켓을 이용해서 저멀리 떨어져있는 기계의 block장치를 현재 컴퓨터의 block장치처럼 쓰게 하는 리눅스의 기능이다.
물론 꼭 저 멀리 떨어져있을 필요는 없으며, 꼭 block장치여야 한다는 법은 없다.
특정한 위치에서 특정한 길이의 데이터를 read하거나 write할 수만 있으면 상관없다.
nbd를 구성하려면 3개의 컴퍼넌트가 필요하다.
- nbd 커널드라이버
- nbd 서버
- nbd 클라이언트
nbd 커널드라이버
커널의 block devices 설정에 포함되어으며, 이 설정을 켜놓으면 /dev/nbd[0-7] 또는 /dev/block/nbd[0-7] 장치로 유저스페이스에 노출된다.
nbd 클라이언트
nbd서버와 연결한 소켓을 nbd device 장치와 연결해주는 역할을 한다.
그외에 블럭장치의 특성(block 장치의 크기, block size, timeout, 등)을 설정해야 한다.
해당 설정은 ioctl 명령 을 참조.
nbd 서버
nbd 드라이버에서 보낸 요청을 처리하는 서버
nbd의 요청은 다음과 같은 형태로 전달된다.
각각의 의미는 다음과 같다.
-
magic: nbd request의 시작. NBD_REQUEST_MAGIC값과 동일해야 한다. 이 값이 틀리면 깨지거나 잘못된 패킷이다.
-
type: 읽기/쓰기 요청의 구분
-
handle: 각 요청을 구분하기 위한 값. nbd_reply에 이 값을 복사해서 응답해야 한다.
-
from: 읽기/쓰기를 시작할 offset
-
len: 읽기/쓰기를 할 길이
쓰기 request일 경우, 위 요청 패킷 바로 뒤에 len에 해당하는 길이의 데이터가 덧붙여 따라온다.
nbd의 요청에 대한 응답은 다음과 같다.
-
magic: nbd reply의 시작. NBD_REPLY_MAGIC값을 채워야 한다.
-
error: 오류 발생시 적절한 errno를 채운다. (보통은 EIO). 에러가 없을 때는 0을 채운다.
-
handle: nbd_request의 handle값을 복사한다.
읽기 request일 경우, 위 응답 패킷을 보낸 후 요청 길이만큼 데이터를 덧붙여 보내면 된다.
위의 모든 값은 모두 Network byte order로 변환해서 처리해야 한다.
자세한건 nbd 홈페이지의 client/server 코드를 참조.
그리고 위의 server/client는 TCP/IP 소켓으로 구현되어 있지만, 리눅스에서 지원하는 SOCK_STREAM 타입의 소켓이라면 어느것이라도 지원된다. (유닉스 도메인 소켓이나 블루투스, IRDA 등등)