시스템 프로그래밍(3)

조권휘·2022년 8월 19일
0

시스템 프로그래밍

목록 보기
3/14

Linux File System

  • 각 file은 inode (information node)를 가지고 있다.
  • inode는 file의 고유 번호이다.
  • inode는 data structure의 모든 정보를 가지고 있다.
  • inode들은 disk에 저장되어 있다.

    inode가 가지고 있는 정보들
    : file name, type, id, permission, size, data block addr .table...


Inode Sturcture

  • 1~12번은 direct pointers로 1개당 1 block size
  • 13번은 single indirect pointer로 block pointer의 집합체
  • 14번은 double indirect pointer
  • 15번은 triple indirect pointer
  • 13~15는 제곱해서 안에 담겨있다고 생각하면 편하다.

File Types

  • ordinary file : 일반 file (text, binary..)
  • directory file : dir도 파일로 자신이 가진 파일에 대한 정보를 가진다.
  • character special file : I/O 연산을 수행할 수 있도록 제공(byte 단위)
  • block special file : 큰 영역의 용량의 data를 주고 받는다.(block 단위)
  • FIFO file : pipe / unnamed pipe
  • Symbolic link file : 다른 위치를 가리키는 file (ex. 바로가기)

Directory File

  • directory 내의 파일들의 (inode#, filename) 형태로 순서쌍을 정보로 가지는 file
  • directory 또한 file이기 때문에 inode를 가지고 있다.

File Descriptor

  • kernel에서 file을 다루기 위해 kernel에서 file에게 할당해준 음이 아닌 정수
  • 0 : stdin / 1 : stdout / 2 : stderr 로 고정되어 있다.
  • file이 open되면 FDT의 3번부터 할당이 된다.
  • process에서는 최대 1024개의 file만 open할 수 있다.
  • 최대치는 ulimit -a를 입력하면 확인할 수 있다.

Basic File I/O

File open

#include <fcntl.h>

int open(const char *path, int oflag);
int open(const char *path, int oflag, mode_tmode);

  • path : open 또는 create할 filename
  • oflag : options
  • mode : 접근 권한(file 생성 시)
  • return : 성공 시 file descriptor / 실패 시 -1

File close

#include <unistd.h>

int close(int fd);
  • fd : 닫을 file descriptor
  • return : 성공 시 0 / 실패 시 -1

File creation

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int creat(const char *path, mode_tmode);
  • file open으로도 표현이 가능하다.
  • mode : 접근 권한
  • return : 성공 시 file descriptor / 실패 시 -1

File seeking

#include <sys/types.h>
#include <unistd.h>

off_t lseek(int fd, off_t offset, int whence);
  • file의 size를 알고 싶다면 SEEK_END를 사용하면 된다.
  • fd : file descriptor
  • offset : 특정 위치에서 얼마나 떨어져 있는가
  • whence : SEEK_SET, SEEK_CUR, SEEK_END
  • return : 성공 시 변경된 offset / 실패 시 -1

File reading

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t nbyte);
  • fd : file descriptor
  • buf : buffer의 주소
  • nbyte : 읽을 byte의 수
  • return : 성공 시 읽은 byte의 수 / 실패 시 -1
  • nbyte보다 return값이 적게 나온다면 file의 끝인 것을 알 수 있다.

File writing

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t nbyte);
  • buffer 내부의 byte 수 만큼 write
  • fd : file descriptor
  • buf : buffer의 주소
  • nbyte : 쓸 byte의 수
  • return : 성공 시 쓴 byte의 수 / 실패 시 -1
  • nbyte와 retunr byte 수가 일치해야 성공

File Table

  • offset, 위치, 상태, vnode pointer등 모든 정보가 저장되어 있는 곳
  • file system : disk에 위치한다.
  • OS file table : kernel에 위치한다.
  • vnode : inode와 동일한 역할을 한다.

Duplication of file

1) dup(fd)

#include <unistd.h>
int dup(int fd);
  • fd : 복사할 file descriptor
  • FDT에서 처음으로 안쓰는 빈자리를 찾아 같은 file table을 가리키게 한다.
  • OS shell에서 각 process를 연결할 때 유용하게 사용한다.
  • return : 성공 시 복사된 file의 fd / 실패 시 -1

2) dup2(fd1, fd2)

#include <unistd.h>
int dup(int fd);
  • fd1 : 복사할 file descriptor
  • fd2 : 이동하기를 원하는 file descriptor
  • 특별하게 fd2 자리에 저장해야 할 때 사용한다.
  • 만약 fd2자리에 file이 open되어 있었다면, 그 file을 닫고 계속 진행한다.
  • return : 성공 시 복사된 file의 fd / 실패 시 -1
  • return값과 fd2가 대부분의 경우 동일하다.

  • 쉽게 파일을 찾아가도록 하기 위해서 사용한다.

  • link 자체로 target file에 대한 경로를 담고 있는 file이다.
  • target이 지워지면 접근할 수 없고, link가 직접 target에 가야 알 수 있다.
    ex.) "~~~" 해당 파일을 찾을 수 없습니다.
  • soft link도 file이기 대문에 target과 link의 inode는 다르다.
  • target의 inode를 직접적으로 가리킨다. 즉, inode를 공유한다.
  • file이 update되면 같이 update 된다.
  • file이 지워지더라도 다른 hardlink는 file에 접근할 수 있다.
  • inode는 둘 이상 공유될 수 있는 정보이다.
  • inode에는 "reference count"라는 것이 존재하는데, 이는 해당 inode에 접근한 link의 수를 나타내는 것이다.
  • hardlink가 1개 늘면 count도 1 증가 → inode의 count를 보면 hardlink의 수를 알 수 있다.
  • hardlink를 지우면 count 1 감소 → count가 0이 되면 inde 제거
Symbolic link를 따르지 않는 system callSymbolic link를 따르는 system call
lchown, lstat, remove, readlink, rename, unlinkaccess, chdir, chmod, chown, creat, exec, link, mkdir, mkfifo, mknod, open, opendir, pathconf, stat, truncate

Linux cmd

  • Symbolic link :
$ ln –s original_file symbolic_link_name
  • Hard link
$ ln original_file hard_link_name
#include <unistd.h>

int link(const char *existing, const char *new_link);
  • exsiting : original file name
  • new_link : inode를 공유할 file과의 link할 name
  • return : 성공 시 0 / 실패 시 -1
#include <unistd.h>

int symlink(const char *existing, const char *link_name);
  • exsiting : original file name
  • new_link : 가리키는 file과 link할 name
  • return : 성공 시 0 / 실패 시 -1
#include <unistd.h>
int readlink(const char *path, void *buf, size_t bufsize);
  • 해당 link하고 있는 원본 file을 알아내는 함수
  • path : link name
  • buf : buffer의 주소(original file name)
  • bufsize : buffer 크기
  • return : 성공 시 읽은 byte의 수 / 실패 시 -1

File information

1) stat

#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>

int stat(const char *path, struct stat *buf);
  • 경로를 이용하여 file에 대한 정보를 읽어온다.
  • path : file의 path name
  • buf : file의 정보를 담을 구조체의 주소
  • return : 성공 시 0 / 실패 시 -1

1) lstat

int stat(const char *path, struct stat *buf);
  • stat()과 거의 유사하지만 target이 아닌 link file의 정보를 읽어온다.
  • path : link file의 path name
  • buf : link file의 정보를 담을 구조체의 주소
  • return : 성공 시 0 / 실패 시 -1

1) fstat

int stat(const char *path, struct stat *buf);
  • file descriptor를 이용하여 접근한다.
  • file을 열고 fd를 할당한 뒤 이를 이용해야 한다.
  • fd : file descriptor
  • buf : link file의 정보를 담을 구조체의 주소
  • return : 성공 시 0 / 실패 시 -1

구조체에 담기는 정보


Process's Creator

  • process가 생성될 때, process에는 user id가 할당된다.
  • real user(user id) : process를 실행했을 때 명령어를 실행시킨 user
  • effective user : process가 실행되면서 access할 file 등에 대한 권한을 가진 user

getuid / getgid

#include <sys/types.h>
#include <unistd.h>

uid_t getuid(void)
uid_t getgid(void)
  • return : 성공 시 user id, group id / 실패 시 -1

geteuid / getegid

#include <sys/types.h>
#include <unistd.h>

uid_t geteuid(void)
uid_t getegid(void)
  • 일반적으로 uid == euid지만 dynamic system에서 달라질 수 있다.
  • return : 성공 시 effective user id, effective group id / 실패 시 -1

mount

  • 시스템에 외부 장치나 storage 장치를 장착하는 system utility 접근 권한이 없더라도 순간 접근할 수 있도록 해준다.
  • S_ISUID/S_ISGID bit나 S_ISVTX와 같이 sticky bit를 사용하는 경우 effective ID가 file의 owner의 id로 set될 수 있다.
  • ex.) bit를 set하는 방법
$ chmod u+s a.out
$ chmod g+s a.out

Sticky bit(S_ISVTX)

  • 어떤 directory에 대해 설정해줄 수 있는 bit
  • 공용(모든 user가 접근 가능)에서 자신의 것은 수정 가능 / 자신이 생성하지 않은 것은 접근만 되고 수정/삭제가 불가능하게 하는 것.
  • ex.) sticky bit를 set하는 방법
$ chmod o+t/test

File permission attribution

  • file의 permission을 설정하는 방법
  • 파일 종류 : directory / character device file / block device file / socket / Symbolic link

File access permission

#include<unistd.h>

int access(const char *path, int amode);
  • file에 접근이 가능한가 check
  • path : path name
  • amode : R_OK / W_OK / X_OK / F_OK
  • 각 read, write, execute, existence를 check
  • return : 성공 시 0 / 실패 시 -1

Default Permission

  • file default permission : 0666
  • directory default permission : 0777

umask

#include<sys/types.h>
#include<sys/stat.h>

mode_t umask(mode_t cmask);
  • defalut permmsion을 바꾸고 싶을 때 사용하는 함수
  • cmask : 허용하지 않는 권한
  • 허용하지 않는 값으로 설정한다.
  • umask로 설정하면 이후로 바뀐 값이 default permission이 된다.
  • return 이전의 umask
  • ex.) umask = 0222 → default permission = 0644

File permission change

chmod / fchmod

#include<sys/types.h>
#include<sys/stat.h>

int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);

  • file의 permission을 변경할 때 사용하는 함수
  • path : file의 path name
  • fd : file descriptor
  • mode : OR(|)를 통해 적용
  • return : 성공 시 0 / 실패 시 -1

Ownership change

chown / lchown / fchown

#include <unistd.h>
#include <sys/types.h>

int chown(const char *path, uid_t owner, gid_t group);
int lchown(const char *path, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
  • ownership을 변경할 때 사용하는 함수들
  • lchown은 taget을 바꾸는 것이 아닌 link file의 ownership을 변경하는 것
  • path : file의 path name
  • owner : owner의 UID
  • group : group의 GID
  • fd : file descriptor
  • return : 성공 시 0 / 실패 시 -1
profile
안녕하세요 :) Data/AI 공부 중인 한국외대 컴퓨터공학부 조권휘입니다.

0개의 댓글