센로그

13. File-System Interface 본문

CS/운영체제

13. File-System Interface

seeyoun 2023. 12. 6. 10:52

◆ 요점 정리

1. 파일 attributes

  • name, identifier, type, location, size, protection, time stamp, user identification ...
  • 얘도 디스크에 저장되어 있음. (not OS)

 

2. 파일 operations

  • create, open, write, read, seek, delete, truncate(내용만 삭제하고 속성은 남겨둠)
  • open-file table을 통해 재접근 시 낭비 방지
    • system-wide open-file table
      • FCB 카피
      • open count : 이 파일을 오픈한 프로세스 개수
    • per-process open-file table
      • system-wide open-file table의 항목을 가리키는 포인터
      • 프로세스 별 read/write 포인터 위치나, 프로세스별 접근 모드

 

3. 파일 locking

  • shared - exclusive lock
  • mandatory lock, advisory lock

 

4. 파일 type

  • Windows: 파일 이름 뒤 확장자를 사용해 타입 인코딩
  • UNIX: 파일 내용 안에 타입 인코딩

 
 

5. 파일 접근 방법

  • Sequential access: 포인터가 가리키고 있는 위치부터 순차 접근
  • Direct access: 접근하고 싶은 위치 지정해서 접근
  • Index access: 레코드에 대한 index 탐색 → 파일에 접근

 

6. 디렉토리 구조

  • Single-Level Directory: 모든 파일들이 단일 계층의 디렉토리 밑에 있음 
  • Two-Level DIrectory: 사용자별로 다른 디렉토리 사용 
  • Tree Structured Directory: 루트에서 시작해서 트리 구조로 디렉토리 관리
    • 트리 구조인 만큼 순환 없음
    • 각 파일이 고유한 경로를 가짐
  • Acyclic Graph: 비순환 그래프 
    • 한 파일에 여러 경로로 접근 가능
  • General Graph: 순환을 허용하는 그래프
    • 가비지 컬렉션 제공

 

7. 보호

  • 모드: r/w/x
  • 사용자 클래스: owner, group, public(others)

 

8. Memory-mapped 파일

파일을 프로세스의 가상 메모리에 매핑해놓고 쓰는 방식

 


◆ File

OS는 편의를 위해 저장된 정보에 대한 일정한 논리적 view를 제공한다.
이를 통해 해당 저장 장치의 물리적 속성을 추상화함.
 

  • 파일: 논리적인 저장소의 단위
    • 유저나 애플리케이션이 데이터를 저장하고 얻기위한 방법
    • Non-volatile : 일반적으로 비휘발성 보조기억장치에 저장되므로, 전원 공급 없이도 보존됨
    • 종류가 프로그램(소스 파일이나 오브젝트 파일)일 수도 있고, 데이터일 수도 있다.

 
 
파일은 직접 만들 수도 있고, 프로그램에서 파일을 열어서 만들 수도 있음.
 
파일 내용은 만드는 사람이 결정함. 다양한 유형의 파일이 있다.

  • 텍스트 파일: character들의 연속
  • 소스 파일: function들의 연속
  • 실행 가능한 파일: 코드 섹션들의 연속

 


◆ File Attributes

파일에는 일반적인 데이터 외에도, Attribute라는 메타 데이터들이 저장되어있음
 
어떤 Attribute들이 있을까?

  • Name (이름): 사람이 읽을 수 있는 형태로, 사람이 파일을 구분하기 위한 정보
  • Identifier (식별자): 파일 간의 유일한 식별자(숫자). 컴퓨터가 파일을 구분하기 위한 정보
  • Type (종류): 다양한 종류의 파일을 지원하기 위해 필요함.
  • Location: 파일 저장 위치
  • Size: 파일 크기
  • Protection: 파일 접근 권한에 관한 것. 파일을 읽거나/쓰거나/실행할 수 있는지 없는지에 관한 권한을 제어하기 위함
    ex) 관리자 권한이 없으면 읽지 못하는 파일도 있음
  • Timestamps and User identification: 언제 마지막으로 수정했는지, 어느 유저에게 속하는 건지

 

  • 이런 파일의 메타 정보들이 directory 구조에 담겨있으며, 실제로는 “disk 위에” 저장되어있다.
    OS에 저장되는 게 아님! OS는 디스크로부터 정보를 불러와서 보여주는 거
  • 위 attribute들 이외에도, checksum 처럼 파일의 내용이 변했는지 안 변했는지를 체크하는 방식의 attribute도 있을 수 있다

 


◆ File Operations

다음은 파일에 관한 operation들이다.

  • Create
  • Open
  • Write: write 포인터가 가리키는 부분에 가서 데이터를 쓴다.
  • Read: read 포인터가 가리키는 부분의 데이터를 읽는다.
  • Seek : 읽고 싶은 위치로 포인터를 이동하는 것.
  • Delete: 파일 자체를 삭제(파일 내용 및 attribute 포함)
  • Truncate: 파일의 내용만 삭제(attribute는 삭제 안 함)

 
대부분의 파일 operation들(create나 delete 제외)은 지명된 파일과 관련 디렉토리를 찾는 작업을 한다.
 
따라서 반복 탐색을 피하기 위해 많은 시스템들은 파일을 사용하기 전에 open() 시스템 콜을 하도록 한다.

  • 파일 open 시, 운영체제는 open-file table의 항목으로 해당 파일의 정보(FCB, open count 등)를 저장함.
    파일 재접근시 이 테이블을 사용하여 낭비를 줄임.
    • open count: 열려있는 파일의 수를 나타내는 카운터. 
  • 파일 close 시, 운영체제는 항목을 open-file table에서 삭제함

 

■ Unix/Linux System Calls

Unix나 Linux에서는 파일 operation들을 시스템 콜로써 지원한다.
  • open: 오픈 파일을 구분하기 위한 identifier.
  • chmod: permission등에 관한 모드를 바꾸는 것. Change mode
  • chown: 파일의 주인을 바꾸는 것. Change Owner
  • flock: 파일의 락 관련

 

  • 프로그래밍 언어들에서는 Unix/Linux의 시스템 콜을 기준으로 라이브러리를 만들어서 사용한다.
  • 보통 언어들마다 기본적으로 제공하는 라이브러리 안에 이런 파일 operation들을 platform independent하게 사용할 수 있도록 인터페이스로 잘 만들어 두었다. fstream, open 같은 거. 
  • 언어에서 제공하는 인터페이스는 같지만, 그 내부는 운영체제마다 다르게 구현이 된다.
    왜냐하면 시스템 콜이 운영체제 마다 다르기 때문.
 

◆ File Locking

File은 multiple-reader, single-writer이어야 한다.
읽기는 여러 명이 동시에 할 수 있지만, 쓰기는 혼자서만 해야 한다는 뜻.

 
따라서 file에도 다른 프로세스들의 접근을 막을 수 있는 lock 기능이 필요하다.
 
OS나 파일 시스템이 lock을 지원해준다.
전에 배웠던 reader-writer lock과 비슷하게, shared-exclusive lock이 있다.

  • Shared lock : 여러 프로세스의 동시 접근 허용. reader lock과 유사
  • Exclusive lock : 한 프로세스만 접근 가능하도록 함. writer lock과 유사

 
락을 제공하는 방식에도 두 가지가 있다.

  • Mandatory lock : OS가 락 기능을 강제적으로 제공함. OS가 자동으로 락이 되도록 보장하는 것
  • Advisory lock : OS가 락 기능을 제공해주긴 하는데, 자동으로 해주는 건 아님. 개발자가 직접 락을 요청해야 함.
    (시스템 콜을 통해서 파일 락 요청 하고, 다 쓰면 free 하는 방식.)

 


◆ File Types

파일은 다양한 타입들이 있다.

  • Understood by file systems (파일 시스템이 알고 있는 파일들)
    : OS가 해당 파일이 어떤 파일인지 알고 있는 경우
    → device, directory, symbolic link, etc
  • Understood by other parts of OS or runtime libraries (운영체제의 특정 파트 혹은 런타임 라이브러리나 사용자와의 약속에 의해 만들어진 파일들)
    : OS가 완전히 알지는 못하지만, OS와 가까움
    → executable, dll, source code, object code, text, etc.
  • Understood by application programs (어플리케이션 사용자가 정해둔 파일들)
    : 해당 프로그램을 커널에 등록하면 OS가 인식할 수 있음.
    → jpg, mpg, avi, mp3, pptx, docx, hwp, etc.

 

이때, OS별로 파일 타입을 구분하는 방식이 다르다. 

  • Windows: 이름 자체에 타입이 인코딩 되어있음.
    이름 뒤 확장자를 사용해 구분하며, 확장자에 따라 파일의 속성이 구분됨
  • Unix: 파일 내용 안에다가 타입을 인코딩 해놓음.

 


◆ Access Methods

파일 시스템에 접근하는 몇 가지 방식을 알아보자.

  • Sequential access
  • Direct access
  • Index access

 

■ Sequential access

파일 열었을 때 포인터가 가리키고 있는 곳에서 시작해서 순차적으로 접근하는 것.

 

현재 위치에서 읽거나 쓰면 offset이 자동으로 증가하고, 뒤로 돌아가기 위해선 rewind(되감기)가 필요함.
 
 

Direct access

포인터가 있는 게 아닌, 내가 접근하고 싶은 위치를 직접 지정해주는 것.

원하는 파일이 어느 위치에 있는지를 아는 경우에 사용 가능
 
읽기나 쓰기의 순서에 제약이 없으며, 현재 위치를 유지할 수 있다면 이를 통해 sequential access 기능도 구현할 수 있음.

 

 Index access

위치 정보를 알고있는 데이터들을 index로 저장하여 이용하는 방식.

파일에서 레코드를 찾기 위해 index를 먼저 탐색하고, 대응되는 포인터를 얻어서 이를 통해 파일에 접근하는 방식.
크기가 큰 파일에서 유용한 방식
 


◆ Directory Structure

디렉토리 구조에 대해서 알아볼 것임.
 

기본적으로, 디렉토리 구조 역시 디스크 위에 저장되어 있음.
디스크 위에 파일도 저장되어 있고, 디렉토리 구조도 저장되어 있다.
 

파일 속성 누르면 나오는 메타 데이터들도 원래 디스크에 있는건데 OS가 읽어와서 보여주는 거라고 했었음.
OS는 파일 시스템을 이해하고, 그 중 필요한 부분만 읽어서 우리한테 보여줄 뿐임.

 
 
디렉토리의 논리적 구조를 잘 구성하는 것은 몇가지 측면에서 볼 때 굉장히 중요하다. 

  • Efficiency: 파일을 빨리 찾을 수 있어야 함
  • Naming: 적절한 이름을 사용해서 사용자가 편하게 구분할 수 있게 해줘야 함
    다른 파일이 같은 이름을 가지거나, 하나의 파일이 여러 개의 이름을 가질 수 있다면 편리할 것임. (바로가기 같은거)
  • Grouping: 파일들을 적절한 분류로 그룹화 해두면 사용하기 편리할 것임

 
 
이를 위해 디렉토리 구조를 구성하는 방법으로 5가지가 있다.

  1. Single-Level Directory
  2. Two-Level Directory
  3. Tree-Structured Directories
  4. Acyclic-Graph Directories
  5. General-Graph Directories

하나하나 살펴보자.
 


◆ Single-Level Directory
: 단일 계층 구조

모든 파일들이 디렉토리 밑에 존재하는 형태.

 

  • 여러 유저가 싱글 레벨의 directory를 공유함.
  • 파일들은 서로 유일한 이름을 가지고, 서로 다른 사용자라도 같은 이름을 사용할 수 없음.

 

  • 같은 파일 이름을 가질 수 없음 (Naming 불가능)
  • 시스템에 오직 1개의 Directory만 있기 때문에 Grouping이 불가능

 


◆ Two-Level Directory
: 2단계 구조

각 사용자별로 별도의 디렉터리를 갖는 방식. 
ex)  /user1/cat 

 

  • UFD(user file directory) : 자신만의 사용자 파일 디렉터리
  • MFD(master file directory) : 사용자의 이름과 계정 번호로 색인되어 있는 디렉터리.
    각 엔트리는 사용자의 UFD를 가리킴.

 

  • 사용자가 다르다면 같은 이름의 파일을 가질 수 있고, 효율적인 탐색이 가능
  • 하지만 Grouping은 불가능함.

 


◆ Tree-Structured Directories
: 트리 구조

루트 디렉토리 밑에서 트리 구조로 서브 디렉토리로 뻗어나가는 방식
모든 파일이 유일한 경로를 가지며, 사용자들은 루트로부터 자신의 서브 디렉토리를 만들어서 파일을 구성하는 방식.

 
트리 구조인 만큼 순환이 없음

 
 

  • 하나의 루트 디렉토리 존재
  • 모든 파일은 고유한 경로(절대/상대경로)를 가짐
  • 이를 통해 효율적인 탐색이 가능하고, Grouping이 가능함.

 

※ 디렉토리도 일종의 파일이므로, 일반 파일인지 디렉토리인지 구분할 필요가 있음.
→ bit를 사용하여 0이면 일반 파일, 1이면 디렉터리로 구분함

 
 


◆ Acyclic-Graph Directories
: 비순환 그래프

트리 구조의 디렉토리를 그래프로 일반화한 형태.
디렉토리들이 서브 디렉토리들과 파일을 공유할 수 있도록 한 것임

 
한 파일을 유일한 경로로만 접근 가능했던 트리 구조에서와 달리, 여기서는 여러 경로로 접근 가능

 

  • 파일은 여러 개의 이름을 가질 수 있음
  • Link: 파일을 무작정 삭제하게 되면 현재 파일을 가리키는 포인터는 대상이 사라질 것임. → Dangling 포인터.
    따라서 참조되는 파일에 참조 계수를 설정하여, 참조 계수가 0이 되면 파일을 참조하는 링크가 존재하지 않는다는 의미이므로 그때 파일을 삭제할 수 있도록 함.
  • 구현시 Directory와 file 사이에 cycle(순환)이 없는 형태로 구현해야 함.

 


◆ General Graph Directory
: 일반 그래프

앞의 경우(Acyclic Graph Directory)에다 cycle을 허용하도록 는 형태.
  • 순환을 허용하는 그래프 구조이므로, 무한 루프에 빠질 수 있음...
    → 하위 디렉토리가 아닌 파일에 대한 링크만 허용하거나, 가비지 컬렉션을 통해 전체 파일 시스템을 순회하고 접근 가능한 것들만 표시하도록 해줄 수 있음

 
그림에서 Book 이랑 avi를 보면, 실제로 파일을 가리키지 않는데 그냥 서로를 가리키고 있음.
또는, 아예 아무랑도 연결이 안 되어있는 관계가 생길 수도 있음.
→ 이런 들을 지워주는 가비지 컬렉션이 필요함.(마지막 참조가 지워졌을 때 가비지 컬렉팅 해줘야 함)

 


◆ Protection

Windows에서는 보통 파일을 혼자 쓰기 때문에, 파일 보호가 크게 중요한 이슈가 아니다.
다수의 사용자가 접근하는 Unix나 Linux 계열의 경우, 각 파일에 대해 접근 권한 및 동작 방식을 지정할 수 있다.
 
파일의 owner나 creator가 파일을 접근할 수 있는 사람이나, 파일의 가능한 동작(r/w/x)을 지정해줄 수 있다는 뜻.
 
실제 Unix/Linux에서 어떻게 protection을 구현하는지 알아보자.
 


◆ Access Lists and Groups in Unix/Linux

Unix나 Linux에서 파일 보호하는 방식을 살펴보자
 
세 개의 접근 모드를 제공한다.

  • read (R)
  • write (W)
  • execute (X)

 
접근 권한을 R W X 순서로 표현하며, 십진수로도 표현할 수 있다.

십진수로 표현하는 경우 이진수로 바꾸었을 때 각 접근 권한을 알 수 있다.

  • 1이면 가능, 0이면 불가능.

 
세 개의 유저 클래스를 제공한다.

  • owner
  • group
  • public

각 유저들에 대해 접근 모드를 지정해줄 수 있다.
 
 

ex) 
접근 모드가 6이라 하자.
숫자 6의 경우, 이진수로 바꾸면 1 1 0이다.

RWX
110

 
즉, Read, Write는 가능하고 Execute는 불가능한 모드라는 의미.
 
chmod 를 통해 모드를 변경한다. (change mode)

 
 
 
ex)
다음은 game이라는 파일(또는 폴더)에 대해서, 유저 클래스별 접근 모드를 바꾸는 과정이다.

 
순서대로 owner, group, public에게 각각 어떤 접근 모드를 부여할 지 결정한 것이다.
 
예시에서 나온 7, 6, 1은 각각 다음과 같은 의미를 내포한다.

  • 7 (1 1 1): R, W, X가 모두 가능하도록 한다
  • 6 (1 1 0): R, W만 가능하도록 한다
  • 1 (0 0 1): X만 가능하도록 한다

또는 숫자로 안 쓰고 문자로

chmode rwxrw---x game 이런 식으로 써도 됨.

 
그룹 단위로 구분하고 싶을 때는 그룹을 만들어서 구분함

 


◆ Memory-Mapped FIles

파일을 프로세스의 가상 메모리에 매핑해놓고 쓰는 것
즉, Virtual address space의 특정 부분에 특정 파일을 매핑해놓고, 그 메모리 부분을 읽거나 쓰면 해당 파일을 읽거나 쓰도록 해놓은 것

 

  • 파일에 있는 data를 읽으려면 cpp에서는 fstream 객체를 하나 만들고, open하고, read/write하고, close 순서로 접근을 함. 귀찮음..
    Memory-Mapped 방식을 사용하면 이런 절차 없이 로컬 포인터 변수로 파일을 컨트롤 할 수 있음!
  • 포인터 변수가 파일을 가르키도록 만들어, 포인터를 따라가서 읽으면 실제 파일에서 데이터를 가지고 오고, 포인터를 따라가서 무언가 write하면 실제 파일에 써지도록 mapping을 해둔 것이다.

 
 
 

  • 디스크 안에 메모리 블록 1 2 3 4 5 6 이 있고, 얘네가 각각 virtual memory에 매핑되어 있다.
  • 처음에 블록 1에 접근했는데 page fault가 나면, physical memory에서 불러옴.
  • 이거는 open/read 이런 식으로 접근하는 게 아니라, 매핑된 파일로써 열어줘야 함
    mmap 사용. 특정 파일을 어떤 address에 매핑하겠다는 뜻

 

mmap을 불러오면 address가 나옴. 얘를 통해서 파일에 접근할 수 있음.

  • addr[0] = "hello" 이런 식으로 쓰면, 단순히 메모리에 쓰는 게 아니라 실제 파일에 쓰여짐.
  • string text = addr[0] 하면 실제 파일에 있는 내용을 읽어오는 것임

 
< 장점 >

  • 로컬 포인터 변수를 통해 마치 파일이 메모리에 올라와있는 것처럼 쓸 수 있어서, 사용하기 편함
  • 프로세스끼리 파일을 공유할 때도 편함.

 
 

 

'CS > 운영체제' 카테고리의 다른 글

15. File-System Internals  (0) 2023.12.11
12. I/O System  (0) 2023.12.06
11. Mass-Storage Structure  (0) 2023.12.05
10. Virtual Memory  (0) 2023.12.04
9. Main Memory  (0) 2023.12.04
Comments