0. Gitbook과 Github Link
해당 블로그 글에는 코드를 따로 올리지 않으므로 대신하여 Github Link를 올립니다.
수정이 필요한 부분이나 틀린 부분은 댓글로 지적해주시면 감사하겠습니다.
Gitbook
https://casys-kaist.github.io/pintos-kaist/project4/introduction.html
Github Link (Implementation)
https://github.com/simons-pintos/pintos-kaist/tree/develop-project4-sunny_jamie
1. 큰 그림 잡아보기
기존의 소스코드는 기본적으로 구현되어 있는 파일시스템에서 동작하였다.
하지만 이는 문제가 있었으니..
파일이 디스크에 연속적으로 올라가기 때문에 외부단편화가 발생하였던 것이다.
따라서 우리는 이번 Project4를 통해서 좀 더 파일 시스템을 효과적으로 사용하여
디스크에서 효율적인 파일의 관리를 사용할 것이다.
파일시스템에 대한 방법은 매우 다양하나 우리는 불연속 할당 방법 중 하나인 FAT(File Allocation Table)을 사용하여 효율적인 파일시스템 체계를 강구한다.
2. FAT (File Allocation Table)
FAT의 경우 Linked List와 비슷하게 작동한다.
파일의 시작 위치에 해당하는 FAT를 찾아가면 해당 테이블 엔트리는 다음 블록의 주소의 클러스터 넘버를 가리킨다.
클러스터는 FAT의 넘버를, 섹터는 디스크의 넘버를 가리킨다고 보면 된다.
클러스터와 섹터는 cluster_to_sector와 sector_to_cluster를 통해 왔다갔다 할 수 있음을 알 수 있다.
그렇다면 여기서 FAT의 크기는 얼마나 될까?
FAT도 디스크의 일부분을 차지하여야하는데 해당 디스크의 크기를 알 수 있어야 FAT 자리를 제외하고 나머지 부분을 우리가 필요한 데이터 들로 구성시킬 수 있다. 해당 부분은 아래와 같이 계산 된다.
fat_boot_create 함수에 구현된 아래의 fat sectors를 이해하기가 어려웠는데, 차근차근 따라가다보면 이해가 된다.
(이해를 못해서 몇번이나 팀원들에게 물어본..)
전체 디스크의 섹터 개수 (핀토스에서는 20160개 이다.) 에서 한 섹터당 넣을 수 있는 cluster_t의 개수 (즉, 디스크 섹터사이즈에서 cluster_t를 나눈 값)을 나눠주면 된다. 다시말해 한 섹터에 넣을 수 있는 클러스터가 DISK_SECTOR_SIZE / sizeof(cluster_t)가 되는 셈. 최종적으로 계산해보면 약 157개의 FAT를 위한 디스크 섹터 개수가 나온다.
그 외에도 FAT_fs_init으로 FAT의 length를 구한다던지 FAT_create_chain 등을 통해 FAT를 운용하기 위한 여러개의 함수들을 구현해놓는다. FAT의 전체적인 그림을 잘 이해하는데 시간이 꽤나 걸렸고, 구현을 하는 것은 그리 코드가 길지는 않아 빠르게 구현이 되었던 것 같다.
3. filesys.c와 inode.c 구현
FAT를 잘 구현하여서 File Growth로 넘어가면 될 것이라 생각하였지만 생각지 못한 복병을 만났다.
아래와 같은 한 줄은 매우 함축적인 의미를 가지고 있었다.
기존에 파일시스템과는 다른 FAT 구조를 차용함으로써 filesys.c와 inode.c를 FAT 구조에 맞게끔 고쳐주어야한다.
기존에 잘 돌아가던 코드를 바꾸는 것이라 먼저 구현한 팀원의 힌트를 들어가며 구현에 임할 수 있었다.
free_map_allocate 함수와 byte_to_sector 함수를 위주로 수정을 하였다.
동시에 filesys.c와 inode.c를 좀 더 면밀하게 살펴보았다.
- filesys.c와 inode.c 간단하게 살펴보기
filesys.c의 경우 filesys_open, close, remove, do_format와 같이 filesys와 연관되어 있는 함수들이 포진되어 있다.
위에서 말한 바와 같이 기존 파일 시스템 -> FAT 구조로 바꾸는 작업을 진행했어야 했다.
구현을 진행하며 헷갈렸던 첫번째 내용은 inode.c에 대한 내용이었는데,
inode_disk와 inode 구조체가 둘 다 존재하여 내용이 많이 헷갈렸었던 것 같다.
기본적인 개념은 inode를 가리키면 대게 struct inode를 가리키고, 해당 inode는 멤버 중 data를 거쳐 inode_disk로 갈 수 있다.
(*inode -> struct inode -> inode_disk의 순)
inode_create 함수에서 해당 내용이 처음에 어떻게 설정되는지 좀 더 구체적으로 살펴볼 수 있었다.
inode.c 내에는 inode create, open, close와 같은 inode를 위한 기본적인 함수들이 구현되어 있다.
inode_read_at과 inode_write_at이 조금은 이해하기 어려웠는데 아래와 같은 도식을 활용하여 이해하려고 노력했던 것 같다.
흥미로웠던 점은 디스크에서 읽거나 쓸 때 섹터 내에도 내용이 있을 수 있는데, 그런 내용들을 bounce에 넣어 새로운 값 때문에 기존 데이터들이 손상되지 않도록 하는 점이었다. (코드 참고 필요)
FAT 파일 시스템을 기존 코드에 잘 녹아내렸다면 Project 3까지의 TC는 문제없이 통과한다.
가장 골치 아팠던 parse_path는 아래에서 다시 설명.
4. file growth와 subdirectories
file growth는 length 제한을 없애주거나, file growth 시 inode의 length를 갱신해주는 과정을 수행한다.
그 후 바로 chdir, mkdir, readdir과 같은 시스템콜 함수들을 구현해주고, soft link(바로가기와 같은 )를 구현해준다.
여기서는 각종 예외처리와 디렉토리의 현재위치, 수행해야하는 action을 잘 생각하며 구현하는 것이 중요하다.
특히 inode 구조체는 inode.c 파일에만 선언이 되어있어 다른 파일에서 구조체에 대한 멤버들로 접근하려면 접근자체가 불가하다.
따라서 우리 팀은 inode_is_dir, inode_is_empty와 같은 함수들을 사용해 해당 멤버들의 값을 들고왔다.
어느정도 기본적인 구현을 끝내놓고서는 테스트케이스를 돌려가며 오류를 잡아내는 식으로 예외처리나 버그를 잡아냈었는데
그 과정이 꽤나 고되고 어려웠다.
'.' , '..'과 같은 디렉토리들을 다루는 것들이 생각보다 쉽지 않았고,
디렉토리 이동, 삭제, open과 같은 테스트 케이스에서 무수히 많은 경우의 수들이 있어 그 경우를 모두 잡는 것이 쉽지 않았던 것 같다.
특히 앞에서 건들여줬던 parse_path는 지속적으로 말썽을 일으켰는데, 팀원이 케이스를 잘 나누어 구현을 성공시킨 덕분에 어려웠던 난관을 잘 극복할 수 있었다. (링크)
아키텍처를 잘 짜서 한번에 통과하면 더할나위 없이 좋겠지만, 모든 경우의 수를 한번에 생각하는건 쉽지 않을 것 같다.
테스트케이스를 돌려가며 요리조리 디렉토리와 파일을 넘나들며 예외처리를 하다보면 어느새 줄어든 Failed 값을 발견할 수 있다.
(두더지 잡기 게임과 같았다..)
우리팀은 아래와 같은 코드를 통해 현재 디렉토리의 상태를 확인하는데 도움을 많이 보았다.
printf("===Start of listing.===\n");
char name_in_dir[15];
while (dir_readdir(dir, name_in_dir))
printf("%s\n", name_in_dir);
printf("===End of listing.===\n");
5. 회고
정글의 "핵심"이었던 핀토스도 이제는 끝났다.
운영체제를 배울 것이라고 막연하게 말만 듣고 어떤 것일지 감도 못잡고 있었는데,
운영체제는 생각보다 단순(?)하게 기본적인 코드들로 이루어져 있다는 것이 신기했다.
태어나서 아마 가장 많은 코드를 접했던 지난 5주,
또 하나가 끝났다는 것에 대해 기쁘기도 하지만 조금 더 잘해내었으면 하는 아쉬움은 항상 남아있다.
좋은 팀원들 덕분에 핀토스도 무사히 마칠 수 있었다.
큰 그림을 그려주고, 코드를 설명해주고, 다양한 개념, 그리고 공부 접근방법까지 성심성의껏 알려준 멋진 팀원들 (HJ, JS)에게
이 글을 통해 감사의 인사를 전하고 싶다.
아직은 부족함을 많이 느낀다.
하지만 앞으로의 하루하루 성장해나가면 되니깐,
그리고 앞으로 남아있는 시간들이 지금까지 지내온 시간보다 훨씬 더 많이 남아있음을 알기 때문에
너무 조급하거나 급박하게 서두를 필요도 없을 것 같다.
그리고 앞으로의 시간들을 무엇인가를 성취하기 위해 마냥 참고 버티는 것들이 아닌
재밌고 즐겁게 하루하루를 보내었으면 한다.
앞으로의 나만무는 지금보다 훨씬 많이 발전된 모습으로 임해보고 싶다. 😊
마지막으로 내가 좋아하는 손흥민 아버지 손웅정님이 유퀴즈에서 알려준 고사성어를 조심스레 옮겨본다.
(찾아보니 지금 읽고 있는 책 '하얼빈'의 주인공인 안중근 의사가 남긴 유묵이라고 한다.)
인무원려 필유근우 (人無遠慮 必有近憂)
: 사람이 먼 생각이 없으면, 반드시 가까운 근심이 있다.
'Review > SW Jungle' 카테고리의 다른 글
Goodbye 정글, Hello world! (0) | 2023.02.12 |
---|---|
[WEEK14-19] 나만의 무기 만들기 + 정글 수료 (0) | 2023.02.05 |
[WEEK12] Pintos _ Project3 Virtual Memory 정리 및 회고 (1) | 2022.12.13 |
[WEEK11] Pintos _ Project3 FIFO / LRU / Clock 알고리즘? Eviction 정책들 파헤치기 (0) | 2022.12.13 |
[WEEK11] Pintos _ Project3 Virtual Memory (ELF 헤더와 프로그램 헤더 차이점 알아보기) (0) | 2022.12.06 |