학부 내용 정리/[ 2-1 ] 운영체제

[ OS ] Files and Directories

haena02 2022. 6. 14. 20:32
반응형

파일

- 바이트의 선형 배열

- 각 파일의 가장 기본적인 이름은 inode

- OS는 확장자를 보고 파일의 구조를 알지 못한다.

 

Directory

- 사용자가 읽을 수 있는 이름과 하위 수준의 이름 쌍을 포함한다. (foo , 10)

- 디렉토리의 inode도 있다.

 

1. Creating files

/* open */
int fd = open("foo", O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR);

O_CREAT : 똑같은 이름의 파일이 없다면 생성, 있다면 open

O_WRONLY  : 오직 쓰기 위해 open

O_TRUNC :  파일이 이미 있는 경우 덮어쓴다

S_IRUSR|S_IWUSR : 사용자 권한 지정, 이 경우 소유자가 파일을 읽고 쓸 수 있도록한다.

 

2 Accessing files

 

1.1 File descriptor

 

- 정수의 숫자. 파일의 포인터라고 생각 할 수 있다. 

- 각 프로세스마다 관리하기 때문데 같은 fd를 갖을 수 있다. 

 

echo : 출력해라

> : redirection

즉 첫째줄은 hello라는 것을 foo 파일에 작성해라라고 해석할 수 있다

cat : 보여줘

즉 두번째 줄은 foo 파일을 보여달라는 의미로 해석할 수 있다. 

 

위 사진은 cat 명령어의 내용이다.

첫번째 줄에서 파일을 열고 fd값 3을 리턴한다. 그 파일의 fd 값이 3이라는 의미이다. 그러고 두번 쨰 줄에서 fd가 3인 파일에 hello\n 을 쓰고 6글자라는 의미로 6을 리턴한다. 다음줄에서는 화면에 6글자를 출력하게 한다. std out은 fd가 1이다. 

 

2.2 offset 

 

오프셋은 다음 읽기 또는 쓰기가 파일 내에서 읽기 또는 쓰기를 시작할 위치를 결정한다. 오프셋은 N바이트의 읽기 또는 쓰기가 수행되고 N이 현재 오프셋에 추가된다. 

off_t lseek(int fd, off_t offset, int whence);

SEEK_SET: offset으로 세팅

SEEK_CUR: 현위치 + offset

SEEK_END: 마지막 - offset

 

2.3 open file table

 

시스템에서 현재 열려 있는 모든 파일을 나타낸다. 테이블의 각 항목은 설명자가 참조하는 기본 파일, 현재 오프셋 및 파일을 읽을 수 있는지 또는 쓸 수 있는지와 같은 기타 관련 세부 정보를 추적합니다.

 

//Example (xv6)

struct {
	struct spinlock lock; // 파일 열 때 race conㅇition 이 일어나지 않도록 
	struct file file[NFILE];  // 파일들의 배열
} ftable;

struct file { 
	int ref;   // 몇개가 접근중인지
	char readable, writable; 
	struct inode *ip; 
	uint off; 
};

2.4 write

write() : 이 함수를 사용하면 작성한 내용을 버퍼링하다가 나중에 실제 스토리지에 저장된다.

fsync() : 모든 작성하는 데이터를 강제로 디스크에 보낸다.

 

3. Shared File Entries

 

3.1 Shared file entry by fork()

int main(int argc, char *argv[]) {
	int fd = open("file.txt", O_RDONLY);  // 읽기 전용으로 열기
	assert(fd >= 0);  // 파일 잘 열렸는지
    
	int rc = fork(); // 프로세스 생성
	if (rc == 0) {  // 자식
		rc = lseek(fd, 10, SEEK_SET);  // off set을 10으로 설정
		printf(“C: offset %d\n", rc);  //현재 offset 위치 출력
	} else if (rc > 0) {  //부모
		(void) wait(NULL);  // 자식 기다리기
		printf(“P: offset %d\n", (int) lseek(fd, 0, SEEK_CUR));  //현재 offset 위치 출력
	}
	return 0;
}

/* 결과
child: offset 10
parent: offset 10
*/

 

child와 parent 가 같은 offset을 출력했다.

parent에서는 offset을 수정해준적이 없는데도 말이다.

그 이류는 아래 사진을 보면 알게된다. 

 

위 사진을 보면 부모와 자식 두 프로세스의 PCB를 보면 같은 open file table의 같은 file entry를 가르키고 있는것을 볼 수 있다. 두 프로세스가 한 파일 엔트리를 가르키게되면 그 파일 엔트리의 ref가 2가 되며 같은정보를 공유하게된다.

 

3.2 Shared file entry by dup()

dup() 을 사용하면 프로세스가 기존 파일을 참조하는 새 파일 을 만들 수 있다.

fd는 사용하지 않는 fd 중 가장 작은 fd를 부여받게 된다.

 

int fd=open(“output.txt", O_APPEND|O_WRONLY);  //fd라는 fd를 갖는 파일 오픈
close(1);  //출력담당 fd 1
dup(fd); //ile descriptor 1에 1을 복제한다.

 

4. Removing files

 

4.1 link() (ln)

위 사진은 link()를 활용한 예이다.

link()는 터미널에서 ln으로 쓰이며 두 파일을 연결해주는 역할을 한다.

따라서 ln file file2를 하면 file과 똑같은 file2 가 생기고 이들은 같은 inode를 참조한다.

4.2 unlink (rm) 

위 사진은 unlink()를 활용한 예이다

unlink()은 사용자가 읽을 수 있는 이름과 아이노드 번호 사이의 "링크"를 제거하고, 참조 카운트를 줄이며,

참조 카운트가 0에 도달하는 경우에만 파일을 삭제한다.

 

 

5. Directories

 

5. Making Directories

mkdir() : 빈 디렉토리를 만든다

 

in 상대경로

.  현재경로

. . 현재의 부모경로

 

5.2 Reading Directories

파일을 읽을 때는

opendir()

readdir()

closedir()

 

이 세가지 함수를 쓴다

 

int main(int argc, char *argv[]) {
	DIR *dp = opendir(".");  // 현재 디렉토리의 주소를 불러온다. 상대경로(현재)
	struct dirent *d;  // 디렉토리 엔트리 포인터 선언
	while ((d = readdir(dp)) != NULL) {  // 디렉토리의 엔트리 읽어오기
		printf("%lu %s\n", (unsigned long) d->d_ino, d->d_name);  // 아이노드와 파일 이름 출력
	}
	closedir(dp);  //닫기
	return 0;
}

5.2 Removing Directories

 

rmdir()

디렉토리는 꼭 삭제되어있어야한다. 디렉토리가 비어있을 때만 사용가능하다. 

이 떄 비어있다는 것은 . 와 . . 만 있다는 것이다. 

비어 있지 않은 디렉터리를 삭제하려고 하면 rmdir() 호출이 실패한다.

 

 

6. File system Resource Sharing

 

6.1 Mechanisms for Resource Sharing

프로세스의 추상화를 위해 CPU virtualization 와 memory virtualization 를 한다. 

파일에서도 Disk virtualization를 해줘야한다. 하지만 이는 프로세스의 추상화라는 약간 다르다.

파일은 block에 들어있는 정보들을 어떻게 하면 사용자 친화적이게 제공할 수 있는가에 대한 내용이다.

파일은 유저와 프로세스에게 모두 공개가 됨으로 private 하지 않다. 따라서 Permission bits 가 중요하게 작용한다.

 

6.2 Permission Bits

맨 앞에 한글자는 파일의 타입을 나타낸다.

종류로는 아래와 같이 있다.

 

- : 파일

d : directory

l : symbolic link

 

그 다음 0글자는 Permission bits를 나타낸다.

 

차례대로 사용자, 사용자의 그룹, 제3의 사람을 의미하며

3글자는 읽기 쓰기 접근하기 를 의미한다.

 

Permission bits를 바꿔주기 위해서는 

 

chmod 600 foo.txt

 

이렇게 600 처럼 숫자로 나타내면 된다. 모두 허용은 777이고 모두 불가는 000이다,

 

 

6.3 Making a File System

파일을 만드는것과는 다름.

명령어를 통해서 백지같은 block기반의 디바이스에 파일 시스템을 깔아주는 내용.

 

mkfs -t ext4 /dev/sda1

실제 저 디렉토리를 가면 파일이 있는 것이 아님. 백지같은 block에 파일 시스템 ext4를 깔아준 것이다.

이렇게 되면 파일 시스템이 만들어진다.

 

6.3 Mounting a File System

파일 시스템을 설치한 block에 시스템에 있는 파일과 디렉토리 트리를 연결해주기 위해서는 mounting 을 해줘야한다.

mount -t ext4 /dev/sda1 /home/users

/dev/sda1 와 /home/users를 연결해준다. 

그럼 이제는 /home/user를 통해서 파일 디스크에 접근할 수 있게된다. 

반응형

'학부 내용 정리 > [ 2-1 ] 운영체제' 카테고리의 다른 글

[ OS ] FSCK and Journaling  (0) 2022.06.15
[ OS ] File System Implementation  (0) 2022.06.14
[ OS ] I/O Devices and HDD  (0) 2022.06.13
[ OS ] Common Concurrency Problems  (0) 2022.06.13
[ OS ] Semaphores  (0) 2022.06.13