유저모드에서 파일시스템 드라이버를 만들기
커널 모드에서 코드를 작성한다는 것은 유저모드에서 보다 훨씬 어렵다.
언어도 자유롭게 사용할 수 없고 디버깅도 힘들며 한 줄이라도 실수하면 여지없이 블루스크린이 발생한다.
그럼 디바이스 드라이버를 커널 모드가 아니라 유저 모드에서 구현 할 수는 없을까? 그러면 좀 편할텐데.
리눅스 세상에는 FUSE라는 것이 있다.
File system in User Space 라는 뜻인데, 유저모드에서 파일 시스템을 구현하도록 제공되는 인터페이스이다.
FUSE
가 커널 모드와 유저 모드의 코드를 중재해준다.
윈도우에도 물론 비슷한 것들이 있다.
상용 제품인 CBFS는 콜백 인터페이스를 제공해준다.
유저모드에서 이 콜백 인터페이스를 구현하기만 하면 되는 것이다.
위 그림에서 Your Application
부분만을 구현하면 되는 것이다.
우측에 있는 Callback File System
에서 ReadFile
WriteFile
등 우리가 미리 등록해둔 콜백 오퍼레이션들을 호출해 준다.
한 일본인 혼자서 열심히 만들고 있는 것 같아 보이는 Dokan
이라는 오픈소스도 있다.
네이버의 NDrive
가 이 Dokan
을 이용해서 만들었다.
File System Application
(우측 초록색)이 처음 구동되면 워커 쓰레드를 여러개 만들어 DeviceIoControl 함수를 호출해Dokan File System Driver
(아래 파랑색)에게 집어 넣어놓는다.
DeviceIoControl
함수는 비동기 호출도 가능하고IOCP
도 지원이 되지만Dokan
에서는 간단하게 구현하기 위해서 쓰레드를 여러개 만들어 동기적으로 호출하고 있다.Application
(좌측 초록색)으로 부터 I/O가 들어오면Dokan File System Driver
(아래 파랑색)가 이Irp
들을 받아서 잘 정리한 뒤File System Application
(우측 초록색)이 미리 넣어두었던DeviceIoControl
의 버퍼에 데이터를 복사하고 완료시킴으로 유저모드로 작업을 위임한다.File System Application
에서는 해당 이벤트가 뭔지 확인해본 뒤에 이벤트에 대한 처리를 한 후Dokan File System Driver
에게 다시 그 결과를 전달해준다.- 그러면
Dokan File System Driver
는 받은 결과 그대로Application
(좌측 초록색)의Irp
를 완료시킨다.
이렇게 드라이버가 유저모드의 구현을 위한 인터페이스만을 제공함으로서 파일 시스템 로직 구현을 유저모드로 옮길 수 있으며 유저모드 개발시의 여러 장점들을 가져올 수 있다.
그림에서 보이는 것처럼 두번씩 왔다 갔다 해야하는 것이 성능의 저하를 가져올 수 있고, 유저모드로 구현이 넘어감에 따라 커널 모드 라이브러리 루틴들을 마음껏 쓸 수 없다는 것은 약간의 단점이라 할 수 있겠다.
함께 읽으면 좋은 글: