2.3.2 Namespaces

 Namespace는 하나의 수행되는 시스템에 서로 다른 관점을 제공하는 것처럼 하는 lightweight 한 가상화의 형태를 제공하는 것이다. 이 매커니즘은 FreeBSD 의 jail 이나 Solaris의 zone과 비슷한 것이다. 

Concept
 전통적으로, Unix 계열의 시스템 뿐만아니라 Linux에서는 시스템이 가지고 있는 많은 자원을 전체적으로 관리한다. 예를 들어, 시스템에 있는 모든 process들은 그것들이 가지고 있는 PID 숫자로 확인되며, 이 PID 리스트는 커널에서 관리되어야 한다. 마찬가지로, uname system call로 반환된 시스템에 관한 정보는(kernel에 관한 약간의 정보와 system의 이름을 반환) 호출한 모든 사용자가 같은 값을 볼 수 있을 것이다. User ID 또한 이와 비슷한 방법으로 관리된다 : 각 user는 시스템에 유일한 UID 값을 가진다. 

uname -r : kernel version 확인
uname -a : system 정보 및 kernel 정보

User 의 ID는 kernel이 선택적으로 특정 권한에 대한 행동을 승인 혹은 거부를 한다. UID 0을 가진 root user는 기본적으로 모든 명령 및 행동이 가능하지만 0 이상의 값을 가진 UID는 제한적 기능만을 제공한다. PID n 의 값을 가진 user가 있다면, 자신의 pid n과 다른 m의 user가 실행 시킨 process는 시스템에서 제거할 수 없다. (ps -ef 명령으로 각 process의 pid와 uid를 확인할 수 있다). 물론 ps 명령어로 다른 사용자가 실행한 process는 확인 가능하다. User N은 다른 User M이 이 시스템에 활성화(사용하고 있는지)가 되어 있는지 볼 수 있다. 이것은 사용자가 자신이 가지고 있는 process들만 가지고 놀 수(?) 있는 한 다른 사용자가 가지고 있는 process를 관찰하는 것까지 막을 필요가 없기 때문에 아무 문제가 되지 않는다. 

 그러나 위의 경우를 원치 않은 경우가 있다. web 공급자가 고객들에게 Linux 시스템에 root 권한을 비롯한 모든 접근 권한을 주는 경우를 생각해 보자. 그렇다면 web service를 제공하는 고객들 한명당 하나의 linux 머신을 제공해야 하기 때문에 엄청난 비용이 든다. 그래서 KVM이나 VMware같은 가상화 환경으로 제공하면 이같은 문제를 해결 할 수 있지만, 이 가상화 방법은 시스템의 자원을 원할하게 분배하지 못하는 단점이 있다. 가상화 시스템은 각 고객들에게 분리된 kernel을 제공해야하는 것이 요구되며, 각 가상화 머신에 리눅스를 각각 설치를 해주고 설정을 완료해 줘야 한다. 

 다른 해결책으로는 namespace를 통해 가상화보다 적은 자원을 들여 같은 서비스를 제공할 수 있다. 하나의 물리적인 머신에 여러 커널을 수행하는 가상화 시스템(물론 서로 다른 운영체제를 수행하는데는 이 방법이 더 좋다)을 제공하는 대신에 하나의 물리적인 머신에 하나의 커널이 수행되고 namespace내부에 미리 모든 시스템의 자원을 추상화 해놓는 것이다. 이것은 하나의 container 에 process 그룹을 넣어두고 다른 container(물론 여기도 process 그룹이..)와는 완벽히 분리 해놓은 것이다. 이러한 분리는 하나의 container에 묶인 사용자들이 다른 container로의 연결을 할 수 없다. 그렇지만 container가 유지되는 동안 특정 경우에 다른 container와 공유하기 위해 그 container의 분리를 느슨하게(?) 할 수 있다. 예를 들어 container안의 PID 의 셋을 가지고 운영되지만, 서로 다른 container와 filesystem의 부분은 여전히 공유 될 수 있다. 

Namespace는 기본적으로 시스템의 다른 view를 생성한다. 모든 이전에 생성된 자원은 container data 구조체로 싸여져 있어야 하고 자원의 리스트 셋과 namespace에 포함하는 내용은 시스템 내부에서 유일해야 한다. 주어진 container 안에서 그 자원이 충분히 활용하고 있지만 외부에 그 자원의  고유 identity(예를 들어 PID, 아래의 예제확인)를 제공하지 않는다. (내부에서만 사용하고 운영한다는 얘기인듯.) 그림 2-3이 상황을 개략적으로 볼 수 있다. 

//그림 2-3  --> 나중에...

세 개의 서로 다른 namespace가 시스템이 있다고 생각해 보자. namespace는 계층적으로 연결될 수 있다고 고려되었다. 하나는 parent namespace이고 이는 두개의 child namespace를 생성했다. 이 container들은 각각 하나의 linux 머신에서 제공되는 것처럼 보이도록 하여 web 호스팅 설정을 할 수 있게 제공한다고 가정하자. 각 container에서는 각각 pid 가 0 인 init task를 가지고 있어야 하며 오름차순으로 생성된 다른 task들을 가지고 있어야 한다. 두 child namespace 내부에는 init task(PID == 0)인 것과 2, 3의 pid를 가지는 task가 있다.(그림 2-3) PID 값은 하나의 시스템에서 고유의 값을 가지므로 이런 식으로 container 내부에서 가지는 pid의 값은 시스템 전체에서 고유의 값이 될 수 없다. 

child container는 시스템의 다른 container에게 자신의 상태를 알려주거나 연결이 되지 않기 때문에 parent container에서 child 관련 정보를 취급해서 child 내부에서 실행되는 모든 process를 볼 수 있어야 한다. 그림 2-3 에서 parent 4~9번 process는 child의 process와 대응되어 있다. 비록 시스템에는 9개의 process들이 있는 것이지만 4~9번의 PID를 가진 process는 하나 이상의 PID를 가지기 때문에 실제적으로 15 개의 PID가 요구된다. 

Namespace는 만약 간결한 분량의 container를 포함하는 경우 비계층적 구조(위의 계층적 구조와는 다른)를 가질 수 있다.(UTS Namespace의 예제를 보면서 확인하자)

꽤나 오래전에 linux는 chroot 시스템 콜을 이용한 간단한 형태의 namespace를 지원하고 있었다.  이 방법은 filesystem의 특정 부분을 동작중인 process들이 root 디렉토리로 인식함으로써 설정된 디렉토리 밖에서 접근 하지 못하도록 진행하는 것이어서 이것 또한 namespace의 한 형태라고 볼 수 있다. 하지만 진정한 namespace는 단지 filesystem을 제어하는 것 이외에도 많은 것을 컨트롤 할 수 있도록 만들어 주는 것이다. 

namespace를 만드는 방법은 두 가지가 있다. 
1. 새로운 process가 fork나 clone 시스템 콜로 생성될 때, 특정 option으로 parent process와 namespace가 공유될 수 있도록 만들어 질 수 있다. 또는 새로운 namespace 가 생성될 수 있다. 

2. unshare 시스템 콜로 parent 로 부터 생성된 process를 분리하고 새로운 namespace를 할당 할수 있다. manual page 를 확인 하자(unshare(2))

관련 자료를 검색 중 찾은 간단한 예제로 확인해 보자
 
http://woodz.tistory.com/23 <-- namespace 의 간단한 실습 내용.

Posted by cyj4369
,

2.3.1 Process Types

 일반적인 Unix process는 binary code로 구성되고 chronological(연대순의, 번역하기가 어려운 단어라..) thread (컴퓨터는 한시점에 코드를 통해 한시점에 하나의 경로로 실행하는 의미의 말) 그리고 application에게 할당된 자원의 셋(메모리, 파일 등)을 가진 것이다. 새로운 process들은 fork exec 시스템 콜의 조합으로 생성된다. 

□ fork 는 현재 process를 복제하여 생성한다. 이 복사본은 child process라 불린다. 원래의 process의 모든 자원은 적절한 방법으로 복사되어 시스템 콜 이후에 최초 process의 독립적인 두개의 객체가 있게 된다. 이 객체들은 어떤 방법으로 연결되어 있진 않지만, 열린 파일, 같은 작업 디렉토리, 메모리의 같은 데이터(data의 복사본을 각각 가지고 있게됨) 등을 가지고 있다. 

□ exec 는 수행중인 process를 실행 가능한 binary 파일로 부터 다른 application 을 로드한다. 결국 새로운 program을 로드한다는 말이다. exec 은 새로운 process를 생성하지 못하기 때문에 fork 시스템 콜로 process를 새로 복사한 후, 시스템에 추가적인 새로운 application을 생성하기 위해 exec을 호출한다. 

Linux는 위 두개의 system call 이외에 추가적인 clone 시스템 콜을 제공한다. 원칙적으로는 clone 은 fork와 같은 방식으로 구동된다. 하지만 새로 생성된 process는 그것의 parent process와 완전히 독립적이지 않으며 parent와 몇몇 자원은 공유한다. 이 시스템 콜은 어떤 자원은 복사되고, 어떤 자원은 공유하게 하는지에 정의가 가능하다.-예를 들면, memory에 있는 data, 열린 파일들, signal handler등이 있다. 

clone은 tread를 구현할 때 사용된다. 그렇지만 thread를 수행하기 위해서는 이것만 가지고는 할 수 없다. user level에서 완전히 실행되기 위해서는 라이브러리들이 필요하다. 예를 들면, Linuxthreads 와 Next Generation Posix Threads와 같은 라이브러리 들이다. 

Posted by cyj4369
,

Chapter 2, Process Management and Scheduling



2.3 Process Representation
Process와 program에 관련된 Linux Kernel의 모든 알고리즘은 include/sched.h 에 정의되어 있는 task_struct 라는 data 자료구조 내부에 있다. 이 자료구조는 시스템의 중심적 역할은 하는 것들 중에 하나이다. scheduler의 구현부를 다루기 전에, 이 기본적인 자료구조를 알아야 한다. 

task 구조체는 많은 process를 연결하는 요소들을 포함하고 있다. 구조체 내부의 요소들을 잘 알지 못하고는 차후에 나오는 내용을 이해시키기는 어려울 것이다. 

task 구조체는 다음과 같이 정의되어 있다.

task_struct 소스 내용을 모두 넣는 것이 쓰는 사람도 읽는 사람도 불편할 것이니 다른 방법을 사용한다. 물론, 필요한 부분은 넣어야겠지..


task_struct 의 링크는 
이다. 링크에서 보는 바와 같이 2.6.37.1 version 의 소스이다. 책의 내용과 조금 차이가 있을 수 있다. 

소스를 보면 알겠지만, 이 구조체의 많은 정보를 다 소화하기란 어려운 일일 것이다. 그렇지만, 이 구조체를 process의 특정 한 상태를 표현하는 등의 부분 부분으로 나누어 본다면 조금 수월할 것이다. 

□ Process 상태 및 실행 정보 : 지연된 signal, 사용된 binary 포멧(또한 다른 시스템의 binary 포멧을 위한 emulation 정보 등), process ID(pid), 자신의 부모 process 및 관련 process의 연결 포인터, 우선순위 값, 마지막으로 program을 실행한 시간 정보(CPU time)

□ 할당된 가상 메모리(virtual memory) 정보

□ process 자격 : user ID, group ID, process가 특정 명령을 수행할 권한 정보 등. System call 을 통해 process 정보등을 확인 하고 변경할 수 있다. 

□ 사용된 file : program code를 포함하는 binary file 뿐만 아니라 process가 다루는 모든 file의 filesystem 정보는 저장해야한다. 

□ Thread 정보, process의 CPU 관련 runtime data 를 기록하게 됨.(그 외 남은 구조체의 field 는 사용된 하드웨어와 의존적이지 않다 - stack 정보같은 것인듯.)

□ 다른 process와 함께 같이 작업할 때, Process간 통신(Interprocess Communication)에 대한 정보

□ process가 signal에 응답하기 위해 등록한 signal handler

task 구조체는 간단하게 값들이 구성되어 있지 않다. 각종 data를 연결하기 위한 포인터 등으로 구성되어 있다. 중요한 변수들 몇몇을 자세히 설명해본다. 



state 는 process의 현재 상태를 기술한다. (volatile long으로 선언됨) 

□ TASK_RUNNING : Task가 수행 가능한 상태이다. 이것은 실제 CPU에 할당되어 수행중이라는 것은 아니다. scheduler에 의해 선택될 때까지 이 task는 기다릴 수 있다. 이 상태는 process가 실행 가능한 상태이며 외부 event를 기다리고 있지 않다는 것이다. 

□ TASK_INTERRUPTIBLE : 어떤 event를 기다리는 잠자고 있는(sleeping) process를 위한 설정이다. 기다리던 event가 발생하게 되면, 이 상태는 TASK_RUNNING 으로 변경되면 scheduler에 의해 선택되면 바로 실행이 가능하게 된다. 

□ TASK_UNINTERRUPTIBLE : kernel의 명령으로 잠들어 있는 process를 disable 시킨 상태. kernel이 직접 해제하지 않는다면, 외부 signal에 의해 깨어나 수행할 수 없다.

□ TASK_STOP : process가 특정목적을 위해 멈춰있는 경우이다.(예를 들면, debugger의 break point에서 멈추게 함.)

□ TASK_TRACED : 이 process의 상태는 ptrace 매커니즘을 이용해 process가 특정 시점에서 trace되고 있는 상태로 일반적인 STOP 된 task와 구별하기 위함이다. 

이 다음에 나오는 상수는 종료되는 process의 상태를 나타내준다. 이것은 exit_state 항목에 저장된다.
□ EXIT_ZOMBIE : 2.2 에서 설명된 zombie 상태를 나타낸다.

□ EXIT_DEAD : 시스템에서 완전히 제거되기 전에 parent process에서 알맞은 wait system call을 호출한 뒤의 process 상태. 이 상태는 하나의 task 안에서 여러 개의 thread가 수행될 때 중요하게 사용되는 상태이다. 

Linux는 process의 시스템 resource 사용 제한을 위해 resource limit (rlimit) 메커니즘을 제공한다. 이 메커니즘은 task_struct 안에 signal 구조체 포인터가 있다. process signal 관리를 위한 구조체 내부에 rlim이라는 배열이 존재한다. ( 아마 책에는 task_struct 내부에 rlim 배열이 있다고 하는데, 소스를 보니 task_struct --> singal_struct *signal-->struct rlimit rlim[] 로 되어 있다.)

rlimit 구조체는 include/linux/resource.h 에 정의되어 있다.  

이 정의(definition)은 다른 많은 resource를 수용하기 위해 매우 일반적으로(?) 유지된다. 
□ rlim_cur : process의 현재 자원 제한. 이것은 soft limit 로 참조된다.
□ rlim_max : process가 허가된 최대 자원의 제한. 이것은 hard limit 으로써 참조된다.

setrlimit system call은 현재 자원제한을 증가시키거나 감소시키는데 사용한다. 그렇지만 이 값은 rlimt_max 값을 초과할 수 없다. getrlimit system call로 현재 limit 값을 확인 할 수 있다. 

이 제한적인 자원은 rlim 배열의 index로 자신의 위치를 확인 할 수 있는데, 이것은 kernel에서 상수값으로 미리 정의를 해두어 연결된 자원과 배열의 위치를 연결했다. Table 2-1을 보면 정의된 상수와 그것의 의미를 기술했다. System programming 책을 보면 자원 제한관련 예제 및 더 상세한 내용을 볼 수 있다. 또한, setrlimit(2) man page를 봐도 조금 더 자세한 내용을 볼 수 있다. 

 Linux 는 특정 유닉스 시스템과 binary 호완성을 제공하기 위한 노력을 해왔기 때문에 아키텍쳐 마다 상수의 값들은 서로 다를 수 있다.

limit은 kernel의 매우 다른 부분과 연관되어 있기 때문에, kernel은 반드시 대응되는 하위 시스템의 limit 값을 확인해야 한다. 

만약 resource type이 limits(거의 모든 자원의 기본 설정임) 설정 없이 사용되었다면, RLIM_INFINITY 의 값으로 rlim_max 가 설정된 것이다. 예외적으로 사용된 경우를 보자, 
□ 열린 파일들의 수(RLIMIT_NOFILE, 기본적으로 1024로 제한한다.)
□ 사용자가 가질 수 있는 process의 개수(RLIMIT_NRPROC)은 "max_thread / 2"로 정의한다. 여기서 max_thread는 global 변수이며, 가용한 RAM의 1/8이 thread 정보를 관리하는데만 사용하고 20개의 thread가 최소의 메모리만을 사용하도록 thread의 생성 개수를 정의한다. (이문장은 번역에 어려움을 겪어 최대한으로 부드럽게 하려고 노력하였음.)

init task를 위한 부팅 때 자원 자한은 include/asm-generic-resouce.h 안에 INIT_RLIMTS 로 정의되어 있다. 

각 process의 proc filesystem을 통해 rlimit 값을 확인 할 수 있다. 
현재 나의 system 정보는 : VMware Server 2.0.1에 Ubuntu 10.10을 설치했다. 10.10의 kernel version은 2.6.35-22 다. 
rlimit 값을 확인 하기 위해, 

proc/self/limits 파일을 읽었다. proc file system의 self 라는 file은 symbolic link 이며 현재 수행중인 process를 가르키고 있다. 

Table 2-1: Process 관련 자원 제한. 
 상수 의미
 RLIMIT_CPU 최대 할당 할 수 있는 CPU 시간
 RLIMIT_FSIZE 사용할 수 있는 file 최대 크기
 RLIMIT_DATA data segment의 최대 크기
 RLIMIT_STACK (user mode) stack의 최대 크기
 RLIMIT_COREcore dump file의 최대 크기 
 RLIMIT_RSS Resident Size Set 의 최대 크기; 다른 말로는 process가 사용할 수 있는 
최대 page frame의 개수이다. 현재 사용되지 않은 것도 포함함.
 RLMIT_NPROC 실제 UID 에 연관된 사용자가 하나의 process를 가지고 생성할 수 있는
process의 최대 개수(fork의 제한 인듯) - 조금 더 알아봐야 할듯.
 RLIMIT_NOFILE 하나의 process가 제어할 수 있는 파일의 개수(open files)
 RLIMIT_MEMLOCK swap 되지 않도록 할 수 있는 page 의 개수
 RLIMIT_AS 하나의 process가 차지할 수 있는 가상 주소 공간의 최대 사이즈
 RLIMIT_LOCKS file lock의 최대 개수
 RLIMIT_SIGPENDING 지연된 signal의 최대 개수
 RLIMIT_MSGQUEUE message queue의 최대 개수
 RLIMIT_NICE non-real time process들을 위한 최대 nice 레벨
 RLIMIT_RTPRIO real time 우선 순위의 최대치.

Posted by cyj4369
,

Chapter 2, Process Management and Scheduling


2.2.1 Preemptive Multitasking
 Linux process 관리 구조를 알기 위해서는 process 실행의 두가지 모드를 알아야한다.(kernel mode와 user mode) 요즘 출시되는 CPU들은 최소한 두가지 다른 실행 모드가 존재하며, 한가지는 제한이 없는 권한을 가지고 실행되며 다른 한가지는 다양한 제한이 걸려있는 상태로 실행된다는 것이다.(제한이 있다는 것에 예를 들면, 특정 물리 메모리 영역을 접근하는 것 등이 될 것이다.) 이런 구분은 시스템의 어떤 한 부분을 간섭하는 것을 보호하고 시스템에 존재하는 process들을 잡아(?-다른 process들에게 넘어가거나 접근하는 것을 막는다는 뜻인가) 둘수있는 잠겨진 "새장과 같은" 것을 생성해줘야 한다. 

일반적으로 kernel은 자신이 가지고 있는 data 만 접근 가능하고 시스템에 있는 다른 application에게 간섭할 수 없는 user mode 안에 있다.(이 부분은 무슨 말인지 써놓고 무슨말인지 확실치 않다.)

만약 한 process가 system data나 함수들의 접근을 원한다면(후자는 모든 process들 사이에 공유된 자원을 관리한다, 예- filesystem 영역) 반드시 kernel mode로 변경하여 수행해야 한다. 물론 kernel mode에서 통제되고(만약 그렇지 않으면, 현재 만들어진 보호 매커니즘이 모두 불필요해지는 것이다. ) 명확히 정해진 루틴으로 실행되어야 한다. 이와 같은 것은 system call 이라는 특별한 함수를 통해 이루어진다. 자세한 사항은 13장에서 더 자세히..

user mode로 부터 kernel mode로의 전환은 interrupt에 의해서도 일어난다.(이것은 interrupt 발생시 자동으로 전환된다.) user application에서 의도적으로 호출되는 system call(system data나 함수를 이용 목적을 위해)과는 달리 독단적(?)으로 수행된다. -의도되지 않은 상태에서 발생함- interrupt의 발생은 현재 process실행과 무관하게 처리해 줄 수 있어야 한다. 예를 들면, 외부 블럭(block) 장치에서 요청한 data를 RAM 으로 복사 완료되면 이 data가 시스템의 어떤 process를 위한 것이었던 간에 interrupt는 발생하게 된다. 비슷하게, network 장치에서도 interrupt를 통해 data package 도착을 알려주게 된다. 반면, network으로 들어온 package는 interrupt를 받아 처리함에 있어 그 data는 현재 수행되고 있는 process에게 전달 된다.(외부 블럭 예제와는 다른 경우 인 것이다.) Linux는 interrupt를 다르게 처리를 하지만, 수행되고 있는 process들은 이같은 상황을 모르고 자신의 작업을 진행한다. 

Kernel의 선점 scheduling 모델은 어떤 상태의 process가 interrupt를 받는지에 대한 구조를 만들어 두었다.

□ Normal Process는 항상 interrupt를 받을 수 있다.(다른 process에 의한 interrupt 발생조차도 다 받는다). 중요한 process(오랫동안 keyboard 입력을 기다리는 편집기 등)
가 실행 상태가 되면 scheduler는 즉시 실행 할 것인지에 대한 결정을 내린다. 현재 그 process가 수행중일 때도 그 같은 고려를 한다. 이와 같은 선점은 시스템의 응답시간을 높이는데 중요한 역할을 했다.

□ 만약 kernel mode에서 system call을 수행하고 있을 때, 어떤 process도 CPU 사용을 취소할 수 없다. 즉, scheduler는 다른 process를 선택하기 이전에 system call의 수행을 완료를 해야한다는 것이다. 하지만 system call은 interrupt에 의해 잠시 보류될 수 있다. 

□ Interrupt는 user mode와 kernel mode에 있는 process들을 중지할 수 있다. 그것은 interrupt가 발생한 시점 부터 가능한한 빨리 처리해야 하는 중요한 것이기 때문에 가장 높은 우선순위를 가진다. 

Kernel 선점은 2.5 버전 개발을 진행하면서 선택사항으로(make menuconfig 수행된 메뉴) 추가되었다. 이 선택사항(option)은 kernel mode에서 system call을 수행 중일 때에도 급히(?) 처리해야 하는 다른 process가 생기면 교체될 수 있는 기능인 것이다.(물론 interrupt 핸들러가 수행중일 때는 불가하다.) 비록 kernel이 system call을 최대한 빨리 수행을 마쳐야 함에도 불구하고(빨리 수행해야하는 이유는 scheduler가 system call을 마무리 하여 다른 process의 수행권을 보장하고 진행하기 위함) 신뢰성있는 어떤 application들은 일정한 data 스트림을 요구하여 많은 시간이 필요하게 되는 경우가 있다. kernel 선점은 이와 같은 대기 시간을 줄이고 부드러운(?) program 실행을 가능하게 한다. 하지만 선점 기능은 하나의 CPU를 가진 시스템에서 병렬적인 접근이 많아지고 이것을 보호하기 위해 많은 data structure가 요구되기 때문에 증가된 kernel 복잡성으로 비용이 증가하게 된다. (향후, 2.8.3 장에서 자세히 다룬다.)

Posted by cyj4369
,

Chapter 2, Process Management and Scheduling



2.2 Process Life Cycle
 하나의 Process는 항상 실행 준비가 된 상태가 아니다. 때때로, Process는 외부 자원의 event 를 기다리고 있는 경우가 있다.(text 편집기에서 keyboard 입력 대기를 위한 경우). 이런 경우는 event(keyboard 입력)이 있을 때까지 process는 실행 될 수 없다. 

scheduler는 process들의 교체를 할때 시스템에 있는 모든 Process의 상태를 알고 있어야 한다. 이는 할일이 없는 process임에 불구하고 CPU 시간을 할당하는 일은 없어야 한다는 것이다. 시간 할당과 중요한 점은 각 process의 상태를 전환(예, 실행 상태 --> 대기상태)시키는 일이다. 예를 들어, 만약 하나의 process가 주변 장치의 data를 기다리고 있다면, scheduler는 process의 상태를 data가 도착할 때까지 실행 대기 상태로 변경해줘야 한다. 

하나의 process는 다음과 같은 상태를 가진다
□ Running -- Process는 실행 중이다. 
□ Waiting  -- Process는 실행 가능한 상태이지만 CPU 를 다른 process가 점유하여 사용 중이기 때문에 기다리는 상태이다. 이 상태의 process 는 scheduler에 의해 다음으로 실행 가능하다. 
□ Sleeping -- Process는 잠든(?) 상태이고, 수행될 수 없다. 외부 장치에 의해 data나 event를 기다리고 있는 상태이며, process가 event를 받기 전까지 scheduler가 선택할 수 없다. 

시스템은 하나의 process table에 그것들의 상태들과 관계없이(running, waiting, sleeping) 모든 process들을 저장한다. 그렇지만, sleeping 상태의 process는 scheduler가 실행 준비가 되지 않은 상태을 알고 있어야 함으로 특별히 "표시"를 해 둔다. 또한 외부 event를 기다리고 있는 process가 event가 발생시 적절한 시점에 깨어나 수행할 수 있도록 다수의 Queue 로 관리하고 있다. 

그림 2-2

실행 가능한 process의 queue에 다양한 상태전의를 알아보도록 하자. 하나의 process가 실행 가능한 상태이지만, 다른 process가 CPU를 점유하고 있는 상태라 CPU를 사용하기 위한 대기 상태이다. (이것의 상태는 "Waiting" 이다). 그것은 scheduler가 CPU 시간을 할당 할 때까지 "waiting" 상태로 남아있을 것이다. 일단 scheduler가 선택을 하면, 그 process의 상태는 "running"으로 바뀔 것이다. (그림 2-2 의 4번 전이)

scheduler가 process의 CPU 자원 사용을 그만 두게 하기로 결정했다면, 그 process의 상태는 "running"에서 "waiting"으로 변경된다. (그림 2-2 의 2번 전이), 그리고 새롭게 cycle을 시작한다. "Sleeping" 상태는 두 가지 경우가 있는데, 하나는 signal을 받아 방해(interrupt) 받을 수 있는 것과 그렇지 못한 것이다. 이시점에서는 sleeping의 경우의 수는 다루지 않는다. 

만약 process가 event를 기다리고 있는 상태라면, 그 process의 상태는 "running"에서 "sleeping" 상태로 변경된다. 하지만, sleeping 상태의 process는 바로 running 상태로 변경이 이루어지지 않는다. 일단 기다리던 event가 발생했을 경우, 그 process는 waiting(그림 2-2의 3번 전이)로 변경되고 다음 번 실행을 기다리게 된다. 

Program 실행이 종료되면(사용자가 application을 종료한 경우 등), process의 상태는 running에서 stopped로 변경된다(그림 2-2  에서 5번 전이)

위에 설명되지 않은 process의 특별한(?) 상태가 있는데, 그것은 "zombie" 상태이다. 이름에서도 알수 있듯이, process가 죽었지만 어찌된 영문인지 여전히 살아있는 상태로 보이는 것이다. 다시 말하면, 그 process들은 사용하던 자원(RAM, 주변장치의 연결 등)을 반납하고 다시는 실행될 수 없는 상태로 소위 죽은 것이다. 그렇지만 process table에 그것들을 위한 공간이 존재하기 때문에 살아있는 것처럼 보인다는 것이다. 

Process가 Zombie 상태로 들어가는 경우는, UNIX 시스템의 process 생성과 종료 구조에 관련되어 있다. 하나의 program가 종료하는 상태는 두 가지가 있다.. 한가지는, 다른 process나 사용자에 의해서 강제 종료되어지는 경우다.(이런 경우는 대게 SIGTERM 이나 SIGKILL signal을 종료대상 process에게 전달되어 이루어진다.-이는 process가 일반적으로 종료하는 경우와 동등한 효과를 가진다), 다른 한가지는, child process가 종료되는 시점에 parent process가 이미 wait4 시스템 콜을 실행하여 child의 종료상태를 parent가 받는 경우이다. 결국 parent process가 child의 종료상태를 인지하고 kernel에게 알려줘야 한다는 것이다. 그 시스템 콜은 child process에게 할당된 자원을 kernel이 해제해주게 된다. 

위에 기술했던 상황 모두 zombie 상태는 발생하게 된다. 하나의 process는 종료와 process table에서 제거되는 시점 사이에 잠시 zombie 상태를 거처간다. 어떤 경우는(parent process가 잘못 구현되어 wait 시스템 콜을 호출하지 않고 종료한 경우), child process가 종료상태를 parent에 알려주지 못한 상태에서 종료를 하여 썼던 자원은 해제가 되었겠지만 시스템의 다음 rebooting 까지 process table을 차지 할 수 있다.(zombie 상태로 오래 남아있는 경우다) 이것은 ps나 top 명령어로 확인 될 수 있다. process table에 남아 있는 zombie 상태는 kernel의 아주 작은 영역을 차지하고 있어 큰 문제가 되질 않는다. 

Posted by cyj4369
,


Chapter 2, Process Management and Scheduling


요즘 나오는 Operating System은 한번에 여러 개의 Process들을 실행 할 수 있다.(이것은 User 입장에서 그렇게 수행되는 것처럼 느껴지는 것이다.)  만약 하나의 시스템에 하나의 CPU를 가지고 있다면, 주어진 시간에 하나의 Process만을 실행 시킬수 있다. Multi-Processor 시스템에서는 물리적인 CPU 개수 만큼 Process들을 병렬적으로 수행 시킬 수 있다. 

Kernel과 Processor는 매우 빠른 간격으로 서로 다른 Application간에 번갈아가며 실행함으로써 시스템이 Multi-tasking(병렬적으로 여러 operation을 수행하는 능력)을 하는 것처럼 만들어 준다. 번갈아 실행하는 간격이 매우 짧기 때문에 User들은 Process가 일정 시간동안 활동하지 않는 상태임을 알지 못하고, 컴퓨터가 실제로 한번에 여러 일을 하는 듯한 느낌을 받게 된다. 

Kernel에서 해결해야할 중요한 시스템 관리 이슈들이 이 있고 이중 중요한 것은,
□ Application들은 일부러 그렇게 만들어 지지 않는 이상, 다른 Application을 간섭할 수 없다. 예를 들어, error를 가지고 실행하는 application A는 Application B에게 영향을 줄 수 없다. Linux는 multi-user 시스템이기 때문에, 프로그램들이 다른 프로그램의 메모리 영역을 읽거나 쓰게 할 수 없도록 해야 한다. 만약 그렇지 않으면, 다른 user들의 개인 data를 쉽게 접근할 수 있는 문제점이 있다. 

□ CPU 사용시간은 다양한 Application 사이에 최대한 공평하게 주어져야 하며, 이것은 어떤 프로램이 다른 것들 보다 더 중요한지 결정하는 것 중요한 포인트가 된다. 

 이 장에서는 kernel이 CPU 사용 시간을 어떻게 공유하고 process간 switch하는 방법을 설명한다.
이 두가지 작업은 각각 독립적으로 수행되는 두개의 부분으로 나누어져있다. 
□ kernel은 반드시 각 process들에게 얼마나 수행해야 하는지 그리고 언제 다른 process와 교체되어야 하는지 결정해야한다. 이것은 실제로 어떤 process가 다음에 수행되어야하는지에 대한 논점과는 다른 것이다. (다음 수행되어야 하는 것이 미리 결정되어 있진 않다) 이런 종류의 결정은 platform에 의존적이지 않다.(알고리즘에 결정된다는 뜻?)

□ process A에서 process B로 교체가 될 때, process B가 CPU 자원을 마지막으로 놓았던(release) 시점의 환경과 동일해야 한다.(당연한 얘기지만 B가 수행되었던 자원 등 상태를 어딘가에 저장해두어야 한다는 의미인듯) 예를 들어, CPU register 값과 virtual address의 구조등의 것들이 교체된 process가 가지고 있었던 것이어야 한다. 

후자의 내용은 CPU type에 매우 의존적이다.(가상 메모리의 구조나 cpu의 register 운영은 cpu architecture 마다 다른게 가지고 있다)그것은 C 언어 만으로 구현되기 어려우며 architecture의 assembler 에 도움을 받아야한다. (register 내용을 저장하고 복구하는 내용들은 순수 assembler로 구현되어 있다)

위의 두가지 작업은 scheduler라는 kernel의 subsystem이 관장하고 있다. scheduler 정책에 의해 각 process에게 CPU 시간을 할당하고 수행하게 한다. 이것은 process 교체 메카니즘과는 완전히 분리된 작업인 것이다. (task switch 관련해서는 다른 포인트인 듯)

2.1 Process Priorities
모든 process들이 똑같이 중요한 것은 아니다. process 우선순위는 여러 요구사항을 만족시키기 위한 임계점(Criticality classes)이 다르다. 임계점을 고려하는 부분에서 크게 두 분류로 나누어 보면, real time process와 non-real time process가 있다. 

□ Hard real-time process는 Process가 수행 완료되는 시간이 엄격히 제한적이다. 만약 항공기의 비행 조종 명령이 컴퓨터에 의해 처리된다면, 그 명령들은 최대한(물론 최대한이라고는 하지만 dead line이내에 수행이 되어야 한다는 뜻) 빨리 기계에 전달되어야 한다. 예를 들어, 만얀 항공기가 착륙지점에 다달았고, 조종사는 기수를 끌어내리기를 시도할 때, 컴퓨터가 몇초 늦게 명령을 전달하여 그 작은(?) 일을 진행했다. 그 때, 항공기는 아마도 땅에 뭍혀버리고 말것이다. Hard real-time process의 중요한 key point는 보장된 시간내에 그 명령이나 행동을 무조건 처리해야한다. 물론 이 보장된 시간은 특별히 짧은 시간만을 말하는 것이 아니다. 그 보다 더 시스템은 주어진 시간을 절대로 초과하지 않는다는 것을 보장해야 한다. 

Linux는 hard real-time processing을 지원하지 않는다.(적어도 vanilla kernel에서는..) 그렇지만, 수정된 리눅스 버전에서 지원되고 있다(RTLinux, Xenomai, RATI 등). 수정된Linux는 process를 분리하여 수행한다. 이는 kernel이 덜 중요한 software(process)를 real-time process 작업이 kernel 외부에서 수행되는 동안 처리하도록 한다.

Linux는 throughput(처리량)을 위해 최적화 되어 있고 가능한한 일반적인 경우를 처리하려고 노력한다. Linux에서는 보장된 응답 시간을 맞추는 것은 어려운 일이다. 그럼에도 불구하고 kernel 전체의 지연시간(요청하고 이행하는 사이의 시간)의 감소는 아주 조금씩 진전이 있어왔다. 이런 진전은 preemptible kernel mechanism(선점 커널 메카니즘), real-time mutexes, 새로운 completely fair scheduler 등으로 이루어 졌다. 이 책의 뒷 부분에 더 자세히 설명되어 있다. 

□ Soft real-time process는 hard real-time 보다 덜 강압적인(?) 형태이다. 비록 빠른 결과를 요구되는 것은 변함이 없지만, 조금 늦게 처리 된다고 하더라도 문제 될 것이 없는 것이다. CD에 data 쓰기를 하는 작업을 예로 들 수 있다. Data는 반드시 CD writer에게 연속적으로 기록해야하는 매체인 만큼 정해진 비율로 지속적으로 전달되어야 한다. 만약 시스템의 부하가 높아져서 Data 전송에 방해를 받게 된다면, CD를 사용할 수 없게 될 수도 있다. (이것은 위에 hard time의 예로 들은 비행기 추락보다는 낫다는 얘기이다). 이것 때문에라도(CD 를 못쓰게 하는 것을 방지) CD write process는 다른 process보다 그것이 요구하는 시간만큼 보장을 받게 해준다.

□ 대부분의 Process들은 특별한 시간 제한이 없는 "normal process"이다. 하지만 그것들에게 더 중요하고 덜 중요하다는 의미의 우선순위로 분류 하고 있다. 
예를 들면, 긴 시간의 컴파일 작업과 숫자 계산을 하는 process는 상대적으로 매우 낮은 우선순위는 가진다. 이유는, 1초 혹은 2초 동안 때때로 진행을 방해받더라도 결과에는 영향을 거의 미치지 않기 때문이다. 반대로 대화형 application(VIM 같은 편집기)는 가능한 빠르게 사용자 명령에 대한 응답을 보내줘야하기 때문에(사용자는 인내심이 없기로 유명하덴다) 높은 우선순위를 가진다. 

application의 CPU 시간은 그림 2-1에서 간단하게 보여 줄 수 있다. Process들은 하나의 시간 조각(time slice)에 나누어 위치하고 있고 각각 중요도에 따라 조각의 크기는 다르게 설정된다. 시스템의 시간 흐름에 따라 원을 돌며 Process를 실행하고 모든 process가 수행되기는 하지만, 중요한 Process들은 상대적으로 많은 시간을 얻어 수행시간이 길다. 

<그림 2-1>

선점 멀티태스킹(preemptive multitasking)이라고 알려진 방법은, 각 process는 수행되는 일정한 시간을 할당 받는다. 일단 그 시간이 만료되면, kernel은 process로 부터의 control을 그만두고 다른 process를 수행시킨다(여기서 다른 process는 이전 process에 의해 마지막으로 실행된 작업과는 무관하다). 시간의 만료된 process의 환경(특히, CPU register와 page table의 내용)은 꼭 저장되어 나중에 다시 복귀하여 실행 시 완전히 이전 상태로 돌아갈 수 있어야 한다. time slice의 길이는 process의 중요도에 따라 다르게 정해지게 된다. 그림 2-1과 같이 각각의 process들은 다른 크기의 slice를 가지고 있는 것을 확인 할 수 있을 것이다. 

이 단순화된 모델(그림 2-1)은 몇 가지 중요한 문제를 다루지 않은 것이다. 예를 들어, process들이 아직 실행 할 것이 없어 준비되지 않은 경우이다. 이 경우에 CPU 시간을 할당 했다고 해서 실행을 하면 아무 것도 하지 않고 시간만 까먹는 것이므로 효율적으로 사용하기 위해서는 이런 process들은 실행을 안 시키는 것이 좋다. <그림 2-1>에서는 모든 process가 실행 가능한 상태에서 CPU 자원을 대기중이라는 가정하에 시행한 것임을 알려드린다. 또 한가지는 Linux는 두가지의 scheduling class를 제공한다.(Completely Fair Scheduling, Real-time Scheduling) 

kernel 개발자들 사이에서는 scheduling의 일부인 다음 수행될 process를 선택하는 알고리즘에 대한 논의가 활발하다.(그만큼 중요하고 개발의 여지가 많아서 인듯). scheduler의 질적 향상에 대한 측정은 거의 불가능 하다. scheduler는 Linux System이 직면한 다른 많은 workload에 의해 생긴 요구사항을 해결 하기 위한 도전적인 과제일 것이다. 자동화된 조작을 위한 작은 embedded system에서는 대형 컴퓨터에서 요구되는 사항과는 많이 다를 것이다. 사실, scheduler code는 최근 두 가지 형태로 알아볼 수 있다. 

1. 2.5 version에서 개발 되는 동안, 기존의 scheduler를 대체하는 O(1) 대체하는 소위 O(1) scheduler 가 있다. 이 scheduler의 한가지 특별한 점은 System에 수행되고 있는 process 개수에 관계없이 상수시간에 다음 실행할 process를 선택할 수 있다. 이런 설계는 기존 scheduling 구조를 완벽히 바꾼 계기라고 할 수 있다.
2. Completely fair scheduling 은 kernel 2.6.23 버전까지 개발 진행되어 추가되었다. 이 새로운 코드는 기존의 원칙을 버리고 완벽한 시도가 되는 출발점이 된다.예를 들면, 이전 scheduler에서 요구된 것을 바탕으로 대화식의(vim program 등의 편집기) process는 응답시간을 빠르게 해주는 것이 된다. 이 scheduler의 중요한 포인트는 이상적인 fair scheduling 을 가능한 가깝게 구현하도록 노력했다는 것이다. 게다가 그것은 각각의 task들을 scheduling 할 뿐만 아니라, 더 일반적인 scheduling 단위에서도 잘 동작한다. 이는 다른 사용자들의 모든 process 간의 시간 분배와 각 사용자들이 사용하고 있는 process들 사이에서도 가능한 시간을 분배할 수 있도록 고려되어 있다. 

2-1 을 마무리 합니다. 틈틈히 읽어보고 수정사항이 있다면 변경하도록 하겠습니다.

Posted by cyj4369
,

2.3.2 Namespaces

 Namespace는 하나의 수행되는 시스템에 서로 다른 관점을 제공하는 것처럼 하는 lightweight 한 가상화의 형태를 제공하는 것이다. 이 매커니즘은 FreeBSD 의 jail 이나 Solaris의 zone과 비슷한 것이다. 

Concept
 전통적으로, Unix 계열의 시스템 뿐만아니라 Linux에서는 시스템이 가지고 있는 많은 자원을 전체적으로 관리한다. 예를 들어, 시스템에 있는 모든 process들은 그것들이 가지고 있는 PID 숫자로 확인되며, 이 PID 리스트는 커널에서 관리되어야 한다. 마찬가지로, uname system call로 반환된 시스템에 관한 정보는(kernel에 관한 약간의 정보와 system의 이름을 반환) 호출한 모든 사용자가 같은 값을 볼 수 있을 것이다. User ID 또한 이와 비슷한 방법으로 관리된다 : 각 user는 시스템에 유일한 UID 값을 가진다. 

uname -r : kernel version 확인
uname -a : system 정보 및 kernel 정보

User 의 ID는 kernel이 선택적으로 특정 권한에 대한 행동을 승인 혹은 거부를 한다. UID 0을 가진 root user는 기본적으로 모든 명령 및 행동이 가능하지만 0 이상의 값을 가진 UID는 제한적 기능만을 제공한다. PID n 의 값을 가진 user가 있다면, 자신의 pid n과 다른 m의 user가 실행 시킨 process는 시스템에서 제거할 수 없다. (ps -ef 명령으로 각 process의 pid와 uid를 확인할 수 있다). 물론 ps 명령어로 다른 사용자가 실행한 process는 확인 가능하다. User N은 다른 User M이 이 시스템에 활성화(사용하고 있는지)가 되어 있는지 볼 수 있다. 이것은 사용자가 자신이 가지고 있는 process들만 가지고 놀 수(?) 있는 한 다른 사용자가 가지고 있는 process를 관찰하는 것까지 막을 필요가 없기 때문에 아무 문제가 되지 않는다. 

 그러나 위의 경우를 원치 않은 경우가 있다. web 공급자가 고객들에게 Linux 시스템에 root 권한을 비롯한 모든 접근 권한을 주는 경우를 생각해 보자. 그렇다면 web service를 제공하는 고객들 한명당 하나의 linux 머신을 제공해야 하기 때문에 엄청난 비용이 든다. 그래서 KVM이나 VMware같은 가상화 환경으로 제공하면 이같은 문제를 해결 할 수 있지만, 이 가상화 방법은 시스템의 자원을 원할하게 분배하지 못하는 단점이 있다. 가상화 시스템은 각 고객들에게 분리된 kernel을 제공해야하는 것이 요구되며, 각 가상화 머신에 리눅스를 각각 설치를 해주고 설정을 완료해 줘야 한다. 

 다른 해결책으로는 namespace를 통해 가상화보다 적은 자원을 들여 같은 서비스를 제공할 수 있다. 하나의 물리적인 머신에 여러 커널을 수행하는 가상화 시스템(물론 서로 다른 운영체제를 수행하는데는 이 방법이 더 좋다)을 제공하는 대신에 하나의 물리적인 머신에 하나의 커널이 수행되고 namespace내부에 미리 모든 시스템의 자원을 추상화 해놓는 것이다. 이것은 하나의 container 에 process 그룹을 넣어두고 다른 container(물론 여기도 process 그룹이..)와는 완벽히 분리 해놓은 것이다. 이러한 분리는 하나의 container에 묶인 사용자들이 다른 container로의 연결을 할 수 없다. 그렇지만 container가 유지되는 동안 특정 경우에 다른 container와 공유하기 위해 그 container의 분리를 느슨하게(?) 할 수 있다. 예를 들어 container안의 PID 의 셋을 가지고 운영되지만, 서로 다른 container와 filesystem의 부분은 여전히 공유 될 수 있다. 

Namespace는 기본적으로 시스템의 다른 view를 생성한다. 모든 이전에 생성된 자원은 container data 구조체로 싸여져 있어야 하고 자원의 리스트 셋과 namespace에 포함하는 내용은 시스템 내부에서 유일해야 한다. 주어진 container 안에서 그 자원이 충분히 활용하고 있지만 외부에 그 자원의  고유 identity(예를 들어 PID, 아래의 예제확인)를 제공하지 않는다. (내부에서만 사용하고 운영한다는 얘기인듯.) 그림 2-3이 상황을 개략적으로 볼 수 있다. 

//그림 2-3  --> 나중에...

세 개의 서로 다른 namespace가 시스템이 있다고 생각해 보자. namespace는 계층적으로 연결될 수 있다고 고려되었다. 하나는 parent namespace이고 이는 두개의 child namespace를 생성했다. 이 container들은 각각 하나의 linux 머신에서 제공되는 것처럼 보이도록 하여 web 호스팅 설정을 할 수 있게 제공한다고 가정하자. 각 container에서는 각각 pid 가 0 인 init task를 가지고 있어야 하며 오름차순으로 생성된 다른 task들을 가지고 있어야 한다. 두 child namespace 내부에는 init task(PID == 0)인 것과 2, 3의 pid를 가지는 task가 있다.(그림 2-3) PID 값은 하나의 시스템에서 고유의 값을 가지므로 이런 식으로 container 내부에서 가지는 pid의 값은 시스템 전체에서 고유의 값이 될 수 없다. 

child container는 시스템의 다른 container에게 자신의 상태를 알려주거나 연결이 되지 않기 때문에 parent container에서 child 관련 정보를 취급해서 child 내부에서 실행되는 모든 process를 볼 수 있어야 한다. 그림 2-3 에서 parent 4~9번 process는 child의 process와 대응되어 있다. 비록 시스템에는 9개의 process들이 있는 것이지만 4~9번의 PID를 가진 process는 하나 이상의 PID를 가지기 때문에 실제적으로 15 개의 PID가 요구된다. 

Namespace는 만약 간결한 분량의 container를 포함하는 경우 비계층적 구조(위의 계층적 구조와는 다른)를 가질 수 있다.(UTS Namespace의 예제를 보면서 확인하자)

꽤나 오래전에 linux는 chroot 시스템 콜을 이용한 간단한 형태의 namespace를 지원하고 있었다.  이 방법은 filesystem의 특정 부분을 동작중인 process들이 root 디렉토리로 인식함으로써 설정된 디렉토리 밖에서 접근 하지 못하도록 진행하는 것이어서 이것 또한 namespace의 한 형태라고 볼 수 있다. 하지만 진정한 namespace는 단지 filesystem을 제어하는 것 이외에도 많은 것을 컨트롤 할 수 있도록 만들어 주는 것이다. 

namespace를 만드는 방법은 두 가지가 있다. 
1. 새로운 process가 fork나 clone 시스템 콜로 생성될 때, 특정 option으로 parent process와 namespace가 공유될 수 있도록 만들어 질 수 있다. 또는 새로운 namespace 가 생성될 수 있다. 

2. unshare 시스템 콜로 parent 로 부터 생성된 process를 분리하고 새로운 namespace를 할당 할수 있다. manual page 를 확인 하자(unshare(2))

관련 자료를 검색 중 찾은 간단한 예제로 확인해 보자
 
http://woodz.tistory.com/23 <-- namespace 의 간단한 실습 내용.

프로세스의 네임스페이스

-네임스페이스 정의

이름공간 또는 네임스페이스(Namespace) 개체를 구분할  있는 범위를 나타내는 말로 일반적으로 하나의 이름 공간에서는 하나의 이름이  하나의 개체만을 가리키게 된다.( http://ko.wikipedia.org/wiki/%EC%9D%B4%EB%A6%84%EA%B3%B5%EA%B0%84)

 

-프로세스에서의 네임스페이스의 의미

1. VFS에는 같은 파일시스템의 혹은 다른 파일시스템의 개별적 공간이 다수 존재 가능하다.

2. 다수의 프로세스가 개별적 파일시스템 공간들에 접근 가능하다.

3. 각각의 프로세스에 개별적으로 자신이 마운트한 파일시스템을 관리할 필요가 있다.

3. 독립적 파일시스템 공간에 대해 각각의 프로세스가 자신이 각각의 파일시스템에 접근한 정보를 관리하므로 여러 프로세스가 한 파일시스템에 접근하더라도 각 프로세시는 자신만의 파일시스템 접근정보(즉 책에서 이야기 하는 유일한 뷰)를 가진다.

4. 즉 프로세스의 네임스페이스는 VFS의 파일시스템들에 대해 프로세스별로 사용하고 있는 자신들의 파일시스템 개체를 구분하는 범위를 정의해 놓은 관리 모듈이라고 말할 수 있다.



Posted by cyj4369
,

SSH를 이용한 파일 복사는 scp 명령어를 통해서 이루어 진다.
# scp {계정}@{파일복사해올 컴퓨터ip주소}:{파일위치} {내컴퓨터저장위치}

예) # scp root@172.17.46.137:/root/rpm/* /opt
이는 172.17.46.137의 컴퓨터에 root의 권한으로 접근 /root/rpm/ 밑의 모든 파일들을 내컴퓨터의 /opt 폴더로 복사하는 것입니다

Posted by cyj4369
,

[RAID]

Embedded Lab/linux, x86 2012. 11. 21. 20:11

RAID : Redundant Array of Indexpensive Disk

 ● 1988년 미국 버클리대 컴퓨터 공학과에서 “A Case for Redundant Arrays of Inexpensive Disks  ”
   로 발표된 기술로, 여러개의 Disk에 일부 중복된 데이터를 나주어 저장하는 기술과  Disk용량 증가를 위한
  기술, 그리고 read/write 속도를 증가시키기나 데이터를 안전하게 백업하는데 사용하기도 하며, 
   RAID의 종류는 방법에 따라 여러개의 Level로 나눈다.

 ● 특징
    - 장애 발생요인을 최대로 제거한 고성능 무정지 저장장치
    - 여러개의 Disk를 하나의 가상 Disk로 구성, 대용량 저장 장치 구축 가능
    - 다수의 Disk에 Data를 분할, 병렬 전송함으로써 Data 전송속도 향상
    - System 가동 중 Disk Fault시에도 시스템 정지 없이 새로운 Disk로 교체하면서 Data 자동복구

1. RAID에 사용되는 기술

 1) Striping (스트라이핑)
  하나의 Disk에 모두 기록할 수 없는 Data를 여러개의 Disk에 분배 기록할 수 있는 기술로 
  큰 용량을 만들어 사용하는데 사용된다.

 2) Mirroring (미러링)
  '거울' 처럼 하나의 Disk를 또다른 Disk에 동시에 기록하는 기술로
  하나의 disk가 Fault 되어도 미러된 disk로 data를 안전하게 관리할 수 있다.
  
 3) Parity (패리티)
  Data의 오류검출 확인에 사용되는 기술


2. RAID의 종류

  1) RAID 0
    여러개의 Disk를 하나의 Disk처럼 사용
   

사용자 삽입 이미지


    장점 : I/O를 분산하고 Disk의 사용 용량을 증대할 수 있어 고용량 저장이 용이
             하며, RAID구성중 속도가 가장빠름.

    단점 : 스트라이핑 된 Disk중 한개의 Disk라도 손상되었을 경우 Data가 보장되지 않아
             Data의 안전성이 떨어짐


 2) RAID 1
   두개의 Disk에 중복하여 Data를 기록하여 DAta의 안정성 확보
 
사용자 삽입 이미지

    장점 : 각 Disk를 동시에 읽을 수 있어 읽기능력을 향상(두배), Data를 두개의 Disk에 기록 할 수 
            있어 하느의 Disk가 손상되어도 나머지 하나의 Disk에 Data가 남아있어 Data의 안전성 확보 가능.
             Multi user사용 적합

    단점 : 저장용량당 단가가 비싸 비용이 높고 쓰기능력은 향상되지 않음.


 3)  RAID 2
    error검출 능력이 없는 Disk를 위해 Hamming 오류정정코드를 사용
   모든 SCSI Disk가 ECC(에러검출기능)를 탑재하고 있기때문에 사용되지 않음
   
사용자 삽입 이미지


4) RAID 3 (Single Check Disk per Group RAID)
   Data 저장을 위한 Disk외에 하나의 Disk에 에러검출을 위한 패러티 정보를 저장하고,
   Disk에 장애가 발생하였을 경우 남아있는 Disk 들을 Exclusive OR (XOR)연산을 통해 복구
사용자 삽입 이미지

  장점 : 큰 용량의 Data를 안정적으로 기록시킬 때 용이 
          Single user, Single tasking 환경에 적합

  단점 : 적은양에  Data에는 비 효율적


5) RAID 4 (Independent Disk Array)
   하나의 Disk에 패러티 정보를 저장하고, 나머지 Disk들에게 Data를 저장
   어느 한 disk가 손상되어도 패러티 정보가 있는 Disk로 복구 가능
사용자 삽입 이미지

   장점 : 큰 Data의 전송시간을 줄일 수 있음
 
   단점 : 모든 Disk에서 I/O발생 병목현상 발생(패러티 정보갱신), 패러티 Disk도 같이 손상시 복구 어려움


6) RAID 5 (Rotating Independent Disk Array)
   하나의 Disk에 패러티 정보를 모두 저장하지 않고, 
   모든 Disk에 패러티 정보를 분산 기록하여 패러티를 담당하는 Disk에 병목현상을 해결
사용자 삽입 이미지

   장점 : 멀티프로세서 시스템과 같이 Data가 작은 기록이 잦을 경우 용이 (Hot Plug 가능)

   단점 : Data를 Read만 할 경우 속도가 느림, 3개 이상의 Disk 필요
             두개이상의 Disk가 Fault될 경우 Data의 안전성을 보장할 수 없음.


7) RAID 0+1 (Stripe then Mirror - High Data Transfer Performance)
   네개 이상의 Disk를 2개씩 RAID 0(스트라이핑)구성하고 다시 RAID 1(미러링)으로 구성
     Disk1
               > RAID 0 (스트라이핑)
    Disk2
                                            > RAID 1 (미러링)
    Disk3
                > RAID 0 (스트라이핑)
    Disk4

    장점 : RAID 0 와 RAID 1의 장점만을 수용하여 구성, 안정성과 속도증대를 동시에 만족.
             공통 O/S 실행과 같은 시스템에 적합

    단점 : 디스크 저장 효율성이 떨어지고 비용이 바싸짐.
             한그룹에 RAID 0(스트라이핑)된 디스크가 두개가  Fault 될 경우 Data의 보장 어려움


8) RAID 1+0 (Mirror then Stripe - High Data Transfer Performance)
  RAID 0+1의 단점인 Data의 안정성 미흡(두개이상 Disk가 Fault될 경우 전체 구성이 깨지는 문제)를
  보안한 기술.
 네개 이상의 Disk를 2개씩 RAID 1(미러링)구성하고 다시 RAID 0(스트라이핑)으로 구성  
사용자 삽입 이미지



  9) RAID 6 (InIndependent Data disks with two independent distributed parity schemes)

사용자 삽입 이미지


RAID 5 
방식는 하나의 패리티를 사용하지만 RAID 6 방식은 두개의 패리티를 사용하므로 두개의 드라이브 장애 시에도 데이터의 복구가 가능하다.
  읽기에서는 RAID 5 방식과 큰 차이는 없으나 쓰기 작업의 구현이 아주 복잡하다.



  10) RAID 7 
        (
Optimized Asynchrony for High I/O Rates as well as High Data Transfer Rates )


사용자 삽입 이미지


  11) RAID 10 (Very High Reliability combined with High Performance)

사용자 삽입 이미지


  12) RAID 53 (High I/O Rates and Data Transfer Performance )

사용자 삽입 이미지


3. RAID TYPE Level Safe & Speed
   
   1) RAID TYPE 
    
사용자 삽입 이미지

  2) Safe : RAID 1 > RAID 5 > RAID 1+0 > RAID 0+1 > RAID 0

  3) Speed : RAID 0 > RAID 0+1 / 1+0 > RAID 5 > RAID 1

'Embedded Lab > linux, x86' 카테고리의 다른 글

[리눅스 namespace]  (0) 2012.12.02
[SSH를 이용한 파일 복사]  (0) 2012.11.21
[우분투에서 NTFS로 빠른포맷하기]  (0) 2012.11.18
[우분투에서 NTFS 포맷하기]  (0) 2012.11.18
[디바이스 파일이란?]  (0) 2012.11.07
Posted by cyj4369
,
[2012-11-17 12:13:50]root@ubuntu:/media# mkfs.ntfs -c /dev/VG_16_8_4/LV_16_8_4
Cannot understand the cluster size '/dev/VG_16_8_4/LV_16_8_4'.

Usage: mkntfs [options] device [number-of-sectors]

Basic options:
    -f, --fast                      Perform a quick format
    -Q, --quick                     Perform a quick format
    -L, --label STRING              Set the volume label
    -C, --enable-compression        Enable compression on the volume
    -I, --no-indexing               Disable indexing on the volume
    -n, --no-action                 Do not write to disk

Advanced options:
    -c, --cluster-size BYTES        Specify the cluster size for the volume
    -s, --sector-size BYTES         Specify the sector size for the device
    -p, --partition-start SECTOR    Specify the partition start sector
    -H, --heads NUM                 Specify the number of heads
    -S, --sectors-per-track NUM     Specify the number of sectors per track
    -z, --mft-zone-multiplier NUM   Set the MFT zone multiplier
    -T, --zero-time                 Fake the time to be 00:00 UTC, Jan 1, 1970
    -F, --force                     Force execution despite errors

Output options:
    -q, --quiet                     Quiet execution
    -v, --verbose                   Verbose execution
        --debug                     Very verbose execution

Help options:
    -V, --version                   Display version
    -l, --license                   Display licensing information
    -h, --help                      Display this help

Developers' email address: linux-ntfs-dev@lists.sf.net
Linux NTFS homepage: http://www.linux-ntfs.org

[2012-11-17 12:14:51]root@ubuntu:/media# mkfs.ntfs -f /dev/VG_16_8_4/LV_16_8_4
Cluster size has been automatically set to 4096 bytes.
Creating NTFS volume structures.
mkntfs completed successfully. Have a nice day.


'Embedded Lab > linux, x86' 카테고리의 다른 글

[SSH를 이용한 파일 복사]  (0) 2012.11.21
[RAID]  (0) 2012.11.21
[우분투에서 NTFS 포맷하기]  (0) 2012.11.18
[디바이스 파일이란?]  (0) 2012.11.07
[인텔 architecture 에서 microblaze용 gcc 설치]  (0) 2012.11.06
Posted by cyj4369
,