πŸ’Ώ KAIST:PINTOS | Concept | create, open, close

μ΄μˆœκ°„Β·2025λ…„ 5μ›” 22일

KAIST:PINTOS

λͺ©λ‘ 보기
17/23

μ‹œμŠ€ν…œ 콜(System Call)μ΄λž€?

μ‹œμŠ€ν…œ μ½œμ€ μœ μ € ν”„λ‘œκ·Έλž¨μ΄ μ»€λ„μ—κ²Œ μž‘μ—…μ„ μš”μ²­ν•˜λŠ” μ°½κ΅¬μž…λ‹ˆλ‹€.
예λ₯Ό λ“€μ–΄, μ‚¬μš©μžκ°€ open("file.txt")라고 μž‘μ„±ν•˜λ©΄ μ΄λŠ” "이 νŒŒμΌμ„ 열어달라"λŠ” μš”μ²­μ΄λ©°,
컀널은 μ‹œμŠ€ν…œ μ½œμ„ 톡해 이λ₯Ό μ²˜λ¦¬ν•©λ‹ˆλ‹€.

PintOSμ—μ„œλŠ” sys_create, sys_open, sys_close λ“±μ˜ ν•¨μˆ˜λ₯Ό 톡해 이 μš”μ²­λ“€μ„ μ²˜λ¦¬ν•©λ‹ˆλ‹€.


λ‚΄κ°€ 맑은 μ‹œμŠ€ν…œ 콜의 μ—­ν• 

μ‹œμŠ€ν…œ μ½œμ„€λͺ…
create(const char *file, unsigned initial_size)μƒˆ νŒŒμΌμ„ μƒμ„±ν•©λ‹ˆλ‹€. 파일 이름이 μ€‘λ³΅λ˜λ©΄ μ‹€νŒ¨ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
open(const char *file)νŒŒμΌμ„ μ—΄κ³ , ν•΄λ‹Ή νŒŒμΌμ„ μ‹λ³„ν•˜λŠ” 번호(fd)λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
close(int fd)μ—΄λ € 있던 νŒŒμΌμ„ λ‹«κ³  κ΄€λ ¨ μžμ›μ„ μ •λ¦¬ν•©λ‹ˆλ‹€.

fd(File Descriptor)λž€?

fdλŠ” "파일 λ””μŠ€ν¬λ¦½ν„°(File Descriptor)"의 μ€„μž„λ§λ‘œ, μš΄μ˜μ²΄μ œκ°€ νŒŒμΌμ„ μΆ”μƒν™”λœ 숫자둜 ν‘œν˜„ν•˜λŠ” λ°©μ‹μž…λ‹ˆλ‹€.
νŒŒμΌμ„ 직접 닀루지 μ•Šκ³ λ„ ν•΄λ‹Ή 숫자만으둜 μ ‘κ·Όν•  수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.

번호의미
0ν‘œμ€€ μž…λ ₯(stdin)
1ν‘œμ€€ 좜λ ₯(stdout)
2 μ΄μƒμ‚¬μš©μžκ°€ openν•œ 파일의 번호

예λ₯Ό λ“€μ–΄, open("a.txt")λ₯Ό ν˜ΈμΆœν•˜λ©΄ λ‚΄λΆ€μ μœΌλ‘œ fd = 2와 같이 λ²ˆν˜Έκ°€ λΆ€μ—¬λ˜κ³ , μ΄ν›„μ—λŠ” 이 번호둜 νŒŒμΌμ„ μ½κ±°λ‚˜ μ“Έ 수 μžˆμŠ΅λ‹ˆλ‹€.


fd_table의 ꡬ쑰

각 ν”„λ‘œμ„ΈμŠ€λŠ” μžμ‹ λ§Œμ˜ fd_table을 κ°€μ§€κ³  μžˆμŠ΅λ‹ˆλ‹€. 이 배열은 ν”„λ‘œμ„ΈμŠ€κ°€ μ—΄μ–΄ 놓은 νŒŒμΌλ“€μ„ μΆ”μ ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.

#define FD_MAX 128

struct thread {
  ...
  struct file *fd_table[FD_MAX];
  int next_fd; // fdλŠ” 2λΆ€ν„° μ‹œμž‘
  ...
};
  • open()을 ν˜ΈμΆœν•˜λ©΄ next_fd μžλ¦¬λΆ€ν„° 빈 μŠ¬λ‘―μ„ μ°Ύμ•„ ν•΄λ‹Ή μœ„μΉ˜μ— νŒŒμΌμ„ μ €μž₯ν•©λ‹ˆλ‹€.
  • close(fd)λ₯Ό ν˜ΈμΆœν•˜λ©΄ ν•΄λ‹Ή fd μœ„μΉ˜μ˜ νŒŒμΌμ„ λ‹«κ³  NULL둜 μ΄ˆκΈ°ν™”ν•©λ‹ˆλ‹€.

각 μ‹œμŠ€ν…œ 콜의 κ°œλ… 및 μ˜ˆμ™Έ 처리

1. create()

create("diary.txt", 0);
  • μƒˆλ‘œμš΄ 파일 "diary.txt"λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
  • 두 번째 인자인 0은 파일의 초기 ν¬κΈ°μž…λ‹ˆλ‹€.
  • λ§Œμ•½ 같은 μ΄λ¦„μ˜ 파일이 이미 μ‘΄μž¬ν•œλ‹€λ©΄ 생성에 μ‹€νŒ¨ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • 인자둜 μ „λ‹¬λœ file이 NULL이라면 sys_exit(-1)을 ν˜ΈμΆœν•˜μ—¬ μ¦‰μ‹œ μ’…λ£Œν•΄μ•Ό ν•©λ‹ˆλ‹€.

2. open()

int fd = open("diary.txt");
  • 파일 "diary.txt"λ₯Ό μ—΄κ³ , 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
  • 파일 열기에 μ‹€νŒ¨ν•˜λ©΄ -1을 λ°˜ν™˜ν•©λ‹ˆλ‹€.
  • μ—΄λ¦° νŒŒμΌμ€ fd_table[fd] μœ„μΉ˜μ— μ €μž₯되며, ν”„λ‘œμ„ΈμŠ€λŠ” ν•΄λ‹Ή 번호둜 νŒŒμΌμ„ λ‹€λ£Ήλ‹ˆλ‹€.

3. close()

close(fd);
  • μ—΄λ¦° νŒŒμΌμ„ λ‹«κ³ , κ΄€λ ¨λœ μžμ›μ„ ν•΄μ œν•©λ‹ˆλ‹€.
  • fdκ°€ μœ νš¨ν•˜μ§€ μ•Šκ±°λ‚˜ ν•΄λ‹Ή μœ„μΉ˜μ— 파일이 μ—†λ‹€λ©΄ 아무 μž‘μ—…λ„ ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

락(lock)이 ν•„μš”ν•œ 이유

파일 μ‹œμŠ€ν…œμ€ μ—¬λŸ¬ μŠ€λ ˆλ“œκ°€ λ™μ‹œμ— μ ‘κ·Όν•  수 μžˆλŠ” 곡유 μžμ›μ΄λ―€λ‘œ, 동기화가 ν•„μš”ν•©λ‹ˆλ‹€.
νŒŒμΌμ„ μ—΄κ±°λ‚˜ λ‹«λŠ” 도쀑 λ‹€λ₯Έ μŠ€λ ˆλ“œκ°€ κ°œμž…ν•˜λ©΄ μƒνƒœκ°€ 꼬일 수 있기 λ•Œλ¬Έμ—, file_lockμ΄λΌλŠ” μ „μ—­ 락을 μ‚¬μš©ν•˜μ—¬ μž„κ³„ ꡬ역을 λ³΄ν˜Έν•©λ‹ˆλ‹€.

lock_acquire(&file_lock);
filesys_open(file);
lock_release(&file_lock);

ν”„λ‘œμ„ΈμŠ€ μ’…λ£Œ μ‹œ μ—΄λ¦° 파일 정리

ν”„λ‘œμ„ΈμŠ€κ°€ μ’…λ£Œλ  λ•Œ close()λ₯Ό 직접 ν˜ΈμΆœν•˜μ§€ μ•Šμ•˜λ”λΌλ„, process_exit() ν˜Ήμ€ process_cleanup() λ‚΄μ—μ„œ λͺ¨λ“  μ—΄λ¦° νŒŒμΌλ“€μ„ 정리해 μ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€.

for (int i = 2; i < FD_MAX; i++) {
  if (fd_table[i] != NULL) {
    file_close(fd_table[i]);
    fd_table[i] = NULL;
  }
}

전체 흐름 정리

[ μœ μ € ν”„λ‘œκ·Έλž¨ ]         β†’ [ PintOS 컀널 ]
open("a.txt")          β†’ syscall_entry() β†’ syscall_handler()
                                          ↓
                                     sys_open()
                                          ↓
                                filesys_open()
                                          ↓
                            fd_table[next_fd] = file*

κ΅¬ν˜„ μ‹œ 체크리슀트

  • struct thread에 fd_table[]κ³Ό next_fd ν•„λ“œ μΆ”κ°€
  • sys_create()μ—μ„œ filesys_create() 호좜 및 NULL 검사
  • sys_open()μ—μ„œ filesys_open() 호좜, μ‹€νŒ¨ μ‹œ -1 λ°˜ν™˜
  • sys_close()μ—μ„œ file_close() 호좜 및 fd_table 정리
  • file_lock을 μ „μ—­μœΌλ‘œ μ„ μ–Έν•˜κ³  λͺ¨λ“  파일 μž‘μ—…μ— 적용
  • process_exit()μ—μ„œ μ—΄λ¦° 파일 전체 μˆœνšŒν•˜μ—¬ λ‹«κΈ°
  • syscall_handler()에 SYS_CREATE, SYS_OPEN, SYS_CLOSE case 등둝

마무리 μš”μ•½

  • μ‹œμŠ€ν…œ μ½œμ€ μœ μ €κ°€ μ»€λ„μ—κ²Œ 파일 생성, μ—΄κΈ°, λ‹«κΈ° 등을 μš”μ²­ν•˜λŠ” μˆ˜λ‹¨μž…λ‹ˆλ‹€.
  • fd_table은 각 ν”„λ‘œμ„ΈμŠ€μ˜ μ—΄λ¦° 파일 λͺ©λ‘μ΄λ©°, 이 ꡬ쑰λ₯Ό 잘 관리해야 ν•©λ‹ˆλ‹€.
  • 락 없이 파일 μž‘μ—…μ„ μˆ˜ν–‰ν•˜λ©΄ 데이터 μ†μƒμ΄λ‚˜ λ™μ‹œμ„± 였λ₯˜κ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • 파일 μ‹œμŠ€ν…œ μ½œμ€ 이후 κ΅¬ν˜„ν•  read, write, fork 등에 λ°˜λ“œμ‹œ μ—°λ™λ˜λ―€λ‘œ 기초λ₯Ό 튼튼히 μž‘μ•„μ•Ό ν•©λ‹ˆλ‹€.
profile
μ„œνˆ΄μ§€μ–Έμ • 늘 행동이 먼저이기λ₯Ό

0개의 λŒ“κΈ€