[운영체제] 파일 시스템
File Systems
🔊 이화여자대학교 반효경 교수님의 KOCW 2014년 1학기 운영체제 강의를 들으며 정리한 노트입니다.
캡쳐한 이미지 중 따로 출처 명시를 하지 않은 이미지 또한 반효경 교수님 강의 자료에 있음을 밝힙니다.
File and File System
‘파일’이라고 하면, 흔히 아는 것처럼 하드디스크에다가 저장하는 단위를 말함.
우리가 전 챕터에서 ‘메모리 시스템’에 대해서 배웠는데, ‘메모리’는 주소를 통해서 접근하는 그런 장치였다.
-
File
반면에 디스크에 일반적으로 저장되는 ‘파일’이라는 것은
-
“A named collection of related information”
이름을 통해서 접근하는 단위이다.
정의를 하자면, “관련 정보를 이름을 가지고 저장하는 것”을 ‘파일’이라고 한다. -
일반적으로 비휘발성의 보조기억장치에 저장
ex) 하드디스크 같은 곳에다가 저장
-
운영체제는 다양한 저장 장치를 file이라는 동일한 논리적 단위로 볼 수 있게 해 줌
우리가 어떤 데이터를 저장하는 목적으로만 파일을 쓰는게 아니라, 운영체제에서는… 특히, 리눅스 같은 시스템에서는 여러가지 장치들도 관리하기 위해서 파일이라는 이름을 사용해서 관리를 한다.
다양한 저장 장치들… 하드디스크 1번, 하드디스크 2번 … 이런 것들이 있으면 운영체제는 그러한 장치들을 서로 다른 파일로 관리를 하고 있다. 그래서, 이런식의 파일을 ‘device special file’ 이라 부름. (이것은 우리가 일반적으로 접근하려는 일반 파일과는 좀 다르다)
-
Operation
파일에 대해서 정의되는 연산은?
-
create, read, write, reposition (lseek), delete, open, close 등
reposition (lseek)
(리포지셔닝 하는 연산) : 파일은 여러개 바이트로 구성이 됨, 굉장히 크기 때문에 어느 위치를 읽느냐, 쓰느냐를 가리키는 포인터가 있다. 그래서 대개는 파일을 그냥 읽으면, 그 파일의 시작 부분부터 읽게 되는데 이게 한 번 읽고나면 그 파일의 위치를 가리키는 포인터가 그 다음 부분을 가리키게 된다.
그러니까, 쭉 읽으면 위치 포인터는 그 다음 위치로 자동 이동을 하고, 계속해서 그 파일을 읽으면 그 위치부터 읽히게 된다는 것이다.
그런데, 우리가 필요에 따라서 파일의 시작 부분 또는 현재 위치 포인터 부분이 아니라 다른 부분부터 읽거나 쓰고 싶을 때가 있을 것이다. 그래서, 그런 파일의 위치를… 현재 접근하고 있는 위치를 수정해주는 그런 연산을 말함.open, close
는 도대체 왜 하는거냐?
일단 정의는 그렇게 되어있다. “read나 write를 하려면 먼저open
을 하고나서 read나 write를 해야된다.” 인터페이스가 그렇게 되있고, 그 다음에 파일에 대해서 읽고 쓰고 하는 일을 다 끝내서 더 이상 할 일이 없으면, 파일을close
해라 이런식으로 되어 있다는 것이다.그러면,
open
하고close
가 왜 굳이 따로 정의가 되있느냐?open
의 역할은 그 파일을 디스크에서 메모리로 내용을 올려놓는게 아니라, 파일의metadata
를 메모리로 올려놓는 작업을 파일의open
이라고 부른다. (뒤에 다시 설명 예정)
-
-
-
File attribute (혹은 파일의 metadata)
그 다음에 파일에는… 그 파일 자체의 내용말고 그 파일을 관리하기 위한 정보가 있다.
-
파일 자체의 내용이 아니라 파일을 관리하기 위한 각종 정보들
에를 들어, 음악 파일이라고 하면 음악은 그 파일 자체의 내용이지만,
-
파일 이름, 유형, 저장된 위치, 파일 사이즈
그 파일의 이름이라던지, 그 파일의 유형, 디스크 상에 저장된 위치, 파일 사이즈 이런 것들은 그 파일 자체의 내용하곤 상관이 없는 것이다. 이런 것도 같이 관리가 되야지만 우리가 파일을 관리할 수가 있겠다.
-
접근 권한 (읽기/쓰기/실행), 시간 (생성/변경/사용), 소유자 등
-
-
-
File system
파일 시스템이라는 것은 운영체제에서 파일을 관리하는 소프트웨어 부분이다.
-
운영체제에서 파일을 관리하는 부분
-
파일 및 파일의 메타데이터, 디렉토리 정보 등을 관리
파일 시스템은 파일 자체의 내용도 관리해야겠지만, 그 파일의 메타데이터도 같이 저장을 하고 있는 것이다.
그리고, 보통은 파일을 파일 시스템에 저장할 때 그냥 1차원적으로 저장하는게 아니라 디렉토리라는 것을 둬서, 루트 디렉토리부터 계층적으로 저장을 한다. 대부분의 파일 시스템이 디렉토리를 제공하고 있다.
좀 더 보기 편하게 관리상 편의성들을 생각해서 디렉토리를 두고 있다.
-
파일의 저장 방법 결정
-
파일 보호 등
그래서, 파일 시스템은 파일을 어떻게 저장할 지, 그리고 그 파일을 어떻게 관리할 지… 파일의 보호 등을 담당하고 있다.
-
Directory and Logical Disk
Directory
-
파일의 메타데이터 중 일부를 보관하고 있는 일종의 특별한 파일
디렉토리도 파일인데, 그 파일의 내용이 그 디렉토리 밑에 있는 파일들이 어떤건지에 해당하는 정보를 그 파일의 내용으로 하는 파일이라는 것이다.
일반 파일은 어떤가? 일반 파일은… 음악 파일이라고 하면 음악이 내용이고, 메타데이터는 그 파일의 이름이나 접근 권한 이런 것이다.
-
그 디렉토리에 속한 파일 이름 및 파일 attribute들
디렉토리 파일은… 그 파일의 메타데이터는 역시 디렉토리 파일의 이름과 디렉토리 파일의 접근 권한 이런게 메타데이터로서 존재할텐데… 디렉토리 파일의 내용은 뭐냐?
디렉토리 파일의 내용이라는거는 그 디렉토리 밑에 존재하는 파일들이 어떤건지, 그 디렉토리 밑에 있는 파일의 메타데이터를 내용으로 하는 파일이 ‘디렉토리’ 파일이라는 것이다.
그래서, 메타데이터는 파일의 이름을 포함해서
이런 것들이 다 메타데이터인데… 디렉토리에다가 이 메타데이터를 몽땅 저장할 수도 있지만, 그 디렉토리 밑에 있는 파일의 일부 메타데이터는 디렉토리에다가 직접 저장하고, 일부 메타데이터는 다른 곳에다 저장을 하기도 한다. (그거에 대해서는 뒤에서 실제 파일시스템의 예를 통해서 설명 예정) -
operation
디렉토리에 대해서 정의되는 연산은 어떤 것들이 있느냐?
-
search for a file, create a file, delete a file
그 디렉토리 밑에 존재하는 파일들이 어떠한건지 파일의 목록을 보는 것, 디렉토리 밑에 있는 파일을 찾는 것, 그리고 디렉토리에다가 파일을 하나 만드는 것, 그리고 그 디렉토리 밑에 있는 파일을 지우는 거
이러한 것들이 디렉토리에 대해서 정의된 연산이라는 것이다.
-
list a directory, rename a file, traverse the file system
파일의 이름을 바꾸는 것도 있을 수가 있고… 그리고, 파일 시스템 전체를 탐색하는 이런 것
traverse the file system
도 디렉토리 파일에 대한 연산으로 정의가 되있다.
-
결국에는 이런 파일 시스템이 하드디스크에 저장이 될텐데, 이 디스크라는게 논리적인 디스크가 있고, 또 물리적인 디스크가 있다.
Partition (= Logical Disk)
(그 두 가지의 차이는 나중에 설명하겠지만) 운영체제가 보는 디스크라는건 ‘논리적인 디스크’이다. 그리고, 이 논리적인 디스크를 다른 말로 ‘파티션’ 이라고도 부른다. 우리가 하드디스크 하나 사서 C드라이브, D드라이브 이렇게 파티션을 나누면, 그 각각이 논리적인 디스크가 된다는 것이다.
-
하나의 (물리적) 디스크 안에 여러 파티션을 두는게 일반적
그래서, 디스크 하나를 사서 파티션을 나누면 논리적인 디스크 여러개가 만들어지고,
-
여러 개의 물리적인 디스크를 하나의 파티션으로 구성하기도 함
또, 경우에 따라서는 물리적인 디스크 여러개를 합쳐가지고, 논리적인 디스크 하나를 구성할 수도 있다.
-
(물리적) 디스크를 파티션으로 구성한 뒤 각각의 파티션에 file system을 깔거나 swapping 등 다른 용도로 사용할 수 있음
그래서 이러한 파티션에 즉, 논리적인 디스크에다가 우리가 파일 시스템을 설치할 수가 있고 또는, 이 논리적인 디스크를 전 챕터에서 배웠던 Virtual Memory(버츄얼 메모리) swap area(스왑 에어리어) 용도로 사용을 할 수도 있는 것이다.
그래서, 우리가 디스크의 용도를 크게
-
파일 시스템 용도
-
스왑 에어리어 용도
이렇게 두 가지로 나눠볼 수가 있는 것이다.
-
Open()
아까 open()
연산에 대해서 설명을 했었는데, 이 open()
이라는 것은 파일의 메타데이터를 메모리로 올려놓는 것이다.
open() |
---|
우리가 이 논리적인 디스크 안에 파일 시스템이 있으면, 그 파일 시스템의 특정 파일에 메타데이터도 저장이 되있고, 그 파일의 내용도 저장이 되있을 것이다. 메타데이터 중에는, 파일의 저장 위치도 있다. 파일의 저장 위치도 하나의 메타데이터이기 때문에, 이 파일의 메타데이터 중에는 “이 파일이 어디에 저장이 되있다.” 파일의 내용을 가리키는 포인터도 같이 저장이 되있을 것이다.
어쨌거나, 이 파일을
open()
하게 되면 그 파일에 대한 메타데이터가 메모리로 올라오게 되는 것이다.
-
open(“/a/b/c”)
예를 들어서,
/a/b/c
라는 파일을 open하게 되면, 이c
라는 파일의 메타데이터가 메모리로 올라올 것이다. 근데, 이런식으로 디렉토리 경로가 계층적으로 구성이 되있을 때 open을 하라고 하면, 이c
라는 파일의 메타데이터가 어디 저장 되있는지를 디스크에서 찾아야 한다.어떻게 찾느냐하면, 보통 root(루트) 디렉토리의 위치는 미리 알려져있기 때문에 루트 디렉토리부터 경로를 따라 내려가면서 이
c
라는 파일의 위치를 찾게 되는 것이다. (아래 그림을 통해서 살펴보자)- 디스크로부터 파일 c의 메타데이터를 메모리로 가지고 옴
- 이를 위하여 directory path를 search
- 루트 디렉토리 “/”를 open하고 그 안에서 파일 “a”의 위치 획득
- 파일 “a”를 open한 후 read하여 그 안에서 파일 “b”의 위치 획득
- 파일 “b”를 open한 후 read하여 그 안에서 파일 “c”의 위치 획득
- 파일 “c”를 open한다
- Directory path의 search에 너무 많은 시간 소요
- Open을 read / write와 별도로 두는 이유임
- 한번 open한 파일은 read / write 시 directory search 불필요
- Open file table
- 현재 open 된 파일들의 메타데이터 보관소 (in memory)
- 디스크의 메타데이터보다 몇 가지 정보가 추가
- Open한 프로세스의 수
- File offset: 파일 어느 위치 접근 중인지 표시 (별도 테이블 필요)
- File descriptor (file handle, file control block)
- Open file table에 대한 위치 정보 (프로세스 별)
(그림과 함께 설명)
왼쪽이 물리적인 메모리, 오른쪽이 논리적인 디스크다.
사용자 프로그램이 ‘시스템 콜’을 할 수가 있다. 나는 /a 밑에 b라는 파일을 open하겠다.
fd = open("/a/b")
(open도 ‘시스템 콜’이다.. read, write, open 이런 것들이 다 I/O를 하는 ‘시스템 콜’임)이렇게 open을 하게 되면, 어떤 일이 일어나느냐?
먼저 시스템 콜이니까 CPU 제어권이 운영체제로 넘어갈 것이다. 그럼 운영체제 안에는 각 프로세스 별로 관리하기 위한 자료구조(PCB)가 있고, 또 전체 프로그램들이 지금 open하는 파일들이 어떤건지를 관리하는 글로벌한 테이블이 유지가 되고 있다.그래서, 이렇게 open을 해주면 루트 디렉토리의 메타데이터는 미리 알려져있다고 했다. 그래서 운영체제가 루트 디렉토리의 메타데이터가 어디 있는지를 알기 때문에,
그래서, 루트 디렉토리의 메타데이터를 먼저 메모리에 올린다. 즉, 루트를 먼저 open하는 것이다.
그러면 메타데이터 가운데에는 그 파일의 위치 정보가 있다고 했다.
그래서, 루트의 메타데이터를 열어보면 루트 디렉토리의 실제 내용이 어디 있는지 그 위치를 찾을 수가 있다.
그러면, 루트 디렉토리의 실제 컨텐츠가 예를 들어서, 위 그림과 같이 있다고 해보자. 그럼 이 root라는건 디렉토리 파일이기 때문에, 그 내용이 뭐냐하면 그 디렉토리 밑에 있는 파일들의 메타데이터를 가지고 있다.
근데, 루트 밑에 (이것도 물론 디렉토리 파일이지만)a
라는 파일이 지금 있는 것이다. 그래서, 루트 디렉토리의 내용에 가면 그 중에a라는 파일의 메타데이터
가 있을 것이다.그래서, 이 안에
a라는 파일의 메타데이터
가 존재하기 때문에 그것도 메모리에 올려놓는다. (a
를 open한 것이다)그러면,
a
가 이제 메모리에 메타데이터가 올라와있고,a의 메타데이터
중에는a
의 파일 시스템 상의 위치 정보가 들어 있을 것이다. 그래서 이 안에 살펴보니까…
a
가 디스크 어디에 그 내용이 있다는 것을 찾을 수가 있고…a
라는 파일도 보니까 디렉토리 파일이다. 이 디렉토리 파일에는 그 디렉토리 밑에 있는 파일들에 대한 메타데이터가 있다.지금
b
라는 파일이 그a
디렉토리 밑에 있는 파일이니까,a
안에는(a
의 내용 중에는)b라는 파일의 메타데이터
가 또 들어있을 것이다.그러면, 이걸 찾아서 또, 메모리에 올려놓는다.
아까 open이라는건 그 파일의 메타데이터를 메모리에 올려놓는 작업이라고 했는데, 지금
b
라는 파일을 open했고,b라는 파일의 메타데이터
가 드디어 메모리에 올라왔다. 그러면 이제 open이 끝난 것이다.open이 끝나면 지금 이 친구
Process A
가 ‘시스템 콜’을 했기 때문에 어떤 결과값을 리턴하게 되는데, 어떤 값을 리턴하느냐?각 프로세스마다 그 프로세스가 open한 파일들에 대한 메타데이터 포인터를 가지고 있는 일종의 배열같은게 정의가 되있다. 그래서, 만약에 지금 open한
b라는 파일의 메타데이터
위치가 여기 (위 그림 PCB안에 노란색으로 색칠되어 있음)그 친구를 가리키는 포인터가 이(PCB 안) 배열 어딘가에 만들어지고, 이 배열에서 “이게 몇번째 인덱스냐?” 그 인덱스가 바로
b
라는 파일의 파일 디스크립터(fd
)(b의 fd
)가 되서,그 값을 사용자 프로세스한테 리턴을 하는 것이다.
지금부터는 이 친구
Process A
가 open을 했기 때문에, 이b
라는 파일에 대해서 read / write를 하면 도대체 이b
라는 파일이 디스크 어디에 있는지를 막 다시 한번 루트 디렉토리부터 따라 내려가면서 찾고, 이런걸 할 필요가 없다 이미 open을 해놨기 때문에.b
라는 파일의 위치는b의 메타데이터
를 보면 나와있다. 그리고,b의 메타데이터
는 이미 메모리에 올라와있고, 그거의 위치를 지금 ‘파일 디스크립터fd
’ 가 가지고 있기 때문에, 이 사용자 프로세스Process A
는 이제 그 ‘파일 디스크립터’ 숫자만 가지고, 즉, 배열의 인덱스만 가지고 read / write 요청을 할 수 있는 것이다.
read(fd...)
예를 들어서,b
라는 파일에서 뭔가 읽어오고 싶다. 그러면, 프로그래밍을 해보면 파일 이름 read할 때 argument로 적는게 아니라, open한 다음에 그 파일 디스크립터fd
를 argument로 적어주게 되어 있다. 디스크립터를 적고 얼만큼 읽어오라던지 그런거를 역시 ‘read 시스템 콜’에 입력으로 넣어주는 것이다.그러면 이제 시스템 콜을 한거니까 다시 cpu가 운영체제한테 넘어간다.
“Process A
가 지금 이 디스크립터fd
를 가지는 파일에서 뭘 읽어오라고 했네?”read(fd...)
그러면,Process A의 PCB
에 가서 해당 디스크립터에 대응하는 r그 파일의 메타데이터 부분을Open file table
오픈 파일 테이블에서 따라간 다음에 이 (여기선,b의 metadata
) 파일에서 뭔가를 읽어오라고 했으니까, 이 파일의 위치정보가디스크 어디에 있는지를 메타데이터가 가지고 있다. 그럼 여기서(
b
에서) 그냥 읽어오라고 했으니까 시작 위치부터 읽어 올 것이다.Process A
가 요청한 용량만큼… 그 내용을 메모리로 읽어서 이 프로그램Process A
한테 전달해주면 될 것이다. 근데 이 과정에서 그 내용을 읽어서사용자 프로그램한테 직접 주는게 아니라
운영체제가 자신의 메모리 공간 일부에다가 먼저 읽어 놓는다.
그런 다음에, 이 사용자 프로그램한테 그 내용을 복사(copy)해서 전달을 해준다. 그래서 이제 read라는 작업이 끝난 것이다.
근데, 방금 전에 이 내용을 운영체제가 자신의 일부 메모리 영역에 copy해놓고서 전달한다고 했다. 만약에, 이 프로그램 또는 다른 프로그램이 동일한 파일의 동일한 위치를 요청하면…read 시스템 콜을 하면, 디스크까지 가는게 아니라 이미 운영체제가 한번 읽어놓은게 있기 때문에, 그것을 바로 전달해줄 수가 있을 것이다.
이게 바로 ‘버퍼 캐싱(buffer caching)’ 이라는 것이다.
우리가 전 챕터에서는 버츄얼 메모리 시스템에서 페이징 기법에 대해서 배웠고, 페이징 기법에서는 이미 메모리에 올라와있는 페이지에 대해서는 운영체제가 뭔가 중간에 끼어들지 못하고, 그냥 주소 변환을 하드웨어가 해가지고 바로 접근을 했고, 페이지 폴트가 났으면 그제서야 cpu가 운영체제한테 넘어와서 운영체제가 swap 영역에서 그 페이지를 읽어오고 이런 작업을 했었다.
근데, 이 파일에 대한 read / write를 하는 이런 시스템에서는 역시 ‘버퍼 캐시(buffer cache)’ 라는 걸 운영체제가 가지고 있는데, 이 파일 시스템의 버퍼 캐시는 요청한 내용이 버퍼 캐시 안에 있든 없든 간에 어쨌든 운영체제한테 cpu 제어권이 넘어가게 된다.
무슨 얘기냐…
지금은, 이 데이터fd...
를 요청했는데, 메모리에 안 올라와있었기 때문에, 이걸 읽어다가 이 자리b의 content내 자리
에다가 버퍼 캐시를 읽어놨다.
나중에, 이미 메모리에 있는 거에 대해서 어떤 프로그램이 요청을 한다…read해가지고
b
라는 파일의 이 부분을 달라… (위 그림 하늘색 v 표시)
그러면, 역시 이거는 시스템 콜이기 때문에, cpu 제어권은 무조건 운영체제로 넘어간다.
운영체제가 판단하는 것이다. “아 이게.. 내가 가져온게 이미 있네?” 그러면, 이거를 그냥 전달을 해주는거고, 요청한게 없다면 디스크에서 읽어와서 역시 ‘버퍼 캐시’ 에 올려놓고, 그거를 copy해서 사용자 프로그램한테 전달을 해야된다는 것이다.그래서, 파일 시스템의 ‘버퍼 캐시’ 라는 환경에서는 이미 버퍼 캐시에 내용이 있든 없든 간에 시스템 콜을 통해서 cpu가 운영체제한테 넘어온다. 그래서, 이 ‘버퍼 캐싱’ 환경에서는 LRU 알고리즘이나 LFU 알고리즘 같은거를 자연스럽게 사용을 할 수가 있는 것이다. 모든 정보를 운영체제가 다 알기 때문에…
그래서, 전 시간에 페이징 시스템에서 LRU를 못쓰고, 클락 알고리즘을 썼던 것과는 대조가 된다.
그래서, 이러한 커널이 유지하는 테이블들에 대해서 여러가지 이름들이 주어진다.
파일 디스크립터 테이블(
별 한개 표시
)은 프로세스마다 가지고 있다고 해서per-process file descriptor table 이다.
라고 부르고,그 다음에 Open file table은 파일을 open했으면 프로세스마다 가지고 있는게 아니라, open된 파일의 목록들을 system wide하게 한꺼번에 관리를 하고 있으므로 그래서, 이러한 테이블은
system-wide open file table 시스템 전체에 하나 존재하는 오픈 파일 테이블이다.
이렇게 부르는 것이다.근데, 시스템 안에 현재 open되있는 것과 관련된 테이블이 글로벌하게 하나 있는게 있고, 프로세스마다 별개로 있는 테이블이 있다는 것이다.
지금은 그림에서 2개만 보여주고 있는데, 운영체제 구현에 따라서 이러한 테이블이 두 종류가 아니고, 세 종류가 있는 경우도 있다.
왜냐하면, 메타데이터가 디스크에 있을 때는
이런 정보만이 메타데이터가 되는데, 그런데, 이것을 일단 메모리로 올려놓게 되면, 여기에 추가적으로 한 가지 메타데이터가 더 필요하다. 그게 뭐냐면, 현재 이 프로세스Process A
가 파일의 어느 위치를 접근하고 있다는 오프셋을 운영체제가 같이 가지고 있어야 된다. 근데, 그거는 프로그램마다 별도일 것이다. (지금Process A
라는 프로그램이 해당 파일b
을 open했지만, 또 다른 프로그램이 같은 파일b
을 open할 수도 있다. 그러면, 그b
라는 파일의 메타데이터는 한 copy만 올라와 있을 것이다. 즉, system wide하게 하나만 존재하는데, 오프셋은 서로 다를 것이다. 이 프로그램Process A
이 이b
파일에서 읽고있는 위치하고, 또 다른 프로그램이 이b
파일에 대해서 읽고 있는 위치가 다를 수가 있고…)
그래서, 그 파일 내에서 어디를 접근하는지 오프셋은 프로세스마다 별도로 가지고 있어야 한다.그래서, 이 오픈 파일 테이블을 사실은 또 두개로 나누어서 프로세스와 무관하게 하나만 가지고 있으면 되는 부분과 프로세스가 어디를 접근하고 있는지 별도로 가지고 있어야되는 오프셋을 따로 또 관리하는 테이블을 두는게 일반적이다.
그리고, PCB 안에 있는 테이블은 그냥 메타데이터의 위치만 가리키는 포인터기 때문에, 내용을 가지고 있는 것은 아니다.
경우에 따라서는 합쳐서 만들 수도 있겠지만, 그것은 구현하기 나름임.
어쨌든, 메타데이터가 메모리에 올라오면 각 프로세스별로 필요한 오프셋 같은 정보가 있고, 그것과 무관하게 이미 디스크에 적혀있는 그런 메타데이터가 있다.. 그걸 잘 구분해야함.
File Protection
파일의 접근 권한, 파일의 보호에 대한 얘기
메모리에 대한 프로텍션은 read / write 권한이 있느냐 없느냐 이런 얘기만 했다. 왜냐하면, 메모리라는 것은 프로세스마다 별도로 가지고 있기 때문에, 결국에는 자기 혼자밖에 못보는 것이다. 그래서, 메모리에 대한 프로텍션은 접근권한이 연산이 무엇이냐… write할 수 있는 페이지냐 read만 할 수 있는 페이지냐 이런식의 프로텍션만 해주면 됐는데,
-
각 파일에 대해 누구에게 어떤 유형의 접근(read/write/execution)을 허락할 것인가?
파일에 대한 프로텍션은 이 파일을 여러 사용자 또, 여러 프로그램이 같이 사용할 수가 있기 때문에, 파일에 대한 접근 권한은… 접근 권한이 누구한테 있느냐에 해당하는 것과 접근 연산이 어떤게 가능하냐에 해당하는 2가지를 같이 가지고 있어야 된다.
-
Access Control 방법
파일의 프로텍션과 관련해서 접근 권한을 제어하는 방법은 크게 3가지 정도로 생각을 해볼 수 있다.
-
Access control Matrix
행렬… 행렬의 행과 열이 있는데, 여기다가 사용자들하고 파일 이름들을 쭉 나열해놓고, 각각의 사용자가 각각의 파일에 대해서 (읽기/쓰기/실행 등) 어떤 권한이 있는지 표시. 그러면, 특정 사용자가 특정 파일에 대한 접근을 했을 때 권한이 있는지를 체크해보고 권한이 있는 경우에만 허락해줌.
근데, 이러한 방법은 사실 행렬 자체가 굉장히 희소행렬(sparse matrix) 형태가 될 것이다. 왜냐하면, 파일들은 엄청 많을텐데 그 중에서 특정 사용자가 본인만 사용하려고 만들어놓은 파일은 다른 사용자에 대해선 접근 권한이 전혀 없을 것이다. 그런데, 행렬의 칸을 다 만들면 낭비가 될 것이다.
그래서, 이런식으로 하지 않고… ‘Linked List(연결 리스트)’형태로 만드는 방법을 생각할 수가 있다. 그것도 주체를 누구로 하느냐에 따라 2가지를 생각해볼 수 있다.
-
Access control list: 파일별로 누구에게 어떤 접근 권한이 있는지 표시
‘파일’을 주체로 해가지고, 그 파일에 대해서 접근 권한이 있는 사용자들을 Linked List로 묶어놓는 것
-
Capability: 사용자별로 자신이 접근 권한을 가진 파일 및 해당 권한 표시
‘사용자’를 주체로 해가지고 Linked List로 만듬. 각각의 사용자를 중심으로 이 사용자에 대해서 접근 권한이 있는 파일들을 Linked List형태로 파일 목록을 쭉 연결해놓은 것.
2가지 중 어떤 방법이든 하나만 쓰면 됨.
그렇지만, 이렇게 되더라도 너무 부가적인 오버헤드가 크다는 것이다. 그래서, 일반적인 운영체제에서는 2번째 나와있는 그룹핑이라는 방법을 통해서 파일의 접근 권한을 제어하고 있다.
-
-
Grouping
-
전체 user를 owner, group, public의 세 그룹으로 구분
‘Grouping(그룹핑)’이라는 방법은 모든 사용자에 대해서 접근 권한을 다루는게 아니라 각각의 파일에 대해서 사용자 그룹을 3가지로 나눈다.
-
각 파일에 대해 세 그룹의 접근 권한(rwx)을 3비트씩으로 표시
그래서,
- 그 파일의 소유주에 대해서, 접근 권한이 read / write / execution 어떤 권한이 있는지를 표시하고,
- 그 다음 사용자와 동일 그룹에 속한 사용자들에 대해서, 읽기, 쓰기, 실행권한이 있는지 없는지 표시
- 나머지 전체 외부 사용자들에 대해서, 읽기, 쓰기, 실행권한이 있는지 없는지 표시
-
(예) UNIX
이런 그룹핑 방법을 쓰게 되면, 파일 하나에 대해서 접근 권한을 나타내기 위해서 총 9개의 비트만 있으면 된다.
(이렇게 해주면, 굉장히 효율적이다. 파일에 대한 접근 권한이 단 9개의 비트면 되는거니…)
-
-
Password
‘패스워드’를 걸어주는 방법. 우리가 보통 패스워드를 거는 것은 로그인 할 때 패스워드 이런 것을 생각하기 쉬운데,
-
파일마다 password를 두는 방법 (디렉토리 파일에 두는 방법도 가능)
여기서는 모든 파일에 대해서 패스워드를 통해서 관리하는 것이다. 또는, 디렉토리에 대해서 패스워드를 걸고, 그 디렉토리를 접근하려면 패스워드를 줘야지만 접근하게 할 수도 있다.
-
모든 접근 권한에 대해 하나의 password: all-or-nothing
-
접근 권한별 password: 암기 문제, 관리 문제
-
-
File System의 Mounting
위에서 하나의 물리적인 디스크를 파티셔닝을 통해서 여러개의 논리적인 디스크로 나눌 수가 있다고 말했다. 그리고, 각각의 논리적인 디스크에는 파일 시스템을 설치해서 사용을 할 수가 있다.
근데, 이러한 root file system(루트 파일 시스템)이라고 해서 어떤 특정 운영체제에 대해서 파일 시스템 하나가 접근이 가능한데, 만약에 다른 파티션에 설치되있는 파일 시스템을 접근해야된다. 그럴 때는 어떻게 해야 되느냐?
그거를 제공하기 위한 방법으로 ‘Mounting(마운팅)’ 이라는 연산이 있다.
마운팅이라는 것은 루트 파일 시스템의 특정 디렉토리 이름에다가 (위 그림에선
usr
) 또 다른 파티션disk3
에 있는 파일 시스템을 갖다가 마운트를 해주면, 그 마운트 된 디렉토리usr
를 접근하게 되면, 또 다른 파일 시스템의 루트 디렉토리에 접근하는 꼴이 된다는 것이다.
(즉, 이 친구초록색 파일 시스템
가 고스란히 루트가 이 자리노란색 루트 파일 시스템
와서 붙어있는 그런 꼴이 된다는 것이다.)그래서, 서로 다른 파일 시스템에 서로 다른 파티션에 존재하는 파일 시스템을 접근할 수 있게 된다는 얘기다.
Access Methods
파일을 접근하는 방법에 대한 얘기
-
시스템이 제공하는 파일 정보의 접근 방식
-
순차 접근 (sequential access)
-
카세트 테이프를 사용하는 방식처럼 접근
예를 들어, 카세트 테잎 안에 가수의 노래 중에 첫번째 곡만 인기가 있다고 가정하면, 그 노래를 듣고나서 다시 듣고 싶으면 테잎을 되감아야 함. 이런게 순차 접근임.
-
읽거나 쓰면 offset은 자동적으로 증가
만약 A, B, C라는 내용이 저장되있는데, “A를 보고 내가 C를 보고 싶다” 그러면, B를 반드시 접근해야지만, C를 볼 수 있는게 ‘순차 접근’이다.
-
-
직접 접근 (direct access, random access)
임의 접근이라고도 부름
-
LP 레코드 판과 같이 접근하도록 함
-
파일을 구성하는 레코드를 임의의 순서로 접근할 수 있음
직접 접근이 가능한 매체에서는 특정 위치를 접근 한 다음에 다른 위치를 접근하는게 바로 가능함.
A, B, C 순서로 저장되있는데, A를 본 다음에 B는 그냥 건너뛰고, C를 바로 볼 수 있다면 ‘직접 접근’임.
-
-
매체에 따라서도 직접 접근이 되는 매체가 있고, 안되는 매체가 있지만 아무리 직접 접근이 되는 매체라도 관리를 어떻게 하느냐에 따라서 순차 접근만 가능한 경우도 있다. 그것은 다음 챕터에서 설명…
Leave a comment