Linux File System
리눅스 커널은 몇 가지로 모듈화 되어 있음
가장 중요한 것은 disk 안에 있는 파일을 관리 한다는 것
파일에 관련된 인터페이스를 유저에게 제공하는 system call API를 제공
유저는 이 system call API를 통해 커널에 접근 가능
그리고 커널은 자신이 관리하는 구조에 의해서 파일에 대한 쓰기 읽기/접근 권한/삭제/생성 을 관리한다.
- 파일 시스템 안의 각각의 파일들은 inode 를 가진다.
- inode 는 파일에 대한 정보를 관리하는 자료구조이다.
- 일반적으로 파일 시스템은 파일의 데이터 영역(실제 파일이 적혀 있는)과 파일 정보를 관리하는 영역(Metadata)으로 나뉨. Metadata 중 하나가 inode
- inode contents (C struct)
• file name • file type (regular, directory,...)
• file owner id
• 접근권한
rwxr-xr-x (for owner, group, others)
• 접근한 시간, 생성시간, 수정시간
• file size
• file data block addr. table (see the next page!) -> 실제로 파일 데이터가 disk의 어디에 적혀있는지
• ..
Inode structure example
disk I/O를 할 때에는 block 단위 개념으로 데이터를 주고 받음
block size는 512byte, 1kb, 2kb, 4kb 그정도 크기
요즘은 대부분 block 크기는 4kb 임.
block 의 address 를 파일마다 할당해줌 -> 그럼 할당된 block number 가 있을 텐데 이걸 inode 에 적어주는 것임.
inode 의 첫번째에 정보들이 있고, 할당된 block number 를 관리하는 table이 있음
Linux File System (2)
File types
• regular file <- 대부분 파일은 이거임
• directory file
• FIFO file (pipe)
• special files (IO devices)
• symbolic link files
Directory file
디렉토리를 파일의 형태로 나타내는 것임. 리눅스에서는 디렉토리도 하나의 파일로 관리를 한다.
• 디렉토리는 그 디렉토리가 가지고 있는 파일에 대한 inode #(number), 파일 이름과 같은 리스트 정보를 가지는 파일이다.
• inode is a data structure which contains all the information about the file and file data blocks
• inode # is a unique file id number in the file system
• “ls –al john” is a shell command that just displays the “john” directory file
Linux File Types
Ordinary File (Regular File)
• 텍스트, 이미지, 비디오, 실행파일, 오디오파일 - binary files
Directory File
• 자신이 가진 파일에 대한 정보(the set of (file-name, inode #))를 담고 있음
Special File은 두 가지
IO 디바이스에 대한 IO연산을 도와주는 기능 제공
시스템에 연결된 각종 IO 장치에 user 가 접근하도록 만들어주기 위해 file 형태의 구조체를 통해서 장치에 접근할 수 있는 통로를 만들어 주는 파일
Character Special File
• Character-oriented device에 대한 접근을 할 수 있도록 해줌 (e.g. Keyboard //character 형태로 된 디바이스)
Block Special File
• Block-oriented device에 대한 접근을 할 수 있도록 해줌(e.g. HDD file systems, eth0 )
FIFO file
파이프 형태, 프로세스간 데이터를 주고받기 위한 통로
• Named pipe / Unnamed pipe cf. pipe in a process is usually unnamed.
Symbolic link file
다른 파일에 대해서 우회로 접근할 수 있는 경로를 만들어주는 파일
• a file which points to another file cf. hardlink is NOT a file.
File Descriptor
커널에서 파일을 handle 하기 위해 파일에 할당해준 a small, non-negative integer
inode 는 파일 시스템(매체)에서 파일을 구분하기 위한 정보를 쓰는 것
실제 그것이 커널에서 사용될때에는 inode 의 정보가 쓰이는 것이 아니고 file descriptor 라고 하는 정보로 파일을 커널 내부에서 사용. 반환값이라고 하는게 file descriptor 라고 하는 것.
• Traditionally, stdin(표준 입력), stdout(표준 출력) and stderr(표준 에러) are 0, 1 and 2 respectively.
• Relying on “magic numbers” is BAD. – Use STDIN_FILENO, STDOUT_FILENO and STDERR_FILENO defined in or stdin, stdout, and stderr defined in .
Maximum number of files
• 프로세스는 1024개의 파일을 열 수 있다.
• we can check the system resource configuration.
Basic File I/Os
가장 기본이 되는 유닉스/리눅스 파일 I/Os 5가지
• open(2)
• close(2)
• lseek(2)
• read(2)
• write(2)
File open
#include <fcntl.h>
int open(const char *path, int oflag);
int open(const char *path, int oflag, mode_t mode)
parameters
• path: 열거나 생성할 파일의 이름
• oflag: 파일 열기 옵션
• mode: 접근권한 (at file creation)
return
• file descriptor if OK
• 1 on error
oflag options
• must be one of these
option1 | meaning | defined |
O_RDONLY | 읽기 | 0 |
O_WRONLY | 쓰기 | 1 |
O_RDWR | 읽고 쓰기 | 2 |
• and can be OR’ed with any of these (by “|”)
option2 | meaning |
O_CREAT | 파일이 존재하지 않으면 생성 |
O_EXCL | used with O_CREAT, 이미 파일이 존재하면 에러 return |
O_TRUNC | 파일이 존재하면 empty(파일크기0)로 만들기 |
O_APPEND | 파일의 마지막위치부터 쓰기 |
O_SYNC | 파일을 I/O 할때 disk 동기화를 하기 |
File access modes
File close
커널 내부에서 메모리를 잡고있는 data structure 를 해제시켜줌.
열린 파일에 대해서 유저가 닫아줄 필요가 있음.
#include <unistd.h>
int close(int fd);
parameters
• fd: file descriptor
return
• 0 if OK
• -1 on error
File open example
File creation
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int creat(const char *path, mode_t mode)
parameters
• path : 파일 이름
• mode : 접근 권한
return
• file descriptor if OK
• -1 on error
File seeking
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
parameters
• fd : file descriptor
• offset : offset from the beginning to seek (move)
• whence : SEEK_SET, SEEK_CUR, SEEK_END
return
• new offset value if OK
• -1 on error
File reading
buffer 에서 데이터를 읽는다.
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t nbyte)
parameters
• fd : file descriptor
• buf : buffer address
• nbyte : number of bytes to read
return
• number of bytes read successfully if OK
• -1 on error
File writing
write 할 땐 buffer 에 data가 있어야 한다.
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t nbyte)
parameters
• fd : file descriptor
• buf : buffer address
• nbyte : number of bytes to write
return
• number of bytes written successfully if OK
• -1 on error
File create/lseek example
File copy example (1)
File copy example (2)
File descriptors & File table
두 개의 프로세스(프로그램)에서 각각 파일에 대한 연산을 한다고 했을 경우 각각의 프로세스에서는 file descriptor를 관리한다
각가의 파일에 대해서 운영체제 레벨(OS level)에서는 어떤 파일의 descriptor 가 생성되었는지를 global하게 파일 table을 관리한다. 그래서 각각의 프로세스는 해당되는 file descriptor에 접근할 수 있게 되고
실제적으로 이 데이터는 파일 시스템에서 관리가 되고
파일 시스템에 있는 inode 라고 하는 객체를 통해서 실제 데이터를 매체로 쓰도록 되어 있다.
이 통로는 파일 테이블에 있는 각각 파일 객체의 v-node pointer을 통해 파일 시스템에 있는실제 파일에 대해서 접근할수 있게 됨. 그리고 inode 정보를 통해 실제 파일의 데이터 block, 정보에 접근할 수 있다.
Duplication of file descriptor (1)
동일한 파일에 대해서 동일하게 접근하는 중복된 file descriptor를 만들 수 있다.
#include <unistd.h>
int dup(int fd);
parameters
• fd : file descriptor to duplicate
return
• newly duplicated file descriptor if OK
• -1 on error
dup과 동일한 기능을 하지만, 기존에 생성된 file descriptor 에 대해서 복제된 또다른 파일 지정자를 argument로 만들어냄.
#include <unistd.h>
int dup2(int fd1, int fd2);
parameters
• fd1 : source file descriptor
• fd2 : destination file descriptor
return
• copied file descriptor (should be same as fd2) if OK
• -1 on error
note
• functionally same as dup except that dup2 designates destination file descriptor (fd2) the user wants
I/O redirection example (1)
I/O redirection example (2)
화면에는 Hello, world! !(1) 이랑 (3)이 출력되고
(2)는 test.txt 라는 파일에 기록이 됨.
Link (1)
Symbolic link
• soft link 라고도 불림
• 원본 파일에 대해서 그 파일 이름에 link함. 파일에는 타겟으로 하는 파일의 path가 기록됨.
파일에 대한 실제적인 내용을 가지고 있는 것은 아님.
• 타겟 파일이 지워지면, 링크는 더이상 유효하지 않음, 하지만 symbolic link 파일은 여전히 존재.
Hard link
• 존재하는 inode를 가리키는 link. 실제 파일 시스템 정보를 가짐.
• an inode can be shared by two or more filenames (hardlinks)
• 파일이 업데이트 되면, 업데이트 된 것을 모든 hard link 파일에서 볼 수 있음
• 파일이 삭제되더라도, hard link가 남아있기 때문에 또 다른 hard link를 통해 파일의 접근할 수 있다.
Link (2)
Linux command
• symbolic link:
$ ln –s original_file symbolic_link
• hard link:
$ ln original_file hard_link_name
Hard link
#include <unistd.h>
int link(const char *existing, const char *new_link);
parameters
• existing : original file name
• new_link : new link name which will share the inode of existing file
return
• 0 if OK
• -1 on error
File permission attributes
Process’s Creator (1)
#include <sys/types.h>
#include <unistd.h>
uid_t getuid(void) // process creator’s uid
return
• user ID of the process if OK
• -1 on error
#include <sys/types.h>
#include <unistd.h>
uid_t getgid(void) // process creator’s gid
return
• group ID of the process if OK
• -1 on error
uid_t geteuid(void)
return
• effective user ID of the process if OK
• -1 on error note
• process’s effective user id is used as a key for a kernel’s protection system, and normally uid = euid,
• but sometimes euid is a different one from uid for the dynamic protection system,
uid_t getegid(void)
return
• effective group ID of the process if OK
• -1 on error
File’s ID
When a process is created, the user(creator)’s IDs are assigned to the process.
But, in the following cases, a process’s effective IDs are set to a file owner’s IDs
• if we run a program file with S_ISUID (or S_ISGID) bit, the process’s UID is not my UID, but the file owner’s UID (or S_ISGID).
How to set the bits (example)
$ chmod u+s a.out
$ chmod g+s a.out
Example
$ ls –al /bin
-rwsr-xr-x 1 root root 26492 Dec 1 2017 moun
• this mount command is executed, the mount process’s UID is set to root, not the user.
-> i.e. with the root’s authority, the mount will be run!
Sticky bit: S_ISVTX
In a directory with sticky bit
• 유저는 그들만의 파일이나 directory에 대한 subdirectory를 만들 수 있다.
• but, each file can be deleted only by its owner or supervisor.
Example
자신이 생성하지 않은 파일은 지울 수 없음.
File access of a process
File access (read/write/execute) is allowed in the following cases
• 만약 프로세스의 effective UID가 0인경우 (supervisor)
•만약 프로세스의 effective UID가 파일의 소유자와 같을 경우, 그리고 소유자의 접근 권한 bit가 설정되어있는 경우
• 만약 프로세스의 effective UID가 파일의 소유자와 같을 경우, 그리고 그룹의 접근 권한 bit가 설정되어 있는 경우
• 만약 접근권한이 누구든지 사용할 수 있도록 설정되어 있는 경우
File’s access permission
#include<unistd.h>
int access(const char *path, int amode);
프로세스가 path 에 있는 파일에 접근할 수 있는지 체크
parameter
• path : path 이름
• amode : 체크하고 싶은 접근 모드가 무엇인지
return
• 0 if OK
• -1 on error
Permission check example
Default permission change
#include<sys/types.h>
#include<sys/stat.h>
mode_t umask(mode_t cmask);
By default
• 디폴트로, 파일의 permission 은 0666 (rw-rw-rw) 로 설정됨
• 디폴트로, directory의 permission 은 0777 (rwxrwxrwx) 로 설정됨
umask() changes the default permission
• set unmask which masks off (i.e. not permits)
• e.g. if umask is 0022, a new file permission is set to 0644
parameter
• cmask : new umask
return
• previous umask
umask value
OR’ed combination of these modes mode meaning
File permission change
#include<sys/types.h>
#include<sys/stat.h>
int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);
파일의 권한 모드를 바꾸기
• 파일의 owner나 supervisor(root)가 이것을 할 수 있음
parameters
• path : 파일의 path 이름
• 바꿀 새로운 접근권한 - 모드는 또한 접근 모드의 OR'ed combination이다(see previous)
• fd : file descriptor
return
• 0 if OK, -1 on error
Permission change example (1)
Ownership change
#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);
// doesn’t follow links
int fchown(int fd, uid_t owner, gid_t group);
parameters
• path : 파일의 path 이름
• owner : owner의 UID
• group : group의 GID
• fd : file descriptor
return
• 0 if OK, -1 on error
Ownership change example (1)
Hard link example
Symbolic link
#include <unistd.h>
int symlink(const char *existing, const char *link_name);
parameters
• existing : 기존의 파일 이름
• link_name : 존재하는 파일을 가리키는 link의 이름
return
• 0 if OK
• -1 on error
Symbolic link example
“mylink” 파일의 포함하는 것은 무엇인가?
• “myfile” -> 따라서 파일의 크기는 6 bytes.
system calls and symbolic links
Following a link (1)
#include <unistd.h>
int readlink(const char *path, void *buf, size_t bufsize);
parameters
• path : link 이름
• buf : buffer의 주소 (기존 파일 이름)
• bufsize : buffer의 크기
return
• number of bytes read if OK
• -1 on error
Following a link example (1)
File information retrieval (1)
파일에 대한 여러가지 정보를 가져올 수 있는 system call
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
int stat(const char *path, struct stat *buf);
parameters
• path : 파일 path 이름
• buf : (파일의 정보를 포함한) struct stat의 주소
return
• 0 if OK
• -1 on error
int lstat(const char *path, struct stat *buf);
기본적으로 stat()와 같다, 하지만
• 파일이 symbolic link인 경우, 링크가 원본파일이 아닌 링크파일 자체에 대한 정보를 받아옴
parameters
• path : 파일 path 이름
• buf : (파일의 정보를 포함한) struct stat의 주소
return
• 0 if OK
• -1 on error
int fstat(int fd, struct stat *buf)
parameters
• fd : file descriptor
• buf : (파일의 정보를 포함한) struct stat의 주소
return
• 0 if OK
• -1 on error
struct stat fields
Macros for struct stat
File stat example