이번 과제, 한 장면으로 이해하기
커널에 붙이는새 파일 관리자.
EXT4 코드를 복사해 PXT4라는 Kernel module로 만들고, 새 디스크에서 파일을 읽고 쓴다.
수업에서 무엇을 가져오면 될까? ↓책을 찾으려면 서가와 목록이 함께 필요하듯, 파일을 찾으려면 저장 공간과 관리 규칙이 함께 필요하다. 이번에는 그 규칙을 실행하는 코드를 준비한다.
파일을 열면, 누가 일할까?
System call은 커널에 요청하는 문. VFS는 그 요청을 파일 시스템에 연결하는 공통 창구다.
같은 요청, 다른 담당자
프로그램은 open(), read(), write()로 요청한다. VFS는 열린 파일이 속한 파일 시스템을 찾아 그쪽 코드를 호출한다.
프로그램은 EXT4의 내부 구조를 몰라도 같은 방식으로 파일을 읽을 수 있다.
수업 연결 · 9/7 Kernel과 파일 I/O · 9/14 파일 I/O와 System call
Function pointer는 함수의 연락처
Function pointer는 호출할 함수의 주소를 담는다. VFS와 공통 I/O 코드는 파일에 연결된 함수 목록을 따라 해당 파일 시스템의 일을 부른다.
/* 흐름만 보여 주는 예시 */
.write_begin = pxt4_write_begin
/* 등록된 함수를 호출 */
a_ops->write_begin(...)실제 파일의 함수 목록이 PXT4 쪽 함수로 연결돼 있어야 한다. 모듈을 넣었다는 사실만으로 모든 파일 요청이 PXT4로 바뀌지는 않는다.
실습 자료 보충 · Practical Class 5, 27–29쪽 · Linux 5.4 VFS 문서
Page cache는 최근 사용한 파일 내용을 메모리에 보관한다. 읽을 내용이 이미 있으면 디스크 접근을 줄일 수 있고, 쓰기도 메모리에 머물렀다가 나중에 디스크에 반영될 수 있다.
PXT4는 파일을 관리하고,
JBD3는 변경을 기록한다.
디스크에는 파일 내용과, 그 내용을 찾고 관리하기 위한 정보가 함께 저장된다.
Filesystem은 파일을 어디에, 어떤 구조로 저장하고 찾을지 정하는 규칙과 코드다. EXT4는 이미 있는 파일 시스템이고, PXT4는 이번 실습에서 그 코드를 복사해 만드는 이름이다.
파일 내용
“안녕”
파일에 실제로 저장한 글이나 사진. 이 내용이 Data다.
관리 정보
크기 · 권한 · 위치
내용을 찾고 다루기 위한 정보. 이런 정보를 Metadata라고 한다.
inode와 block도 지금 알아야 할까?
Block은 파일 시스템이 공간을 나누어 쓰는 단위다. inode는 파일의 크기·권한과 데이터 위치를 찾는 정보를 담는다. 파일 이름은 directory에 기록돼 inode와 연결된다. 지금은 이 역할만 알면 된다.
수업 연결 · 9/14 inode와 extent · 실습 자료 2–3쪽
Journaling은 변경 작업의 기록장
파일 관리 정보를 바꾸다가 전원이 꺼지면 일부만 바뀐 상태가 남을 수 있다. Journal은 기록된 변경을 이용해 복구를 돕는다.
- 관리 정보의 변경을 Journal에 기록한다.
- 기록을 끝냈다는 Commit을 남긴다.
- 변경을 원래 위치에 반영한다.
반영 도중 멈췄다면, 다음 복구 때 완료된 기록을 다시 적용할 수 있다. PXT4는 이 기능을 위해 JBD3를 사용한다.
흐름을 단순화한 설명이다. EXT4 기본 모드의 Journal은 주로 Metadata를 보호한다. 저장 중이던 파일 내용 전체가 항상 보존된다는 뜻은 아니다.
공식 문서 보충 · EXT4 Journal의 기본 원리. 최신 문서의 추가 기능은 이 실습 범위에서 제외했다.
코드를 커널에 붙이는 방법: Module
Kernel module은 따로 빌드해서 실행 중인 커널에 넣을 수 있는 기능 묶음이다.
일반 C 프로그램은 사용자 공간에서 실행된다. Kernel module은 로드된 뒤 커널의 권한으로 실행된다. 실행 파일처럼 ./pxt4.ko로 시작하는 방식이 아니다.
module_init()은 넣을 때 호출할 초기화 함수를 등록하고, module_exit()는 뺄 때 호출할 정리 함수를 등록한다.
사용 중인 파일 시스템은 먼저 unmount해야 제거할 수 있다. PXT4를 제거한 다음, 더 이상 쓰는 모듈이 없는 JBD3를 제거한다.
수업 연결 · 9/14 Module · 9/21 Kernel module
JBD3를 먼저 준비하는 이유
- JBD3를 빌드해
jbd3.ko를 만든다. - JBD3의 공개 함수 정보를 전달해 PXT4를 빌드한다.
insmod로 JBD3를 먼저 로드한다.- PXT4를 로드하고
lsmod로 확인한다.
insmod는 필요한 다른 모듈을 자동으로 찾아 로드하지 않는다. 이 실습에서는 의존 순서를 직접 지킨다.
실습 자료 · 15–17쪽
Makefile은 조립 순서,
Kbuild는 커널의 조립 도구.
여러 C 파일을 모아 현재 커널이 받아들일 수 있는 .ko 파일로 만든다.
Makefile에는 어떤 파일로 무엇을 만들지, 어떤 명령을 실행할지가 적혀 있다. make는 그 규칙을 읽는다. 커널 모듈은 커널의 빌드 시스템인 Kbuild를 사용한다.
Makefile 안에 적는 빌드 대상
obj-m += pxt4.o터미널에서 실행하는 빌드 명령
make -C /lib/modules/$(uname -r)/build \
M="$PWD" modules빌드 방식을 보여 주는 예시다. PXT4 실제 Makefile에는 여러 소스 파일의 목록도 필요하다. -C는 커널 빌드 경로, M은 모듈 작업 폴더를 지정한다.
수업 연결 · 9/21 Makefile · 실습 자료 13–16쪽
이름만 바꾸면 끝일까?
소스 파일 이름뿐 아니라 함수·변수 이름, header의 선언과 경로, Makefile 안의 이름도 맞춰야 한다. Symbol은 함수·변수를 가리키는 이름이다. 다른 모듈에도 공개하는 이름이 기존 EXT4/JBD2와 겹치면 충돌할 수 있다.
Module.symvers는 공개 이름 목록
어느 모듈이 어떤 공개 이름을 제공하는지 빌드 도구에 알려 준다. 과제에서는 JBD3를 빌드한 뒤 이 정보를 PXT4 빌드에 전달한다. 모듈 버전 검사를 켠 경우에는 인터페이스 검사값도 사용한다.
실행 중인 커널에 맞는 소스·설정·빌드 결과를 사용해야 한다. 같은 버전 숫자만 같다고 호환이 보장되지는 않는다. CONFIG_...는 실제 설정을 가리키므로 이름 치환 뒤에도 확인해야 한다.
공식 문서 보충 · Linux 5.4 External modules · 설정 확인은 실습 자료 8–12쪽
포맷은 구조를 만들고,
마운트는 폴더에 연결한다.
새 디스크를 추가하는 것, 파일 시스템을 만드는 것, 사용할 경로에 연결하는 것은 서로 다른 작업이다.
MKFS · 포맷
서가와 목록 만들기
디스크에 EXT4의 저장 구조와 초기 관리 정보를 만든다.
MOUNT · 연결
들어갈 문 정하기
그 파일 시스템의 내용을 /mnt/test 같은 경로에서 보이게 한다.
과제에서는 EXT4 형식으로 포맷하고, PXT4 코드로 마운트한다. 복사한 PXT4가 같은 디스크 형식을 다룰 수 있기 때문이다.
mkfs는 기존 데이터를 잃게 한다. lsblk·fdisk로 새 실습용 디스크를 확인한 뒤 진행한다. 장치 이름이 항상 /dev/sdb인 것은 아니다.
실습 자료 · Practical Class 5, 18–19쪽 · Practical Class 5-b
마운트가 끝난 뒤 보이는 경로
/mnt/test/hello.txt
/mnt/test
새 파일 시스템으로 들어가는 경로
PXT4가 hello.txt의 관리 정보와 내용을 읽는다.
새 가상 디스크
EXT4 형식의 저장 구조
디스크 내용을 폴더로 복사해 온 것이 아니다. 그 경로에 새 파일 시스템을 연결한 것이다.
빌드 성공과 마운트 성공은 어떻게 확인할까?
make성공: .ko 파일을 만들었다.lsmod: 모듈이 커널에 로드돼 있다.mount -l또는findmnt: 디스크가 PXT4로 경로에 연결됐다.- 파일 쓰기·읽기: 연결된 파일 시스템에서 기본 I/O가 동작한다.
dmesg: 커널 메시지와 오류를 확인한다.
각 단계에서 결과를 확인하고 다음으로 넘어간다.
수업 노트는 이 부분부터 읽으면 된다.
이번 실습에 필요한 깊이로 읽고, 바로 해당 작업에 연결한다.
실습 자료 15–17쪽
Linux 5.4 공식 문서
27–29쪽
공식 Journal 문서
Practical Class 5-b
먼저 9/21 노트의 Makefile과 Kernel module 부분을 읽자.
그다음 9/14 노트의 파일 I/O 경로를 이 페이지의 그림과 연결해 보면 된다.
9/28의 Race condition, 10/5의 Spinlock·Mutex는 공유 자료를 수정할 때 연결된다. 이번 복제·빌드·마운트 실습은 위의 개념부터 이해하고 시작할 수 있다. 세부 lock 구현과 scheduler는 필요해질 때 읽는다.
명령을 치기 전에, 네 말로 설명해 보기.
답을 말해 보고 펼친다. 외우기보다 다음 작업의 이유를 이해하면 된다.
왜 JBD3를 먼저 로드할까?
PXT4가 사용하는 저널링 함수를 JBD3가 제공하기 때문이다. 먼저 준비돼 있어야 PXT4가 그 함수를 사용할 수 있다.
PXT4를 넣으면 모든 파일이 PXT4로 바뀔까?
아니다. Module 로드는 기능을 준비하는 단계다. 해당 디스크를 PXT4로 마운트해야 그 파일 시스템의 요청이 PXT4 코드로 연결된다.
포맷했으면 /mnt/test에 파일이 보일까?
포맷은 디스크의 저장 구조를 만든다. 그 내용을 /mnt/test에서 사용하려면 별도로 마운트해야 한다.
이름만 바꾸는 데 왜 header도 수정할까?
C 파일이 부르는 함수 이름과 header의 선언, 파일 경로, Makefile의 이름이 서로 맞아야 한다. 기존 코드와 공개 이름이 겹치는지도 확인해야 한다.
이제 할 일은,
EXT4와 JBD2의 작업용 복사본을 만드는 것.
작은 Kernel module도 별도 제출 항목이다. 파일 시스템 부분을 먼저 진행한 뒤 마무리해도 된다. 실습 자료는 로그·모듈 목록·마운트 결과의 스크린샷을 포함한 PDF를 요구한다.
어디까지가 수업 내용인가?
9/7·9/14·9/21 수업 노트에서 Kernel, 파일 I/O, Makefile과 Module을 연결했다. Journaling, 이름 변경, Module.symvers 전달, Function pointer, 포맷·마운트 절차는 Practical Class 5를 근거로 설명했다. 공식 문서는 원리와 Linux 5.4 빌드 조건을 보충한다.
- 수업 노트: 「리눅스 커널의 역할과 파일 IO 계층」(9/7), 「파일 IO에서 시스템 콜과 커널 구조까지」(9/14), 「Makefile과 커널 모듈부터 fork와 thread까지」(9/21).
- 실습 자료: Making a File System Module, 2–19·27–29·33–35쪽. Creating a new virtual hard disk for VirtualBox, 3–10쪽.
- Linux 5.4 · Building External Modules — Kbuild, Symbol 정보와 호환 조건.
- Linux 5.4 · VFS — 공통 파일 인터페이스와 파일 시스템별 동작.
- Linux Kernel · EXT4 Journal — Metadata 변경과 복구의 기본 원리. 최신 문서의 추가 기능은 다루지 않았다.
Linux 5.4 계열 실습을 기준으로 구성했다. 그림과 비유는 이해를 위한 보충 설명이다. 실제 함수 이름과 설정은 사용하는 커널 소스에서 확인한다.