일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
- 미국
- The beauty and Joy of computing
- Process
- scheduling policy
- control flow
- 코딩
- 균형의 정치
- Scratch
- insertion Sort
- 버클리
- 프로그래밍
- list
- 직업으로서의 정치 서평
- Jupyter Notebook
- Snap!
- Lock
- CLRS
- 맛집
- 영어논문
- 잘 짜인 코드
- xv6
- 푸드트럭
- 7월4일
- 스크래치
- 여행
- 독립기념일
- 운영체제 강의
- concurrency
- Operating System
- Deep Learning
- Today
- Total
여행다니는 펭귄
I/O , File 과 Directory 측면에서 본문
전 글에서 Process Virtualization, Memory Virtualization에 대해 모두 다루었죠?
이제는 마지막 Virtualization인 Storage Virtualization에 대해서 다뤄보도록 하겠습니다.
우리가 어떤 저장장치를 쓰던 관계없이, 저희는 일관적인 방식으로 Storage에 접근할 수 있어야 해요.
여기엔 두 가지 Concept가 필요합니다.
- File
- File은 연속된 array의 bit으로, 저희가 읽고 쓸 수 있습니다.
- 이것의 내용은 제작자에 의해 정의됩니다 ( text 파일인지 binary 파일인지)
- 그리고 inode number로 식별되죠 ( pid 와 비슷한 개념 )
- File은 연속된 array의 bit으로, 저희가 읽고 쓸 수 있습니다.
- Directory
- Directory는 특별한 종류의 파일로 다른 파일과 다른 디렉토리를 Collection 한 것입니다
- 이것의 내용은 앞에 나온것과는 다르게 (filename(user readable name), inode) 의 집합이 됩니다.
- Hierarchical한 구조를 가집니다.
- 이것 역시 inode number로 식별됩니다.
- Directory는 특별한 종류의 파일로 다른 파일과 다른 디렉토리를 Collection 한 것입니다
이 두가지 개념을 통해서 OS가 Storage를 관리하는 것입니다.

UNIX File System은 어떻게 돌아갈까요?
UNIX는 file의 컨셉트를 아주 폭 넓게 보아서 normal file 뿐 아니라 프로세스간 통신 경로, 각종 I/O 장치들을 전부 포함시켰습니다. Kernel 역시 파일로 관리되지요.
그리고 이 파일 역시도 inode number로 식별됩니다.
Directory 역시 파일이며 inode number을 가집니다. (user-readable name, inode number)을 포함하는 리스트죠.
그렇다면 어떤 파일이던 열어볼 수 있을까요?
이런 열기, 읽기 권한같은 경우는 다음과 같은 개념으로 관리됩니다.
- Ownership
- 각 파일에는 그 파일을 소유한 User가 있습니다.
- Owner는 어떤 Permission을 줄지 결정할 수 있습니다.
- Permissions
- 누가 파일에 접근할 수 있는지, 어떤 방식으로 접근이 가능한지 입니다.
- Ownership에 의해 부여됩니다.
이 Permission은 어떻게 표현될까요?

UNIX에서 File I/O는 어떻게 할까요?
- Opening Files
- File을 오픈하기 위해서는 Kernel에 File에 Access하고 싶다고 알립니다.
int fd; // file descriptor if ((fd = open("/etc/hosts", O_RDONLY) <0 ){ perror("open"); exit(1); }
- 그러면 file descripter를 file을 식별하기 위해서 반환해 줍니다.
- file descriptor 0,1,2는 각각 standard input/output/error 입니다.
- 만약 -1 이면 정상적으로 열리지 않았다는 의미입니다.
- Closing Files
- File Descriptor를 사용해서 File을 닫습니다. 이때도 Kernel에게 File을 닫는다는 사실을 알려야 합니다.
int fd; int retval; if ((retval = close(fd)) < 0){ perror("close"); exit(1); }
- 이 경우에 Return Value 역시 Error Check에 사용됩니다.
- File Descriptor를 사용해서 File을 닫습니다. 이때도 Kernel에게 File을 닫는다는 사실을 알려야 합니다.
- Reading and writing
- 일단 open() 으로 file을 열고 난 뒤에 read(), write()를 시스템 콜로 호출하고, close()를 해 줍니다.
- 만약 파일이 클 경우 반복해서 호출해 줘야 합니다.
- open( file name with path , flags)
- file descriptor를 return 합니다.
- read(file descriptor, buffer pointer, the size of buffer)
- 이것이 읽은 byte의 수를 return 합니다
- write(file descriptor, buffer pointer, the size of buffer)
- 이것이 쓴 byte의 수를 return 합니다.
- Read and Write는 Current offset 이 있어서 내가 어느 위치에 있는지를 확인해야 합니다.
- Implicitly : N byte를 읽었다면, Offset이 N만큼 늘어납니다
- Explicitly : lseek() 함수를 통해 조정할 수 있습니다.
- lssek(int fildes, off_t offset, int whence)
- 위 함수는 whence ( 0 = seek_set, 1 = seek_cur, 2 seek_end ) 로 부터 offset만큼 떨어진 곳으로 current offset을 조정합니다.
- open( file name with path , flags)
- Renaming Files
- atomic cell로 일어나는 작업입니다.
- 바꿀 이름의 파일을 만들고 copy한 다음 fsnyc()를 호출해서 모든 파일의 변경점을 디스크에 기록해야 합니다.
- 그 후에 기존 파일을 지웁니다.
- Getting Informatiion About Files
- fstat(), stat() 함수를 통해 파일의 메타데이터를 볼 수 있습니다.
- 이 메타데이터는 disk의 innode structure에 저장됩니다.
- Removing Files
- unlink()라는 함수를 통해서 파일을 지우는데, 이게 delete나 remove가 아닌 이유는 linking에 대해서 알아보면서 살펴봐야 합니다.
- 여기서 간단하게 설명하자면, 파일을 0으로 덮어씌우는 그런것이 아니라 접근할 수 있는 주소를 없앤다는것이 맞는 표현입니다.
- Making Directories
- mkdir()을 통해 디렉토리를 만듭니다.
- Directory가 맨 처음 생성되었을때 그것은 비어있습니다.
- 그 다음 자기 자신과 Parent로 가는 엔트리만 추가됩니다.
- Reading Directories
- ls 함수를 통해서 directory를 읽을 수 있습니다.
- Directory가 (inode, user readable) name으로 되어있다고 했는데, 이를 읽는 것이 directory를 읽는 것입니다.
- 이는 struct dirent 안에 포함되어 관리됩니다.
- Deleting a directory
- rmdir()로 Directory를 지웁니다.
- empty한 경우에만 실행할 수 있습니다.
Link는 무엇일까요?
아까 Link에 대해 언급을 간단하게 했었죠? Link의 종류에는 Hard link가 있고 Soft Link가 있습니다.
Hard Link는 link(or ln)(old pathname, new one)이라는 함수를 통해서 하게되는데 이 llink 함수는 어떻게 동작할까요?
- 새로운 이름을 가진 file 하나를 directory에 생성합니다.
- Original file의 inode number를 file에 줍니다.
- 그렇게 되면 복제하여 저장할 필요 없이 하나의 파일을 두개 이상의 이름으로 참조할 수 있게 되는 것입니다.
이는 파일 이름이 기본 메타데이터에 대한 링크임을 보여줍니다.
그러니 기본 파일은 그대로 있고, 저희는 link를 통해서 이 file을 찾을 경로를 생성하는 셈입니다.
그래서 remove를 할때 unlink를 통해 이 파일을 찾을 수 있는 경로만 끊어내는 것이죠.
reference count는 특정 inode를 가진 파일이 얼마나 많이 링크되어있는지의 수를 보여주는데, unlik가 호출되면 reference count는 감소합니다.
만약 reference count가 0이라면 파일 시스템이 이 파일을 절대 접근할 수 없기 때문에 Delete된 것과 마찬가지인 것이죠.
Hard Link에 대해 알아보았으니 Symbolic Link에 대해서도 알아봅시다.
Symbolic link는 hard link보다 훨씬 유용합니다.
Hard link는 다른 파티션에 있는 파일에 대해서 Link할 수 없기 때문이죠. 이는 inode number가 file system마다 unique한 것이기 때문입니다.
Symbolic link는 ln - s방식으로 이루어집니다.
그리고 Symbolic link는 Hard link와는 다르게 pathname을 저장하는 방식으로 이루어집니다.
만약 pathname이 길면 Sybmolic link의 size도 커지게 됩니다.
다만 이는 Original File이 삭제되면 Symbolic link가 빈 곳의 주소를 참조하게 되는 Dangling reference문제를 발생시킵니다.
다른 file system은 어떻게 열 수 있을까요?
- mkfs tool
- file system을 만들 수 있습니다.
- Input으로 partition된 disk와, file system type을 넣으면 됩니다.
- Output으로는 루트 디렉토리를 가진 empty file system이 나옵니다.
- mount()
- 이것이 바로 다른 file system을 여는 방법이죠.
- 이미 존재하는 디렉토리 하나를 mount point로 만들고, 새로운 파일 시스템을 그 mount point에 붙여넣습니다.
- 그럼 무엇이 mount 될까요?
- ext 3 : A standard disk-based file system
- proc : A file system for accessing information about current process
- tmpfs : A file system just for temporaray files
- AFS : A distributed file system
'컴퓨터 > 운영체제' 카테고리의 다른 글
Paging (0) | 2021.12.12 |
---|---|
File System Implementation (0) | 2021.12.12 |
Flash-based SSD (0) | 2021.12.10 |
HDD란? (0) | 2021.12.09 |
I/O Devices (0) | 2021.12.09 |