테코톡을 준비하면서 정리한 자료를 글로 남겨본다. 발표 시간이 짧은 관계로 생략된 부분이 많다.

파일이 뭔데?

  • 컴퓨터를 편리하게 사용하기 위해 저장된 정보에 대한 논리적인 단위다.
  • 파일은 하드디스크나 CD 같은 제2저장장치에 저장된다.
  • 실행 파일과 데이터 파일로 나눌 수 있다.
    • 실행 파일: 운영체제가 메모리로 가져와 CPU를 이용하여 작업하는 파일 예: Windows의 exe, 유닉스의 실행 파일(따로 확장자가 없음)
    • 데이터 파일: 실행 파일이 작업하는 데 필요한 데이터를 모아놓은 파일 예: mp3, png, rar

파일 시스템은 왜 필요한데?

  • 이런 파일들을 어떻게 사용하고 관리할지 고민을 해야됐다.
    • readme.md 파일을 새로 저장하고 싶은데 하드 디스크의 몇 번째 주소가 빈 공간이지??
    • A.mp3 을 재생해서 노래를 듣고싶은데, 이 파일은 하드 디스크의 몇 번 주소에 있지???
    • 헐 뭐야? 누가 내 테코톡_대본.doc 파일 마음대로 삭제했어???
  • 파일 하나를 사용하는데 사용자들이 알고 있어야되는게 너무 많으니 너무 불편하다.
  • 파일 시스템이 이런 파일들을 효율적으로 관리하고, 쉽게 사용할 수 있도록하기위해 만들어졌다.
  • 하지만 파일에 필요한 기능, 성능, 안정성 등 중요하게 생각하는 설계 목표가 달라서 다양한 파일 시스템이 만들어졌다. 심지어 한 운영체제에서 여러 개의 파일 시스템을 사용하기도 한다. 예: FAT, NTFS, APFS, ext

Linux는 어떤 파일 시스템을 사용하는데?

  • 그 전에 Linux가 어떻게 만들어졌는지 알아볼 필요가 있다.
    • 1991년에 리누스 토발즈가 21살(만 나이)의 나이일 때, 운영체제에 관심이 있었다. 그 당시 Minix 라는 교육용 운영체제가 있었는데, 리누스는 마음에 들지 않는 부분이 많았다. 그래서 직접 만들기 시작했다.
    • 그 당시 Linux 개발은 Minix 플랫폼에서 개발되었다.
    • 이 과정에서 Linux가 Minix의 파생품이 아니냐는 논란도 있었다 https://zdnet.co.kr/view/?no=00000010068900
  • Minix 플랫폼 위에서 개발을 진행했기 때문에, Minix와 데이터 교환을 쉽게 하고 싶었다.
  • 따라서 리눅스는 Minix와 호환되는 파일 시스템을 만들어졌다.
    • Minix 파일 시스템을 확장하여 extended file system(extfs)이라고 명명되었다.
    • 성능 향상, 확장성, 기능 추가하여 ext2fs
    • 저널링 기능을 추가하여 ext3
    • 익스텐트(extents) 같은 현대 파일 시스템 기능을 추가하여 ext4

ext의 대표적인 기능들

엄청나게 많은 기능들이 있다. 그 중 일부 기능들을 소개할 것이다.

  • 파일의 할당: 새로 생성할 파일을 디스크에 할당하는 방법
  • 파일의 접근: 사용자가 파일을 열었을 때, 해당 파일의 위치를 접근하는 방법
  • 파일의 보호: 해당 파일에 접근 권한이 있는지 관리하는 방법
  • 파일의 일관성: 파일의 내용이 손상되지 않았도록 보장하는 방법

파일의 할당

  • 파일을 하나 생성했을 때, 파일의 메타데이터와 파일의 실제 내용(데이터)을 디스크에 저장하게 된다.
  • ext에서는 파일의 메타데이터를 inode라는 자료구조로 저장된다. inode에는 파일의 접근 권한, 저장되어있는 데이터의 위치를 가지고 있다. 즉, 하나의 파일은 하나의 inode를 가진다.
  • ext는 디스크를 크기가 같은 여러 개의 블록 그룹으로 나누고, inode에 해당하는 데이터 블록은 같은 블록 그룹에 할당한다.

    Linux%20%E1%84%91%E1%85%A1%E1%84%8B%E1%85%B5%E1%86%AF%E1%84%89%E1%85%B5%E1%84%89%E1%85%B3%E1%84%90%E1%85%A6%E1%86%B7%20%E1%84%87%E1%85%A1%E1%86%AF%E1%84%91%E1%85%AD%20%E1%84%8C%E1%85%AE%E1%86%AB%E1%84%87%E1%85%B5%209a9fc74006f5401586e7e2e2fac3d79d/Untitled.png

  • inode에서 데이터 위치를 저장하는 방법을 자세히 보자.

    Linux%20%E1%84%91%E1%85%A1%E1%84%8B%E1%85%B5%E1%86%AF%E1%84%89%E1%85%B5%E1%84%89%E1%85%B3%E1%84%90%E1%85%A6%E1%86%B7%20%E1%84%87%E1%85%A1%E1%86%AF%E1%84%91%E1%85%AD%20%E1%84%8C%E1%85%AE%E1%86%AB%E1%84%87%E1%85%B5%209a9fc74006f5401586e7e2e2fac3d79d/Untitled%201.png

    • 12개의 direct block, 각각 하나씩 single indirect block, double indirect block, triple indirect block을 가진다.
    • 이런 구조를 가지는 이유가 뭘까?
      • 15개의 direct block로만 이루어져있다고 생각해보자.
        • 원하는 데이터 블록을 찾기 위해, 디스크 참조가 한번만 일어나므로 빠를 것이다. 하지만 파일 하나에 할당할 수 있는 블록의 수가 15개 뿐이다. 블록의 크기가 4KB인 최대 파일크기가 60KB가 될 수 밖에 없다.
      • direct block부터 사용하면서 파일의 크기가커지면서, single indirect, double, triple을 점차적으로 사용한다면,
        • 4KB 블록에 파일 포인터가 32비트(4바이트)인 경우
        • (12 + 1K + 1M + 1G) * 4KB ≈ 4TB
        • 즉, 32비트 파일포인터가 가리킬 수 있는 4GB보다 많은 블록을 지정할 수 있다.
  • 데이터 블록은 저장할 때 저장할 빈 공간을 어떻게 찾지?

    Linux%20%E1%84%91%E1%85%A1%E1%84%8B%E1%85%B5%E1%86%AF%E1%84%89%E1%85%B5%E1%84%89%E1%85%B3%E1%84%90%E1%85%A6%E1%86%B7%20%E1%84%87%E1%85%A1%E1%86%AF%E1%84%91%E1%85%AD%20%E1%84%8C%E1%85%AE%E1%86%AB%E1%84%87%E1%85%B5%209a9fc74006f5401586e7e2e2fac3d79d/Untitled.png

    • 데이터 블록 사용 상태를 나타내는 비트맵이 있다.
    • 이 비트맵에 사용중인 블록은 1로 아닌 블록은 0으로 나타내어 파일 할당시, 빈 블록을 찾게된다.

파일 접근

  • 우리는 파일을 열 때, 1. 어떤 디렉토리에 있는 파일인지 2. 파일의 이름이 무엇인지 를 명시한다. (예시: /main/chess/SpringChessApplication.java)
  • 우리는 ext가 디렉터리를 어떻게 관리하는지 알 필요가 있다.
  • ext에서는 디렉터리도 파일로 관리되고 있다.

    Linux%20%E1%84%91%E1%85%A1%E1%84%8B%E1%85%B5%E1%86%AF%E1%84%89%E1%85%B5%E1%84%89%E1%85%B3%E1%84%90%E1%85%A6%E1%86%B7%20%E1%84%87%E1%85%A1%E1%86%AF%E1%84%91%E1%85%AD%20%E1%84%8C%E1%85%AE%E1%86%AB%E1%84%87%E1%85%B5%209a9fc74006f5401586e7e2e2fac3d79d/Untitled%202.png

  • 디렉토리 inode가 가리키고 있는데 data 블록에 파일의 이름과 inode가 테이블 형태로 저장되어있다.
    • 앞서 말했듯이, 디렉토리도 파일로 관리되고 있다고 했으므로, 디렉토리가 디렉토리를 가지고 있는 형태도 가능하다.
  • 이런 방식을 통해 한 파일 시스템에 있는 수많은 파일들을 분류하여, 쉽게 찾을 수 있게되었다.
  • 하지만 서로 다른 디렉터리에서 하나의 파일을 공유하고 싶을 때가 있다.
  • 그래서 생긴 개념이 링크다.
    • 링크에는 하드 링크와 심볼릭(소프트) 링크가 있다.
    • 심볼릭 링크: 심볼릭 링크는 추가하면 별도의 파일이 생성되며, 내부에 원본 파일의 경로가 저장되어있다. 쉽게 생각할 수 있는 예로 (Windows의 바로가기).
    • 하드 링크: 원본 파일을 그대로 참조하고 있는 링크로, 원본과 동일한 inode를 가진다. 즉, 하드 링크는 원본 파일과 구분이 불가능하며, 하드 링크 추가되면 디렉터리 블록에 원본 파일명과 원본 inode가 추가된다. 하지만 하드 링크는 순환 참조 문제 때문에 디렉토리의 하드링크는 막혀있다.
  • 다시 본론으로 돌아가서, /main/chess/SpringChessApplication.java 같이 디렉터리 경로와 파일명으로 파일을 열게되면
    • 디렉터리 구조를 통해 해당 파일의 inode를 찾은 다음에 파일을 연다.
    • 이런 과정은 잦은 디스크 접근으로 느릴 수 있기때문에, 디렉터리 구조의 일부를 메모리에 캐싱시킨다.

파일의 보호

  • Linux에서는 파일의 접근권한을 2가지 방법으로 관리한다.
    • ACL: 접근 제어 리스트(access-control list)로 누가 어떤 연산을 할 수 있는지 리스트 형식으로 관리한다.
      • 누가: 유저 또는 그룹
      • 어떤 연산: read, write, execute
      • 장점: 정교한 접근 권한을 설정할 수 있다.
      • 단점: ACL은 가변적이 데이터기 때문에 inode내에서 관리하기 힘들다.
    • 접근 권한 비트: 파일의 접근권한을 고정적인 길이의 9비트로 관리한다. 3비트씩 각각 소유자, 그룹, 기타의 읽기, 쓰기, 실행 권한을 나타낸다.
      • 디렉터리에서 read, write, execute의 의미?
        • read: 디렉터리 내에 파일의 리스트를 읽어야될 때 필요한 권한
        • write: 디렉터리 내에 파일을 추가또는 삭제할 때 필요한 권한
        • execute: 디렉터리를 열 때 필요한 권한

파일의 일관성

  • 인생은 변수 그 자체다. 파일 시스템에 파일을 생성하거나, 파일을 쓸 때 디스크에 전원이 꺼질 때도 파일 시스템을 계속 사용할 수 있는 상황이어야 된다.
  • 간단하게 파일을 생성하다가 디스크에 전원이 꺼지면 어떤 문제가 생기는지 생각해보자.
    • inode를 새로 할당했지만, 데이터 블록을 기록하지 않은 경우: inode가 가리키고 있는 데이터 블록에 쓰레기값이 존재해 문제가 발생한다.
    • 데이터 블록 비트맵을 업데이트 했지만, inode가 이 데이터 블록을 가리키지 않는 경우: 아무 파일도 해당 블록을 사용하고 있지 않지만 계속 데이터 블록이 할당되어있는 문제가 있다.
  • 이 문제를 해결하기 위해 리눅스에서는 두 가지 기능을 제공하고 있다.
    • fsck(The File System Checker)로 이런 파일에 불일치가 있는지 확인하는 검사기의 기능을 제공한다. 문제가 있을 때 복구가 가능한 경우에는 복구도 해줄 수 있다. 검사 내용은 엄청나게 많은데 간단하게 어떤 내용이 있는지 일부만 살펴보자.
      • Free blocks: inode가 가리키고 있는, direct block, indirect block을 스캔하고 데이터 블록 비트맵을 비교하여, 불일치 하는 내용이 있는지 확인한다.
      • Duplicate: 서로 다른 inode가 같은 데이터 블록을 가리키고 있다면, 둘 중하나의 inode를 삭제하거나 사본을 만들어 inode마다 각각 다른 데이터 블록을 가리키도록 만든다.

        하지만 이런 fsck는 루트 디렉터리로부터 시작해 모든 디렉터리를 스캔해야되기 때문에 상당히 느리다는 단점이 있다. 또한 파일의 일관성이 깨졌는지 검사는 가능하지만 복구가 불가능해서 무의미한 상황도 있을 수있다. 이를 개선하기 위해 오늘날에는 저널링이라는 기법을 사용한다.

    • Journaling: 애초에 파일의 일관성이 깨지는 일이 발생하지 않도록 하는 기능이다. 이 기능은 파일에 연산을 수행할 때, inode나 비트맵 같은 메타데이터의 변경이 있다면 로그를 남긴다. 이 연산의 집합을 하나의 트랜잭션이라고 부른다. (맞다. 이 기능은 데이터베이스의 트랜잭션과 유사하다.) 한 트랜잭션의 로그들이 모두 기록이 되면 확약(commit)된 것으로 간주하고 실제 메타 데이터의 변경을 시작한다.
      • 로그를 작성하는 중간에 크래시가 발생하는 경우: 파일시스템에 반영된 것이 아니기 때문에 파일의 일관성이 깨지지 않았다.
      • 확약(commit)된 트랜잭션을 파일 시스템에 기록하는 중에 발생하는 경우: 로그에 기록된 내용을 바탕으로 다시 작성하여 복구가 가능하다.

하나의 PC에 여러개의 저장 장치가 있다면?

  • 하나의 물리적인 저장 장치를 여러 개의 논리적인 저장장치로 나누는 파티션이라는 개념이 있다.
  • 하나의 컴퓨터에는 여러 개의 저장 장치를 연결할 수 있다.
  • 파일 시스템은 한 개 이상의 파티션을 묶어 하나의 파일 시스템으로 사용할 수 있다. 즉, 하나의 저장 장치 안에 여러개의 파일 시스템이, 또는 여러개의 저장 장치를 묶어 하나의 파일 시스템을 가지게 할 수 있다.
  • 이런 파일 시스템들을 하나의 디렉터리 구조로 연결 할 수 있는데, 이것을 마운트라고 한다.

준비하면서 생긴 의문점 정리

  • Unix와 Unix-like 의 차이점이 무엇인가?
    • https://upload.wikimedia.org/wikipedia/commons/7/77/Unix_history-simple.svg
    • Unix-like는 유닉스가 아님에도 기능적으로 유닉스 규격에 호환되어 유닉스의 대체품으로 쓸 수 있는, 유닉스와 비슷한 운영 체제를 말한다.
    • 리눅스는 UNIX가 아니기에, 리눅스재단에서도 UNIX 표기는 쓰지 않으며, 소스코드또한 유닉스와 별개이기에 리눅스 운영체제는 항상 Unix-like로 분류된다.
    • 애플의 macOS는 유닉스 운영체제이기에 Unix-like가 아니라 항상 UNIX로 분류된다.
  • ACL은 가변적인데 어떻게 inode에 저장하나?
    • Extended attributes라고 추가적인 메타데이터가 필요한 경우 한개의 inode를 더 할당할 수 있다. 거기에 ACL을 저장한다.
  • ACL과 접근 권한 비트의 내용이 상충되면 어떻게 되는가?
  • inode와 데이터 블록을 같은 블록 그룹에 할당하는 이유가 무엇인가?
    • 하드디스크의 물리적인 특성 때문에 디스크를 접근할 때 서로 가까운 위치에 있는 블록들을 순서대로 접근하는 것이 속도가 빠르다. 자세한건 디스크 접근 시간에 관련하여 공부하면 좋다.
    • 따라서 ext에서는 파일을 할당할 때 최대한 하나의 블록 그룹에 할당하려고 한다.
  • super block은 무엇인가?
    • 파일 시스템에 대한 정보를 담고있다. 파일 시스템에 몇 개의 아이노드와 몇개의 데이터 블록이 있는지, 아이노드 테이블은 어디에서 어디에서 시작하는지 같은 정보를 담고있다.
  • 로그를 작성하는 중에 크래시가 발생하면, 어떻게 되는가?
    • 로그 작성 시작전과 로그 작성 후에 각각 특별한 자료구조를 기록한다. 이 시작과 끝이 보이지 않으면 그 기록한 부분을 그냥 쓰레기 값으로 보고 그냥 넘어가게 된다. 즉 파일 시스템에는 아무 영향을 주지 않았으므로 파일의 일관성은 유지된다.
  • 파일 시스템이 크래시가 발생했는지 어떻게 확인하고 복구하나?
    • 운영체제가 부팅이되면 저널영역을 탐색해서 남아있는 트랜잭션이 있는지 확인하는걸로 알고있다. 자세한건 OSTEP의 저널링 부분을 참고하면 좋을거같다.
  • 만들수 있는 커넥션의 수를 찾을 때 왜 파일의 개수를 찾아야되는가?
    • 이 내용을 설명하자면 내용이 너무 깊어져서 생략했었다.
    • 사실 리눅스 파일 시스템은 여러개의 레이어로 구성되어있다.
    • 그중 vfs는 여러 유형의 파일 시스템을 자연스럽게 하나의 파일 시스템처럼 사용할 수 있도록 구현되어있다. 그래서 리눅스 내에 proc이라는 특별한 파일 시스템을 사용하는데, 여기는 각 프로세스에 대한 정보를 파일로 관리하고 있다.
    • 소켓은 파일 디스크립터로 연결되어 관리되는데 각 프로세스에 대한 파일 디스크립터도 proc에서 관리된다.
    • 파일 디스크립터는 파일에 접근하는데 사용되는 추상화된 개념이다.

참고자료

Abraham Siberschatz, Peter Baer Galvin, Greg Gagne(2020). 운영체제. 퍼스트 북.

조성호(2018). 쉽게 배우는 운영체제. 한빛아카데미.

Stephen Shankland(2004). 리누스 토발즈는 정말 리눅스를 창작했을까?. 2020. 05. 19. 검색, https://zdnet.co.kr/view/?no=00000010068900

위키피디아. 아이노드. 2020. 05. 19. 검색, https://ko.wikipedia.org/wiki/아이노드

rocksea. [inode] inode 관련자료. 2020. 05. 19. 검색, https://rocksea.tistory.com/20 Remzi Arpaci-Dusseau(2020). Operating Systems: Three Easy Pieces. 홍릉.

댓글남기기