파일 시스템
파일 개념
저장장치의 물리적 특성을 추상화한 논리적 저장 단위, 보조저장장치에 기록된 정보의 집합.
- 자료가 파일 안에 존재해야만 보조저장장치에 기록될 수 있음.
- 프로그램
- 자료
- UNIX, Linux 및 기타 운영체제는 시스템 정보(프로세스 세부 사항)에 대한 엑세스를 제공하기 위해 파일 시스템 인터페이스를 사용한다(proc)
파일 유형
- 텍스트 파일
- 행과 페이지로 구성되는 연속된 문자.
- 소스 파일
- 선언과 실행문으로 구성된 함수들의 연속.
- 실행 파일
- 로더가 메모리로 가져와 실행시킬 수 있는 연속된 코드 부분.
파일 속성
사용자 편의를 위해 파일에 이름을 부여하고 그 이름으로 파일을 참조한다. 파일이 일단 만들어지면, 그 파일을 생성한 프로세스, 사용자, 시스템으로부터 독립하며 개별적으로 변경될 수 있다.
- 이름
- 식별자 (우리가 읽을 수 없는 파일의 이름(숫자))
- 유형
- 위치
- 크기
- 보호 : 접근 제어 정보, 누가 읽기 쓰기 실행 등을 할 수 있나?
- 타임스탬프와 사용자 식별 : 생성, 최근 변경, 최근 사용.
디렉터리
디렉터리는 파일의 메타데이터를 저장한다.
- 파일 정보를 확인할 때 뜨는 메타데이터들은 사실 디렉터리가 저장하고 있던 것.
- 디렉터리 항목 → 파일 이름, 고유의 식별자(다른 파일 속성을 찾는데에 유용.)
파일 연산
파일을 정의하기 위해 파일에 대해 실행할 수 있는 연산.
- 파일 생성
- 파일을 저장할 수 있도록 파일 시스템 내에 공간 찾기
- 디렉터리에 파일 메타데이터 기술
- 파일 열기
- 파일 연산에서 매번 파일 이름을 지정하면 검사+접근 권한을 매번 수행해야 함.
- 먼저 파일을 open() 하고 파일 핸들러를 가져와서 작업 수행.
- 파일 쓰기
- 시스템은 파일 내의 다음 순차적 쓰기가 일어날 위치를 가리키는 쓰기 포인터를 유지하고 있어야 함.
- 파일 안에서 위치 재설정(커서 옮기기)
- 파일의 읽기/쓰기 위치를 변경 → 탐색(seek)
- 파일 삭제
- 파일을 디렉터리에서 찾음.
- 모든 파일 공간을 해제하고 디렉터리 항목을 지우거나 사용 가능으로 표시
- 하드 링크 : 하나의 파일이 여러 개의 파일 이름으로 존재할 수도 (i-node 는 같음)
- 파일 절단
- 파일 크기를 잘라 일부 내용을 자름
- 예 ) 로그 파일 10GB → 마지막 1GB 만 유지하도록 절단
💡 새로운 파일을 생성하고 기존 파일을 읽어 새로운 파일에 기록하는 복사. 파일 속성을 정할 수 있는 연산 등도 있다.
파일 연산
모든 파일 연산은 관련 디렉터리를 먼저 찾는 작업을 하는데, 반복적인 탐색을 피하고자 맨 처음 open() 시스템 콜을 한다.
- 열린 파일 테이블
- 모든 열린 파일에 대한 정보를 갖고 있음.
- 임의의 파일 연산이 요구되면, 이 테이블에 대한 인덱스로 그 파일을 지정하니까 어떤 탐색도 필요 X
- create() , delete() 는 닫힌 파일을 대상으로 동작하는 시스템 콜.
열린 파일
open()
전형적으로 열린 파일 테이블 항목에 대한 포인터를 반환함.
- 포인터를 입출력 연산에 사용
- 탐색 과정을 피하고
- 시스템 콜 인터페이스를 단순화
운영체제의 내부 테이블
- 프로세스 별 테이블
- 각 프로세스가 연 모든 파일을 기록
- 파일 포인터, 읽기 쓰기 위치
- 프로세스가 파일을 어떻게 사용하는가.
- 시스템 테이블
- 파일의 메타데이터 저장
열린 계수
열린 파일 테이블이 가진, 파일을 연 프로세스 수를 가리킴.
- 계수가 0이 됐을 때, 파일은 더 사용되지 않음을 나타내고 열린 파일 테이블로부터 제거 됨.
요약
- 파일 포인터
- 가장 최근 읽기/쓰기 위치 추적
- 유일하게 하나씩 만들어지므로 디스크상의 파일 속성들과는 분리되어 유지
- 파일 열린 계수
- 마지막 파일이 0이 되어야 항목 제거
- 파일 위치
- 열린 파일 위치 → 메모리에 저장
- 접근 권한
- 접근 불허/허용 등
파일 락
하나의 프로세스가 파일을 잠그고 다른 프로세스들이 그거에 대한 접근하는 것은 막는데에 사용
- 시스템 로그 파일처럼 공유되는 파일들에 유용
- 읽기 락 : 공유락처럼 여러 프로세스가 동시에 락을 획득할 수 있는 것과 비슷.
- 쓰기 락 : 배타적인락처럼 한번에 한 프로세스만 락을 획득할 수 있다는 점에서 비슷.
강제적, 권고적 락
- 강제적 락
- 프로세스가 배타적 락을 획득하면, 운영체제가 다른 프로세스가 잠겨진 파일에 접근하는 것을 막는 것.
- 락 무결성을 안전하게 보장
- 권고적 락
- 파일에 접근하는 걸 막진 않지만, 파일에 접근하기 전 락을 획득해야 함.
- SW 개발자가 락이 적절히 획득되고 해제되는 것을 보장해줘야 함.
파일 유형
holiday.exe 라면
- holiday → 파일 이름
- exe → 확장자
- 응용 프로그램이 동작하는 파일들에 대한 “힌트”
💡각 파일은 자신을 생성한 프로그램의 이름을 파일 속성으로 가진다.
매직 넘버
이진 파일의 시작 부분에 저장된 넘버
- 파일의 데이터 유형(예: 이미지 파일 형식)을 나타냄.
- 파일 시작 부분에 텍스트 매직 번호를 사용하여 파일 유형(스크림트에 사용된 셸 언어)등을 나타내기도..
- 주로 사용자가 파일에 포함된 컨텐츠 유형을 결정하는 데 도움을 준다.
파일 구조
실행 파일에 대해 메모리상의 어느 위치에 적재되며, 초기에 실행 가능한 명령어의 위치를 파악할 수 있도록 특별한 구조를 요구한다.
- 운영체제가 여러 파일 구조를 지원하면 단점 → 운영체제의 크기가 커지고 관리하기 힘들어짐.
- 운영체제의 파일 유형 메커니즘에 반하는 예외적인 경우를 만들거나 암호화된 형태는 사용하지 않아야 할 것임.
- UNIX 는 파일을 단순히 8비트 바이트들의 단순한 집합으로 봄 → 내용이나 파일 구조에 관여 X
- 모든 운영체제는 반드시 한 가지 파일 구조는 지원해야 함
- 프로그램을 로딩하고 실행할 수 있는 실행 파일의 구조
파일의 내부 구조
파일은 일련의 블록으로 간주하고 모든 I/O 기능은 블록단위로 수행됨.
- 파일 시스템은 자동으로 바이트들을 하나의 물리 블록(예: 512바이트)로 필요에 따라 팩하거나 언팩.
- 모든 파일 시스템은 내부 단편화 문제를 갖고 있음.
- 디스크 공간이 항상 블록 단위로 할당 → 각 파일의 마지막 블록의 일부는 낭비 됨.
- 블록 크기가 클수록 내부 단편화가 커짐.
접근 방법
순차 접근 (hadoop)
저장되어 있는 레코드 순서로 접근
- 데이터를 한 번에 큰 블록 단위로 읽음
- 디스크 I/O 최소화 (성능 최적화)
- 대량의 데이터 빠르게 처리
직접 접근
고정 길이의 논리 레코드의 집합을 어떤 블록이라도 직접 엑세스 가능.
- 블록 14를 읽고 → 블록 53을 읽고 → 블록7을 기록
- 읽기 쓰기 순서에 제약 X
- 대규모 정보를 다루는데 아주 유용 → 대규모 데이터 베이스
- 엥 근데 하둡은 왜?
기타 접근 방법
파일에 대한 색인(index) 를 사용하여 찾는 레코드를 색인부터 찾아 그에 대응하는 포인터를 얻는다.
- 색인(index) 여러 부분에 대한 포인터
- 책 맨 뒷부분에 나오는 단어 가이드 등
- 파일을 같은것끼리 정렬해두면 인덱스를 정의 가능
- 인덱스를 (이진) 탐색
- 어느 블록이 원하는 레코드를 수록하고 있는지 파악
- 이 블록에 접근
- 너무 크면 2차 색인 등등 함
디렉터리 구조
각 디렉터리에서 수행될 수 있는 연산
- 파일 찾기
- 메타데이터로 파일 찾기
- 파일 생성
- 파일 삭제
- 디렉터리 나열
- 디렉터리에 존재하는 파일들 나열하고 메타데이터 내용 보여줌
- 삭제는 디렉터리 구조에 hole 을 남기고 파일 시스템에서는 디렉터리 구조를 단편화를 없애는 방법이 있을 수 있음
- 파일의 재명명
- 파일 시스템의 순회
- 파일을 디렉터리를 순회해 볼 수 있게 해주는 기능.
디렉터리란
특별 취급을 받는 파일
- 모든 디렉터리는 내부적으로 똑같은 구조로 되어 있다.
- 비트를 사용하여 파일(0)인지 디렉터리 파일(1)인지 구분할 뿐이다.
비순환 그래프 디렉터리
디렉터리들이 서브디렉터리들과 파일을 공유할 수 있도록 허용하는 구조, 똑같은 파일이나 서브디렉터리가 서로 다른 서브디렉터리에 있을 수 있다.
- 한 사람이 디렉터리에 파일을 만들거나 지우면 다른 서브디렉터리에 자동으로 반영 됨. → 복사와 개념이 다름
파일 공유 구현법
- 링크 : 다른 파일이나 서브 디렉터리를 가리키는 포인터
- 포인터로 하나의 디렉터리를 가리킨다.
- 그 링크를 해석하여 디렉터리 접근
- 공유하는 디렉터리들이 동일한 항목 내용을 복사해서 가지고 있음.
- 하지만 일관성 문제가 있음 → 하나가 바뀌면 하나도 동기화해줘야하는데..
공유 때의 삭제 시 문제
공유 공간에 할당된 공간을 언제 반납하고 재사용하는가?
- 심볼릭 링크
- 이 링크를 지울 경우 문제가 없다.
- 하지만 링크가 살아있으면서 이 링크가 가리키는 파일이 지워지면 링크는 존재하지않는 파일의 이름을 가리키게 된다.
- 모든 참조가 지워질 때까지 원본 파일을 보존한다.
- 참조한 숫자를 가리키는 계수를 유지한다 → 0이 되면 삭제
💡이런 문제들이 있어 어떤 운영체제에서는 공유 디렉터리나 링크를 허락하지 않는다.
보호
접근의 유형
통제된 접근을 하도록 각각에 접근 권한을 둔다.
- 읽기
- 쓰기
- 실행
- 추가
- 삭제
- 리스트
- 속성 변경
접근 제어
특정 파일에 대한 접근 허용 여부를 결정하자.
- 접근 제어 리스트(ACL) 로 이 파일을 누가 어떤 연산을 위해 사용할 수 있는지 기술한다.
- 복잡한 접근 방법을 가능케하나
- 리스트 길이가 너무 길어질 수 있다.
- 리스트 길이를 간결하게 하기 위해 모든 사용자를 세 가지 부류로 분류한다.
- 소유자 : 파일을 생성한 사용자
- 그룹 : 파일을 공유하여 유사한 접근을 해야하는 사용자 집합.
- 기타 : 시스템에 있는 다른 사용자
예시
- 소유자는 그 파일에 대한 모든 연산을 실행 가능하다.
- 그룹에 있는 사용자들은 단지 읽고 쓰기만 할 뿐 파일 삭제는 불가능하다.
- 모든 사용자는 그 파일을 읽기만 가능하다.
슈퍼 사용자
UNIX 시스템에서 스룹은 시스템 관리자(혹은 슈퍼 유저)에 의해서 생성되고 변경된다.
메모리 매핑 파일
디스크 입출력을 메모리 참조 방식으로 대신하자.
기본 기법
프로세스의 페이지 중 일부분을 디스크에 있는 파일 블록에 매핑한다.
- 첫 번째 파일은 요구 페이징 과정에 따라 페이지 폴트가 일어난다.
- 이후 read/write 는 일반 메모리 엑세스와 같이 처리된다.
- 메모리를 파일에 올려 사용한다.
- 메모리에 매핑된 파일에 대한 쓰기는 반드시 보조저장장치의 파일에 동기식으로 써지지 않는다는 것은 주의하자.
- 파일을 닫을 때 저장하거나, 메모리가 부족하면 스왑 공간에 반영한다.
파일 공유
프로세스가 데이터 공유를 위해 메모리에 올려진 파일을 공유할 수 있다.
- 이런 경우 한 프로세스가 공유 중인 메모리 매핑 파일에 쓰기를 하면, 그 쓰기는 즉시 다른 모든 프로세스도 볼 수 있게 된다.
- 파일을 공유하는 프로세스들의 페이지 매핑 테이블은 모두 그 파일에 대응하는 물리 메모리상의 페이지를 가리킨다.
- 가상 메모리를 생각해보자!
- 공유 메모리를 메모리 매핑 파일을 통해 구현하는 것은 매우 자주 있는 일이니 기억해두자!
'개발공부 개발새발 > OS' 카테고리의 다른 글
OS ) 메인 메모리 - 2편 : 페이징, 34/64비트, ARM (0) | 2025.02.15 |
---|---|
OS ) 메인 메모리 - 1편 (0) | 2025.02.14 |
OS ) 교착 상태 DeadLocks (0) | 2025.01.23 |
OS ) 동기화 도구 -> 락 (Mutex, 세마포) (0) | 2025.01.21 |
OS ) 스레드 Thread (0) | 2025.01.15 |