이 글은 포스텍 김종 교수님의 컴퓨터SW시스템개론(CSED211) 강의를 기반으로 재구성한 것입니다.
이 글은 Linux에서 system level I/O를 살펴본다.
Unix I/O
Linux에서 file은 m개 byte의 나열, B$_0$, B$_1$, B$_2$, ... , B$_{m-1}$이며, 모든 I/O device는 file로 간주하며 current file position을 조정해 해당 위치에 있는 byte를 읽는다.
File Type
file type은 아래 3가지가 있다.
- Regular File : 임의의 데이터를 포함하는 file
- Directory : 관련있는 파일 그룹의 index. link들의 배열로 이루어져 있으며 각 link는 file과 filename을 매핑한다.
- Socket : 다른 machine의 process와 communicate하기 위해 사용하는 file.
File Operations
File Open
int open(char *filename, int flags, mode_t mode);
C에서 위 코드를 통해 파일을 열며, filename을 구분하기 쉽게 integer 형태의 file descriptor를 리턴한다. 이 때 file descriptor가 0보다 작다면 문제가 발생한 것을 의미한다.
이렇게 파일을 열면 kernel에게 해당 파일에 접근할 준비가 완료되었다는 것을 알린다.
File Close
int close(int fd);
C에서 위 코드를 통해 파일을 닫는다. 이미 닫힌 파일을 닫으면 multi-thread 프로그램에서 큰 문제가 발생하므로 그러지 않아야 한다.
File Read
ssize_t read(int fd, void *buf, size_t n);
fd에 해당하는 file descriptor 값을 가진 file의 current file position에있는 byte를 읽어 메모리에 복사하고 file position을 이동한다.
File Write
ssize_t write(int fd, const void *buf, size_t n);
file read와 마찬가지로 fd에 해당하는 file descriptor 값을 가진 file의 current file position에 메모리에 있는 값을 쓰고 file position을 이동한다.
Unix kernel이 파일을 표현하는 방식
kernel은 아래 3개의 data structure를 이용해 file을 표현한다.
- descriptor table : 각 process마다 하나씩 존재하며 하나의 descriptor element는 open file table의 element를 가리킨다.
- open file table : open된 file은 모든 process가 공유하는 file table에 올라간다. file table entry는 현재 file position, 해당 file을 참조하고 있는 descriptor table element 개수 등의 값을 가지고 있다. (즉, descriptor를 닫으면 해당 descriptor가 가리키는 file table element의 refcnt가 1 감소한다.)
- v-node table : 모든 process가 공유하며 file metadata를 가지므로 file당 하나씩 존재한다.
Metadata
metadata는 데이터에 관한 데이터이다. (요약본으로 이해하면 될 것 같다.)
이 장에서는 file metadata를 다루는데 file metadata는 kernel에 의해 유지되며 file마다 하나씩 존재한다.
File Sharing : 같은 file을 참조하는 경우
open() 함수를 2번 호출하는 등의 방식을 통해 서로 다른 file descriptor는 서로 다른 file table element를 통해 같은 file을 참조할 수 있다. 이 경우 v-node table은 file metadata이므로 하나만 존재하지만 open file table는 다른 값이다.
File Sharing : fork()하는 경우
fork() 함수 호출 시 해당 process의 모든 것을 복사한 child process가 생성되므로 기존 것과 동일한 descriptor table이 복사된다. open file table과 v-node table은 모든 process가 공유하므로 새로 생기지 않는다. 단, open file table의 refcnt가 하나씩 증가한다.
I/O Redirection
int dup2(int oldfd, int newfd);
dup2 함수는 descriptor table의 newfd에 해당하는 것을 oldfd로 바꾸는 함수이며, 이를 이용해 표준 입출력을 disk file과 연결할 수 있다.
위 그림을 보자. 기존 descriptor table의 0은 stdin, 1은 stdout, 2는 stderr, 3은 file table의 file A에 해당하는 element를 가리키는 상태였다. 여기서 fd(3, 1)을 호출하면 descriptor 1은 file descriptor 3이 가리키고 있는 file A를 가리키게 된다.
잘못된 내용이나 지적, 오탈자 등은 언제나 환영합니다.
'CS > OS' 카테고리의 다른 글
[컴퓨터 SW] Dynamic Memory Allocation (0) | 2023.06.24 |
---|---|
[컴퓨터 SW] Virtual Memory (0) | 2023.06.21 |
[컴퓨터 SW] Exceptional Control Flow & Process (0) | 2023.06.19 |
[컴퓨터 SW] Static Linking (0) | 2023.06.17 |
[컴퓨터 SW] Cache와 Locality (0) | 2023.06.15 |