Polymor!

[OS] All about Linux 본문

Linux

[OS] All about Linux

Megan Kim 2020. 6. 7. 14:18

* Linux Filesystem 

" 파일을 사용자가 접근할 수 있도록 운영체제가 시스템의 디스크상에 일정한 규칙을 가지고 보관하는 방식" .

 

"파일 시스템"의 "파일 (file)"은 물리적인 하드웨어 저장공간에 저장되는 데이터의 집합을 말한다.

리눅스에서 파일이란... 정말 중요한 개념이다. 왜냐하면 키보드,마우스,인터페이스카드 등 디바이스가 파일의 개념으로 접근되기때문이다. 

단순한 일반(regular)파일만을 파일이라 칭하지 않고 모든 디바이스들까지 전부 파일로 취급함을 알아야한다. 

 

파일 시스템 추상적인 구조

 

파일 시스템 그 코어는 결국 구조체이고 포인터, 'SW프로그램'이다.. 

파일들은 디스크 상에 여러 조각으로 나누어 저장되어있다. 이 조각들의 시작주소를 포인터로 가지고 있는 것이 아이노드(inode)이다.

이때 시작주소는 디스크의 섹터 주소 (Sector Address) 이다. 참고로 read() / write() 의 기본 단위는 1섹터(512bytes)이다.

아이노드는 파일 각각에 대한 메타 데이터들을 함축하고있는 구조체라고 생각하면된다. 그리고 이 아이노드 정보들은 따로 포인터 배열로 저장을 해놓는다. 이 아이노드 정보들이 없으면 디스크 내 파일(실제 데이터가 저장되있는) 접근이 불가하다. 그래서 흔히 여러곳에 백업을 해둔다고 한다. 

디스크 내 여러 파일들 그리고 포인터 

 

 

터미널에 ls -i라고 명령어를 치면 좌측에 일련 번호들 나열된걸 확인 할 수 있다. 저게 바로 inode Number이다. 

 

* File Descriptor?

파일 디스크립터의 사전적 의미를 먼저 살펴보면 "음수가 아닌 정수로 파일을 기술하는 숫자" 라고 한다.

흔히 알고 있는 표준 입출력 그리고 표준에러가  0,1,2번을 할당 받는다. 

 

0: STDIN_FILENO

1: STDOUT_FILENO

2:STDERR_FILENO 

3: 새로 할당 받는 파일의 디스크립터 (가장 작은 수부터 채워지는 원칙)

.

.

.

.

 

파일 디스크립터의 본질은 무엇일까? 이러한 기술은 왜 사용하는 것일까? 

 

 

*한 상황을 가정해보자.

"a.txt" 라는 파일이 있는데 두개의 프로세스에서 이 파일에 접근을 하려는 상황이다. 

디스크에 저장이 되어있을 이 a.txt 라는 파일은 고유의 메타데이터가 있을 것이고 이 정보들은 아이노드라는 구조체에 담겨있다. 

아이노드 정보들을 가지고 있는 배열 형태의 inode table 이 있고 이 테이블은 커널 메모리 영역에 저장되어있다. 

동일한 파일이 두번 open() 된다면, 커널 영역에 file table에 해당 엔트리가 추가된다. 즉 아이노드 테이블 엔트리 포인터가 open할 때마다 생겨나는 것이다. 

 

다시 돌아가 두개의 프로세스 이야기이다.

두 프로세스는 독립적으로 메모리를 가지고 있다. 각각의 프로세스 메모리에는 파일 디스크립터 테이블이 있는 것이다. 

여기서 중요한 점은 파일 디스크립터 테이블과 파일/아이노드 테이블의 가장 큰 차이 점은 , 파일 디스크립터라는 개념은 독립적인 프로세스마다 고유하게 갖는 것이고, 아이노드는 커널 영역에 하나로 공유되는 것이라는 점이다.

결론적으로,  두 프로세스는 각각 디스크립터를 할당 받고 서로 다른 offset 정보와 공유하는 inode 정보로 동일한 파일에 접근하게 된다. 

 

그림 1

 

그림 2

 

한 프로세스에서 동일한 파일을 두번 open()한다고 가정해도 커널 영역 메모리 table 구조는 동일하다. 파일 디스크립터는 어떤 파일이 열리는지에 관심이 없고 그냥 시스템콜이 실행되는 것에만 고려하기때문에 같은 파일이든 다른 파일이든 2개의 파일 디스크립터가 생성될 것이다. 

 

int fd = open("a.txt",O_RDONLY); 

와 같이 open 시스템 콜을 호출하면 결과적으로 정수값을 리턴하여  fd에 그 값을 받아 write(), read()시스템콜에 접근자로 쓴다. 

 

그렇다면 , write() 와 read() 시스템콜을 호출하면 때마다 해당 파일을 접근하기 위해 디스크 I/O 가 실행되는 것일까? 하는 궁금증이 든다.

매번 디스크를 접근하는 것은 오버헤드가 크고 효율적이지 않을 것 같다는 막연한 생각이 든다. 

이때 사용되는 것이 memory mapped file의 개념이다.  즉, 입/출력을 메모리 참조 방식으로 대체하는 것이다.

 

Virtual Memory

실재하는 물리적 메모리 공간은 유일무이하다. 4GB RAM이라고 불리는 그 메인 메모리는 한개다.

그리고 운영체제는 멀티 태스킹을 지원하며 수많은 프로세스를 동시간에 실행시키고 있다. 이때 각 프로세스는 독립적인 메모리를 가지고 있다고 생각하며, 우리는 이 시스템을 메모리의 가상화라고 부른다. 프로세스와 마찬가지로 디스크의 파일도 가상 메모리 영역 한 부분을 차지하게 된다. 그럼 프로세스에서 그 파일을 접근할 때 디스크에 직접 접근하는 것이 아니라, 해당 메모리 주소 참조로 데이터 읽/쓰기 를 하는 것이다.

 

 

 두서없이 작성하였는데 다시 돌아가 파일 디스크립터에 대해 이야기를 하며 마치려한다.

파일 디스크립터는 그저 정수에 불과하는 숫자가 아니라, 장치를 접근하여 데이터를 읽고 쓰고 , 때로는 장치를 제어기도 한다.

각 프로세스마다 부여되는 고유의 값들로서 유저와 장치 사이의 인터페이스 역할을 하는 대단한 본질을 가진 아이다.

 

 

 

 

 

 

 

 

'Linux' 카테고리의 다른 글

kernel parameters  (0) 2022.12.04
ssh 로그인 없이 통신하기  (0) 2022.04.28
나를위한 리눅스 명령어 / shell 파일들  (0) 2020.05.28
Comments