리눅스 디렉토리와 링크

Jongwon·2021년 12월 10일
0

Linux Programming

목록 보기
16/25

Linux 디렉토리 구조

  • / : 루트 디렉토리
  • /bin : 실행파일들이 모여있음
  • /dev : 디바이스 드라이버
  • /etc : 시스템 설정 파일 및 초기 스크립트 파일
  • /home : 홈 디렉토리
  • /lib : 공유 라이브러리 이미지 포함
  • /proc : 가상 파일 시스템, 시스템에서 운영되는 다양한 프로세서의 내용과 프로그램 정보 가짐
  • /tmp : 임시 파일들이 저장되는 곳
  • /usr : 응용 패키지들이 설치되어 있는 곳
  • /mnt : 각종 입출력장치들의 파일시스템을 마운트 하는 곳
  • /opt : Add-On 소프트웨어 패키지가 설치되는 곳
  • /var : 로그 파일이나 스풀 파일같이 시스템 작동 중 변경되는 파일들이 담겨있음
  • /lost+found : 갑작스런 종료 등으로 손상된 파일이나 디렉토리를 담아두고 fsck(Filesystem Check)를 통해 복구함
  • /media : CD, USB등이 임시로 마운트되는 디렉토리
  • /boot : 리눅스 부팅과 관련한 모든 파일들이 담겨있는 곳
  • /sbin : 슈퍼유저가 시스템 관리용으로 사용하는 명령어가 기록되어 있음


디렉토리 엔트리

디렉토리 엔트리: 자신이 가진 파일이나 디렉토리의 목록

struct dirent {
    ino_t d_inode;             //엔트리가 가리키는 inode
    long d_offset;             //offset
    unsigned short d_reclean;
    size_t dir_name_len;
    int d_type;
    char d_name[NAME_MAX+1]    //파일명

디렉토리 특징

  • 디렉토리 내에 존재하는 파일이나 서브디렉토리를 (Inode, 파일명)의 테이블 형태로 구성함.
  • dir에 execute 권한이 없다면 하위 디렉토리로 넘어갈 수 없다.
  • 트리 형태로 저장된다.
  • 디렉토리 파일에 대한 수정은 커널만 가능하다.

디렉토리 구조체

파일 구조체 FILE처럼 library에서 디렉토리를 접근하는데 필요한 구조체, opendir로 디렉토리를 open하면 DIR 구조체가 반환된다.

struct DIR {
    struct dirent entry;
    ...
}
파일시스템이 알아서 관리하기 때문에 수정할 이유가 없다.



링크

이미 존재하는 파일이나 디렉토리로 연결된 파일

이름은 다르지만 같은 Inode를 가진 파일. 하드링크 파일이 생기면 inode의 link count가 증가. 모든 하드링크 파일과 원본 파일을 삭제해야 파일이 지워진다.
디렉토리 파일의 하드링크는 자칫하면 루프가 발생할 수 있어 root사용자만 만들 수 있다.
다른 디렉토리에 있다면 파일이름이 같아도 되지만, 같은 디렉토리 내의 link면 같아야 한다.

<장점>

  • 디렉토리 엔트리 읽기 -> Inode 읽기 -> Disk Block 읽기의 3단계로 파일로 빠른 접근이 가능

<단점>

  • 같은 파일시스템에 대해서만 link가 가능하다.
  • 디렉토리 파일을 link하면 루프가 발생할 확률이 높다.
  • 파일의 삭제를 보장할 수 없다.

원본과는 다른 바로가기 파일. 심볼릭 링크의 데이터에 원본 파일의 경로에 대한 데이터가 저장되어 있다. 원본 파일이 삭제되면 심볼릭 링크 파일을 열 때 실패를 반환한다.
자체적인 inode를 가진다.

<장점>

  • 하드링크의 단점을 모두 보완

<단점>

  • 디렉토리 엔트리 읽기 -> slink Inode 읽기 -> 디스크블록 읽기 -> 디렉토리 엔트리 읽기 -> Inode 읽기 -> 디스크블록 읽기의 상대적으로 많은 읽기 필요


디렉토리 관련 함수

<unistd.h> 헤더

  • int link(const char path, const char newpath)
    newpath에 path에 대한 하드링크 생성, 성공은 0, -1은 에러
  • int unlink(const char *pathname)
    파일삭제(link count를 1감소), rm 함수 역시 최종적으로는 unlink를 호출, 성공은 0, -1은 에러
    => 이때, link count가 0이 되고, 파일을 참조중인 fd가 없어 reference count도 0이라면 디스크공간과 inode를 시스템에 반납함.
link count vs reference count
reference count는 현재 파일을 open한 프로세스가 몇 개인지 표시
link count는 해당 inode를 가리키는 디렉토리 엔트리의 개수를 나타냄(hard link)
  • int symlink(const char path, const char sympath)
    path에 대한 symbolic link 생성, 경로가 아닌 이름을 주면 현재 dir에 생성, 성공은 0, 에러는 -1
  • int readlink(const char pathname, const char buf, int bufsize)
    bufsize만큼 symlink 데이터를 읽음. buf는 NULL로 끝나지 않아 print 하고싶다면 추가해야함.

  • int rmdir(const char *pathname)
    디렉토리 삭제, link count와 reference count가 0이 되면 디렉토리가 제거됨, 0은 성공, -1은 에러
  • int chdir(const char *pathname)
  • itn fchdir(int fd)
    현재 디렉토리를 pathname(또는 fd)로 변경. 0이면 성공, -1은 에러
    =>이때, 다른 프로세스의 디렉토리는 변경불가
  • char getcwd(char buf, size_t size)
    현재 작업 디렉토리를 buf에 넣어줌, buf가 NULL이면 임의로 메모리 잡고 넣어줌. buf 반환
    =>cwd는 커널이 관리함.

<stdio.h> 헤더

  • int remove(const char *pathname)
    path가 파일이면 unlink처럼 동작, 디렉토리면 rmdir처럼 동작(단 비어있지 않으면 실패), 0이면 성공, -1은 에러
  • int rename(const char oldpath, const char newname)
    파일이나 디렉토리명을 newname으로 변경, newname이 존재하면 overwrite, 변경대상이 디렉토리라면 비어있을 때만 성공, 성공은 0, 에러 -1

<sys/stat.h> 헤더

  • int mkdir(const char *pathname, mode_t mode)
    새로운 디렉토리 생성(.과 ..은 자동생성), 0이면 성공, -1은 에러

<dirent.h> 헤더

  • DIR opendir(const char pathname)
  • struct dirent readdir(DIR dp)
    디렉토리를 읽으려면 읽기 권한이 있어야함. readdir할 때마다 디렉토리 파일의 offset은 sizeof(dirent)만큼 증가
  • void rewinddir(DIR *dp)
    디렉토리의 offset을 맨 처음으로 다시 이동
  • int closedir(DIR *dp)
    DIR을 닫음
profile
Backend Engineer

0개의 댓글