Devin.KR

용량과 inode

100분 안팎

학습 목표

제공된 작은 실습 전용 파일시스템에서 블록과 inode 사용량을 각각 확인합니다.

개념

남은 공간에는 두 가지 질문이 있습니다

앱이 파일을 저장하려면 내용이 들어갈 블록과 파일 정보를 관리할 inode가 필요합니다. 많은 빈 파일은 내용이 거의 없어도 inode를 소모합니다. 큰 파일 몇 개는 inode 개수보다 블록을 많이 차지할 수 있습니다. 따라서 디스크에 여유가 있다는 한 문장만으로 저장 가능성을 판단하기 어렵습니다. 같은 data 경로에서 블록과 inode를 각각 조회하고 실제 실패의 errno와 함께 읽는 습관을 만듭니다.

이번 레슨은 제공된 작은 ext4 이미지로 두 자원을 따로 소모해 보는 실습입니다. VM 전체 디스크나 서비스 data를 채우지 않습니다. 이미지마다 새로운 파일시스템을 만들고 한 사례가 끝나면 해제합니다. 실습의 목적은 서비스를 멈추는 일이 아니라 같은 No space left on device가 다른 자원 부족에서 생길 수 있음을 관측으로 구분하는 일입니다. 정상 상태·실패 직후 상태·정리 뒤 상태를 순서대로 남깁니다.

df의 블록과 inode 관측을 읽습니다

df -Pk에 경로를 넣으면 해당 파일시스템의 크기·사용·가용 공간을 1024바이트 단위로 조회합니다. df -Pi는 같은 경로의 inode 전체·사용·여유를 보여 줍니다. 경로를 생략하고 다른 마운트의 여유를 보면 이번 파일 생성 실패와 관계없는 수치를 볼 수 있습니다. 사람이 읽는 반올림 단위만 비교하지 말고 숫자 단위·대상 경로·관측 시각을 함께 기록해 전후 차이를 해석합니다.

inode는 파일의 여러 메타데이터를 관리합니다. inode 하나가 파일 내용의 바이트 하나에 대응하는 것은 아닙니다. 디렉터리 등도 inode를 사용하며 하드링크 여러 개가 같은 inode를 참조할 수 있습니다. 그러므로 빈 파일 개수와 전체 inode 사용량이 처음부터 정확히 같다고 가정하지 않습니다. 실습 이미지에는 파일시스템이 생성한 메타데이터와 lost+found 같은 초기 항목도 있습니다.

Python의 os.statvfs는 같은 자원을 숫자로 읽는 수단입니다. f_blocks는 전체 블록 수, f_bfree는 전체 여유 블록, f_bavail은 일반 사용자가 이용할 수 있는 여유 블록을 나타냅니다. f_files와 f_ffree는 전체·여유 inode를 읽습니다. 블록 하나의 바이트 단위는 f_frsize와 함께 해석합니다. 이번 JSON은 블록 개수 자체를 보존하므로 바이트로 변환한 숫자와 혼동하지 않습니다.

작은 일반 파일만 파일시스템으로 만듭니다

ZIP의 check.sh는 현재 실습 폴더 아래 mktemp로 고유 디렉터리를 만듭니다. 그 안의 32MiB 일반 이미지 두 개에만 mkfs.ext4를 실행합니다. 기존 /dev 경로를 입력으로 받지 않으며 서비스 파일을 옮기지 않습니다. e2fsprogs와 loop 마운트를 지원하는 Linux VM, sudo 권한, 이미지와 관측 파일을 둘 여유가 필요합니다. 관리자 권한은 마운트·해제와 마운트 루트 소유자 설정에만 사용하고 파일 생성은 일반 계정으로 합니다.

포맷 옵션 -N 128은 작은 inode 개수를 요청하고 -b 1024는 블록 크기를 지정합니다. 실제 개수는 생성 규칙에 따라 조정될 수 있으므로 시작 시 statvfs 값으로 확인합니다. -m 0은 이 전용 이미지에서 예약 블록 비율을 없애 두 축의 부족을 단순하게 비교하기 위한 선택입니다. 실제 루트 파일시스템의 예약 공간을 없애라는 운영 지침이 아닙니다. 새 일반 파일 외에는 포맷 명령을 적용하지 않습니다. mke2fs 매뉴얼에서 옵션 정의를 확인할 수 있습니다.

mode.txt는 실습 범위 검토를 마친 뒤 ready로 바꾸는 게이트입니다. 이것만 바꿔서 관측이 성공한 척하지 않습니다. 검사기는 실제로 이미지를 만들고 블록·inode 부족을 재현해야 통과합니다. starter의 review 상태에서 실패하는 이유는 아직 범위를 확인하지 않았기 때문입니다. 스크립트를 먼저 읽고 실습 폴더·필요 도구·정리 방법을 확인한 다음 게이트를 열어 실행합니다.

오류를 일부러 만들고 다른 자원을 비교합니다

블록 사례는 payload 하나에 실제 데이터를 반복해서 씁니다. sparse 파일 크기만 늘리면 블록을 충분히 소비하지 않을 수 있으므로 쓰기 데이터를 사용합니다. 반복에는 최대 128MiB라는 상한이 있고 첫 ENOSPC에서 멈춥니다. 오류 뒤 available_blocks가 0이고 free_inodes가 남았는지 검사합니다. 검사 결과가 반대라면 블록 부족을 재현했다고 보고하지 않습니다.

inode 사례는 다른 새 이미지에서 최대 4096개의 빈 파일을 만듭니다. 파일마다 새로운 이름을 써야 기존 파일을 다시 열어 inode를 재사용하는 실수를 피할 수 있습니다. ENOSPC를 받은 뒤 free_inodes가 0이고 available_blocks가 남아 있는지 검사합니다. 디렉터리 자체에도 블록이 필요하므로 빈 파일이 블록을 전혀 쓰지 않는다고 설명하지 않습니다. 한 축을 먼저 소모한 실제 관측이 핵심입니다.

fill.py는 OSError 중 ENOSPC만 예상 부족으로 인정합니다. EACCES는 계정 권한 문제, EROFS는 읽기 전용 상태, 파일 없음 오류는 경로 문제의 단서이므로 성공적인 부족 실험으로 세지 않습니다. 반복 상한까지 오류가 없다면 assert가 실패합니다. 그 경우 파일시스템 크기·inode 실제 수·쓰기 경로를 확인하며 상한을 없앤 무한 반복으로 바꾸지 않습니다. 실패 보고서는 안전 상한이 지켜졌다는 근거이기도 합니다.

가용 공간과 판정 모델의 차이를 남깁니다

실제 파일시스템에는 일반 사용자에게 남은 공간과 전체 여유 공간의 차이가 있을 수 있습니다. 예약 블록·쿼터·서비스의 접근 정책 같은 조건도 쓰기에 영향을 줍니다. 따라서 전체 블록 대비 사용 비율이 낮다는 이유만으로 계정 쓰기 성공을 보장하지 않습니다. 다음 레슨의 경보 계산은 학습용 전체·사용 모델이며 이번 레슨의 가용 블록과 실제 쓰기 검사가 운영 진단을 보완합니다.

블록·inode 모두 여유인데 생성이 실패했다면 경로의 마운트와 쓰기 계정, 파일과 상위 디렉터리 권한을 이어서 확인합니다. root로만 쓰기가 되는 상황은 bcweb의 정상 상태를 증명하지 않습니다. 미션에서는 실제 서비스 data의 새 임시 파일 쓰기를 bcweb으로 시험하고 권한 실패는 별도 전용 디렉터리에서 재현합니다. 기존 items.json을 빈 파일로 바꿔 쓰기 시험을 하지 않습니다.

trap은 정상·오류 종료 때 마운트를 해제하고 성공한 경우에만 이미지 폴더를 삭제합니다. umount의 target is busy는 사용 중인 경로와 열린 파일을 조사할 단서입니다. 셸이 마운트 안에 머물러 있다면 먼저 바깥으로 이동합니다. 해제 실패 경로는 보존하고 VM 콘솔에서 확인합니다. 강제 종료나 지연 해제로 숨기지 않으며 관측 JSON은 이미지 밖 evidence에 남겨 다음 담당자가 다시 읽을 수 있게 합니다.

성공 조건을 숫자로 설명합니다

제출할 blocks.json과 inodes.json에는 before·after·errno·message가 있습니다. 두 보고서에서 부족한 축과 남은 축을 찾아 설명합니다. VM마다 생성된 메타데이터와 inode 수가 달라질 수 있으므로 특정 전체 숫자를 외우는 대신 부등식과 0 여부를 검사합니다. 실행되지 않은 맥의 output에 Linux 결과를 적지 않습니다. 실제 df 옵션과 추가 진단 사례는 더 읽기의 df 원고를 참조합니다.

따라하기

두 관측축을 먼저 비교

고정 수치는 부족 모델이며 실제 파일시스템 관측과 구분합니다.

for label, free_blocks, free_inodes in [('blocks', 0, 100), ('inodes', 100, 0)]:
    print(label, 'available_blocks='+str(free_blocks), 'free_inodes='+str(free_inodes))

실행 결과

blocks available_blocks=0 free_inodes=100
inodes available_blocks=100 free_inodes=0

실제 data의 두 축 조회

서비스가 설치된 Linux VM에서 같은 경로를 지정해 원문·단위·시각을 보관합니다.

df -Pk /srv/bootcamp-m02/lab-root/data
df -Pi /srv/bootcamp-m02/lab-root/data

전용 이미지 대상 검토

실습 ZIP 안에서 스크립트를 읽습니다. 새 일반 파일 두 개만 포맷하는지, trap·유한 반복·여유 128MiB 조건을 확인합니다.

cat README.md
cat check.sh
cat fill.py
df -Pk .

부족과 해제 검사 실행

검토를 마친 Linux VM에서 게이트를 열어 실행합니다. image 내부 원문과 evidence의 두 JSON을 비교합니다. PASS만으로 설명을 대신하지 않습니다.

printf 'ready\n' > mode.txt
bash check.sh
cat evidence/blocks.json
cat evidence/inodes.json

확인 문제

실습

Linux VM에서 README·check.sh·fill.py의 대상을 검토하고 mode.txt를 ready로 바꿉니다. 새 일반 ext4 이미지에서 블록 부족과 inode 부족을 재현해 evidence의 두 JSON을 제출합니다. check.sh는 ENOSPC·두 축 잔량·유한 반복·해제를 확인합니다. 실행 전 128MiB 이상 여유와 도구·sudo를 준비합니다. 기존 장치·data는 수정하지 않습니다.

시작 코드·테스트 내려받기

실행 명령

bash check.sh

기대 결과

ENOSPC 두 사례의 한 축 부족·다른 축 여유 검사 통과, 마운트 해제, 종료 코드 0

모범 답안모범 답안 내려받기

더 읽기

면접 질문

  • 디스크 용량이 남았는데 파일 생성이 실패한 원인을 설명합니다.