유닉스 혹은 리눅스 시스템에서 프로세스가 특정 리소스를 다룰 때 사용하는 개념
즉, 특정 리소스에 접근하기 위한 추상적인 키를 말한다.
프로세스는 파일 디스크립터만으로 파일에 접근할 수 있다.
파일 디스크립터를 사용함으로써 파일 시스템의 복잡성을 신경 쓰지 않고도 파일을 다룰 수 있다.
**
파일 디스크립터 자체가 테이블 인덱스
STDIN_FILENO - 0 // 표준 입력
STDOUT_FILENO - 1 // 표준 출력
STDERR_FILENO - 2 // 표준 에러
파일 디스크립터는 3번부터 부여
사용하는 이유
1. 다양한 유형의 I/O 리소스를 동일한 인터페이스로 다룰 수 있음
- read(), write() 같은 함수를 사용하여 리소스에 쉽게 접근
2. 커널의 효율적인 관리
- 커널이 프로세스의 열린 파일을 효율적으로 관리하기 위해 사용
3. 추상화 및 간소화
- 복잡한 파일 시스템 구조를 간단한 정수로 추상화
4. 보안 및 격리
- 각 프로세스는 자신의 파일 디스크립터만 접근할 수 있으므로, 프로세스 간 격리를 제공
5. 리소스 추적
- 커널은 파일 디스크립터를 통해 각 프로세스가 사용 중인 시스템 리소스를 추적
구조
파일 디스크립터 테이블
- 각 프로세스마다 고유하게 존재하며, 파일 디스크립터를 저장하는 테이블
- 각 프로세스는 동일한 파일을 열 수 있다. 하지만 서로 다른 파일 디스크립터를 부여할 수 있음
- 테이블의 각 항목은 FD 플래그와 파일 테이블 포인터 등을 가지고 있음
파일 테이블
- 시스템 전체에서 공유되는 단일 테이블이며, 모든 프로세스의 열린 파일 정보를 포함
- 테이블의 각 항목은 파일 오프셋, inode 포인터 등을 가지고 있음
- 파일 디스크립터에 해당하는 inode 포인터가 매핑되어 있음
inode 테이블
- 파일 시스템의 모든 파일과 디렉토리에 대한 메타 데이터를 저장
- 파일 크기, 소유자, 권한, 타임스탬프, 데이터 블록 위치 등의 정보를 포함
**
프로세스는 파일 디스크립터만으로 파일에 접근할 수 있다.
**
파일 오프셋
- 파일 시작점으로부터 현재 위치까지의 바이트 단위
- 읽기/쓰기 작업이 어느 지점에서 시작 될 위치
- 읽기/쓰기 작업 수행 시 오프셋 자동 증가
파일 디스크립터 할당 과정
1. 프로세스가 Open() 시스템 콜 호출
2. 커널 모드로 전환
3. 파일 테이블에 해당하는 파일이 열려있는지 확인
- 열려있다면 기존 파일 테이블 엔트리를 재사용 (파일 테이블 엔트리의 참조 카운트 증가)
4. 열려있지 않다면 파일 시스템으로 이동하여 파일를 찾는다. (inode 번호를 찾음)
5. inode 테이블 확인
- inode 테이블에 엔트리가 있는 경우 해당 inode 정보를 사용 (inode의 참조 카운트 증가)
즉, 8번으로 넘어가 파일 테이블 엔트리와 inode 포인터 매핑
6. 엔트리가 없는 경우 디스크에서 inode 정보를 읽어와 inode 테이블에 새로 할당
7. inode에 저장된 권한 정보와 프로세스의 권환 정보를 확인하여 접근 여부 판단
8. 접근 가능한 경우 새로운 파일 테이블 엔트리를 생성하고 inode 포인터 저장하여 매핑
9. 프로세스의 파일 디스크립터 테이블에서 가장 작은 번호를 찾아 할당하고 파일 테이블 엔트리 포인터를 저장
하여 매핑
10. 결과 반환
- 성공적이라면 파일 디스크립터 번호 반환
- 오류가 발생했다면 오류 코드 반환
11. 사용자 모드로 전환
파일
유닉스 시스템은 모든 데이터들은 파일로 구성
일반적인 파일 뿐만 아니라 하드웨어도 포함한다.
-> 키보드, 모니터, 프린터도 파일로 취급
유닉스 시스템은 inode 인덱스를 사용하여 파일을 관리 및 접근
inode는 파일 시스템의 가장 기본이 되는 단위
각 파일은 고유한 inode 번호를 갖는다.
** TODO: 다시 찾아보기
inode는 15개씩 저장하는 12개는 직접 블록 주소를 저장하고
그 다음부터는 단일
12번줄 부터는 이중