Section 4. 파일 시스템

4.1 파일 시스템이란?

파일 시스템이란 애플리케이션이 스토리지에 데이터를 읽고 쓸 때 이를 중개하는 커널 서비스 중 하나이다.

애플리케이션 또는 사용자가 애플리케이션을 매개로 특정 데이터를 읽어 들이는 지시를 내렸을 때 애플리케이션은 시스템 콜을 이용해 데이터를 불러온다. 시스템 콜을 이용해 스토리지에서 데이터를 읽어들이는 과정 중간에 파일 시스템이 들어간다.

출처 : http://slideplayer.com/slide/7986042/

컴퓨터는 CPU, 메모리, 스토리지(HDD나 SDD, USB메모리나 SD카드 등) 등으로 구성되어 있다. 이 중에서 메모리는 전원이 꺼지면 내용이 휘발되어 영속적인 기록이 불가능한 기억 장치이다. 따라서 전원을 끌 때마다 보조 기억 장치에서 내용을 불러와야만 한다.

스토리지는 용량이 크면서도 메모리와 비교하면 가격이 싸지만, 읽기와 쓰기가 모두 느린 편이다. 스토리지의 용량이 점점 커지면서 원하는 데이터를 찾아 취득하는 처리 방법을 개선해야 할 필요성이 생겼고 사용자가 이 스토리지를 '관리'하기 위한 어느 정도의 구조도 필요해졌다.

파일 시스템은 스토리지 안의 데이터를 간단히 검색할 수 있는 알고리즘으로, 사용자의 디렉터리와 파일 등의 관리를 돕고, 디스크 캐시를 이용한 비동기 쓰기로 처리 속도를 향상시키며, 퍼미션을 통해 액세스 권한 관리 등을 수행함으로써 멀티 사용자 시스템을 구현하고 있다. 파일 시스템의 종류에 따라 취급하는 파일 크기나 파일 시스템 자체의 크기도 각각 다르다.

리눅스에서는 여러 파일 시스템을 선택해 이용할 수 있다. 이 책 기준에서 최근 리눅스 배포판의 경우 주류는 ext4이다. 참고로 구동 중인 리눅스 시스템이 이용할 수 있는 파일 시스템은 cat /proc/filesystem로, 리스트로 표시할 수 있다.

리눅스에서는 여러 종류의 파일 시스템을 사용하지만, 애플리케이션은 이들 파일 시스템의 차이를 따로 고려하지 않는다. 따라서 커널에서는 이 차이를 없애고 접근 방법을 획일화하기 위한 VFS(Virtual File System)를 제공하고 있다.

리눅스 커널은 시스템 콜로 파일이나 디렉터리에 대한 액세스 방법을 애플리케이션과 프로세스에 제공한다. 따라서 파일 시스템에 따른 액세스 방법의 차이는 모두 리눅스 커널이 해결해준다.

VFS는 파일 시스템을 통괄하여 애플리케이션의 읽기, 쓰기를 중개한다. 그리고 그 외에 비동기 쓰기도 지원하고 있다. 스토리지 액세스는 메모리보다 시간이 오래 걸리게 되는데, VFS는 파일 시스템에 대한 실제 쓰기의 일부를 메모리 버퍼 캐시에 기록하여 애플리케이션에는 쓰기를 완료했다고 보고함으로써 '빠른 것처럼 보이게 하는' 처리도 한다.

최근 리눅스 배포판이 채택한 파일 시스템에는 저널 파일 시스템이라는 기능이 있다. 이 저널 파일 시스템은 스토리지에 쓰기를 하는 도중 충돌 등으로 쓰기를 완료하지 못한 상황이 발생했을 때에 대처하려는 것이다.

애플리케이션에서 파일 시스템에 데이터 쓰기 명령이 내려오면 파일 시스템은 장애 발생에 대비하여 데이터 중 메타 데이터를 저널이라고 부르는 영역에 기록하고 그 뒤 메타 데이터와 데이터 본체를 합친 데이터를 스토리지에 기록한다. 그리고 그 후에는 저널에 썼던 메타 데이터를 삭제한다. 이 흐름을 처음부터 끝까지 완성하지 못하는 한 스토리지에 데이터가 기록되지 않도록 함으로써 장애 시 파일이 미갱신되는 경우가 발생하더라도 파일이 유실되지 않도록 한다.

4.2 파일 시스템의 구조

파일 시스템은 데이터의 관리나 효율성을 높이고자 자신의 상태를 파악해야만 한다. 데이터를 배치해 이용하는 영역, 미사용 영역, 파일 위치, 디렉터리 위치 등을 파악해 두어야 한다. 이들은 메타 데이터로 기록된다.

관리를 위한 데이터인 메타 데이터, 데이터의 집합인 파일, 파일의 집합인 디렉터리를 실제 스토리지와 함께 살펴볼 것이다.

데이터를 스토리지에 저장할 때 파일 시스템이 1bit, 1byte씩 읽고 쓴다면 퍼포먼스가 나빠지기 때문에 어느 정도의 크기로 묶어서 처리한다. 이 때의 용량을 블록 사이즈라고 한다. 파일 시스템은 읽기, 쓰기에 고정 길이(일정 단위)의 블록 사이즈를 사용한다. 예를 들어 한 블록이 4096byte(4KB)라고 하고 3000byte를 기록할 때, 이 한 블록의 3000byte만큼에는 데이터가 쓰이고 나머지 1096byte는 공백이 된다. 4100byte의 데이터를 기록한다면 두 블록을 사용하게 되며 남은 4092byte의 공백이 생긴다.

ext4에서는 최소 블록 사이즈가 1024byte(2^10), 최대 블록 사이즈가 65536byte(2^16)로 설정되어 있다. 대부분의 리눅스 배포판에서는 ext3, ext4의 파일 시스템의 경우 한 블록에 4096byte(2^12)로 설정되어 있다. 각 파일 시스템의 블록 사이즈는 해당 파일 시스템을 생성할 때 옵션으로 지정한다.

참고로 스토리지 등의 디바이스는 이 '블록'을 직선으로 나열된 이미지의 형태로 취급하기 때문에 블록 디바이스라고 부른다.

16777216은 4096^2이다.

다음은 ext4 파일 시스템의 블록 레이아웃이다.

Group 0 Padding

x86 부트 섹터나 그 외의 정보가 있는 곳. ext4 파일 시스템의 커널 드라이버는 먼저 Group 0 Padding을 보고 파일 시스템의 Super Block과 Group Descriptor를 찾는다.

ext4 Super Block

파일 시스템 관리용 총 i-node 수, 총 블록 수, 빈 블록 수, 빈 i-node 수, epoch 마운트 시간, 가장 마지막으로 파일 시스템 체크를 한 시점부터 경과한 개월 수 등 관리 데이터가 포함되어 있다. 참고로 epoch는 '에포크'라고 읽으며 Unix epoch 시간인 1970년 1월 1일 오전 0시(UTC)를 기준으로 하여 그 후 시간을 초 수로 나타내는 것이다.(윤초는 세지 않는다)

Group Descriptors

파일 시스템 내의 블록 여러 개를 그룹으로 묶어 각 기술자(descriptor)를 관리하는 부분이다.

Reserved GDT Blocks

파일 시스템의 크기 변경을 고려하여 향후 그룹 디스크립터를 저장하려고 예약해두는 영역이다.

Data Block Bitmap, inode Bitmap

특정 데이터 블록이나 inode의 이용 가능 여부를 1bit로 0과 1로 표현하는 것이기 때문에 'Bitmap'이라는 이름이 붙었다.

inode Table, Data Blocks

inode Table은 실제 데이터가 들어가는 Data Blocks 안에 있는 inode의 정보가 저장된 테이블이다. inode파일과 디스크 영역의 관련 내용을 정리한 것이다. inode는 퍼미션, 파일 종류, 소유자의 사용자 ID, epoch 시간 기준 가장 마지막 액세스 시간, epoch 기준 가장 마지막에 데이터가 갱신된 시간, epoch 기준 삭제된 시간, 사용자 데이터 블록 수 등을 담고 있다. 이들 정보는 stat으로 일부를 확인할 수 있다.

4.3 파일 시스템을 조작하는 커맨드

다음은 e2fsprogs패키지에서 파일 시스템 조작 도구 목록이다. 구체적인 사용법은 이 책에서는 다루지 않는다.

4.4 커널, 라이브러리, 애플리케이션

라이브러리는 Library답게 다른 애플리케이션이 이용하는 함수가 들어 있는 곳이다. 필요할 때마다 꺼내쓸 수 있다.

라이브러리를 읽어들여 실행하는 프로그램을 동적 프로그램이라고 한다. 동적 프로그램인지, 어떤 라이브러리를 읽어들이고 있는지는 ldd로 확인할 수 있다. 어떤 프로그램을 설치했을 때, 필요한 라이브러리가 설치되지 않아 프로그램을 실행할 수 없는 경우에는 이 명령어로 체크해본다. 라이브러리 패스에 'Not Found'가 표시되면 필요한 라이브러리가 설치되지 않았다는 뜻이다.

실행 파일과는 별도로 공유 라이브러리를 사용하지 않는, 즉 라이브러리를 가진 실행 파일을 정적 프로그램이라고 한다. 정적 프로그램은 라이브러리 코드가 프로그램에 들어있어 용량은 크지만 배포는 용이하다. 이 경우 ldd로 파일 인수를 지정하면 "동적 실행 파일이 아닙니다."라는 한 행만 표시된 후 커맨드가 종료된다. 실제로 시도해 보려면 ldd/bin/busybox 등을 실행해본다.

여기서 예로 든 busybox는 여러 개의 UNIX 도구를 이용하는 라이브러리까지 포함하여 하나의 바이너리 파일로 정리한 도구이다. 문제 발생 시 자주 사용하므로 시간이 날 때 사용법을 익혀 두도록 한다.

results matching ""

    No results matching ""