##### Namespaces, Cgroups and Docker


### 0. System Design


1. Container

- Host provides Kernel

- Filesystem, network interface, etc are already there

- Guests starts from /sbin/init


2. Application Container

- Host provides Kernel

- User data, socket fd, etc are already there

- starts from application not init


### 1. Namespaces

: 하나의 system에서 시스템 자원을 가상화하여 namespace로 구분되는 각각의 독립된 공간을 만들어주는 기술


<linux에서 제공하는 namespaces>

 Namespace

 flags

 Isolates

 IPC

 CLONE_NEWIPS

 System V IPC, POSIX message queues (프로세스 간 격리)

 Network

 CLONE_NEWNET

 Network devices, stacks, ports, etc.

 (network interface, iptables, ..).

 Mount

 CLONE_NEWNS

 Mount points(file system의 mount 지점을 분할하여 격리)

 PID

 CLONE_NEWPID

 Process IDs

 User

 CLONE_NEWUSER

 User and group IDs

 UTS

 CLONE_NEWUTS

 Hostname and NIS domain name

* Linux namespace는 namespaces API를 사용하는데, 

"clone", "setns", "unshare"이라는 system call을 포함하며 flags를 사용하여 각각의 namespace를 구현

(linux man page 참고. http://linux.die.net/man/2/)



1. File System


a. read-only, mount RO /usr inside a container

b. shared - sharing data across containers via binds

c. slave

d. private - /tmp per service


=> docker에서는 aufs를 사용


2. Networking


a. Root namespace


docker container 내부에 network interface가 172.17.0.1/24로 네트워크가 할당 됨을 확인할 수 있음

$ ifconfig 

eth0    ~


- Full access to the machine interfaces

fast, easy to get setup, Network looks normal to the container 

but, No separation of concerns, Container has full control .......-> MAC addresses


b. Bridging

- docker  외부에는  브릿지 네트워크로 가상 브릿지가 생성됨 


$ ifconfig 

/eth952NTB    ~


$ bridge show

docker0    veth952NTB


- More complex to get setup

- Network looks normal to the container

but, Less speed, NAT to the internet, iptables to expose public socket


c. Private namespace with socket activation

- No inerface 

- Sockets are passed via stdin (inetd)

- systemd style listen fd API


3. Process Namespace    

: PID I is something else outside the namespace



### 3. Cgroups


- Control Groups은 실행 프로세스가 사용하는 block I/O, CPU, memory 등의 자원을 제한하고 감시하고 계산하는 Linux Kernel의 기능

- 실행 프로세스들의 그룹을 만드는 역할을 수행하며 이런 그룹은 hirachy를 가지게 됨

- 시스템의 자원 할당, 우선순위 지정, 거부, 관리, 모니터링 등의 제어 기능을 수행하므로 자원의 효율성을 향상시킴

- 단순 그룹핑을 제공하므로 실제 자원 분배를 위해서는 각 자원마다 해당하는 subsystems가 필요함

: blkio, cpu, cpuacct, cpuset, devices, momory, net_cls, ns(namespace subsystem), ..


1. Block I/O

weighting system

iops serviced, waiting and queued

2. CPU

shares system

cpuacct.stats user and system

3. Memory

total RSS momory limit

swap, total rss, # page ins/outs



### 4. tools

1. docker

2. nspawn 

3. nsenter

4. /sys/fs/cgroup

5. systemd units



참고.

Modern Linux Servers with cgroups - Brandon Philips, CoreOS, YouTube

https://wiki.archlinux.org/index.php/Cgroups

http://man7.org/linux/man-pages/man7/namespaces.7.html

https://access.redhat.com/documentation/ko-KR/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/ch01.html



--------------------------------------------------------------------------------------------------------


##### 

해당 포스팅이 시발점.

http://idchowto.com/?p=19919



### 위의 포스팅 내용 정리


Linux에서 보안과 성능의 향상을 위해 리소스의 사용을 제한하고 사용자와 분리하고자 함

Cgroups을 통해 보안을 강화하였고 자원의 할당량을 조절하였으나 가상화나 사용자 격리에 효율적이지 못 하였음.

namespace를 강화하기 시작함 (커널 2.6.x ~ 3.8, 오랫동안 공들임)


특히 네트워크 관점에서의 namespace에서,

트래픽을 network namespace로 분산한 만큼 방화벽 룰셋이 줄어들며, 결과적으로 지연시간도 줄어들게 됨

또한 network namespace에 해당하는 conntrack은 slab allocator를 통해 관리되는데, 

conntrack 또한 줄어들게 되므로 자원의 효율에 있어서 아주 효과적임. 

(하나의 룰셋을 찾기위해 검색해야할 conntrack의 범위를 한정 시켜주기 때문에)


또한 Docker는 lxc+aufs를 제공하기 위해 특화되었으며 이 결과 docker image reposigory가 활성화 됨

사용자 이미지의 저장 및 배포가 굉장히 단순화 되어 빠른 배포를 구현

이는 기존의 다른 가상화보다 docker가 인기있는 이유임



### 


# slab allocator

http://jiming.tistory.com/131



# conntrack

http://manpages.ubuntu.com/manpages/trusty/man8/conntrack.8.html



# VFS와 UnionFS

리눅스에서는 VFS을 통해서 다양한 파일시스템을 지원

* VFS  : http://jiming.tistory.com/127





- UnionFS은 몇개의 branch를 가지며 여러 타입의 파일시스템을 지원한다. 

- UnionFS 내에서 각각의  branch들은 precedence를 할당받고, higher precedence의 branch는 lower precedence의  branch를 override 한다.

- branch는 Directory에 동작한다.

: 2개의 directory에 걸쳐있는 하나의 branch가 있다면, 

UnionFS의 그 directory(high-level)의 내용과 속성은 두 directories(low-level)의 조합이다.

- UnionFS는 사용자가 알지 못하게 자동으로 중복된 directory entreies를 처리한다.

- 만약 두 branch에 하나의 파일이 존재한다면 

UnionFS file의 속성과 내용은 높은 우선순위의 branch의 파일에 따르며 낮은 우선순위의 내용은 무시된다. 


(http://www.slideshare.net/endhrk/introduction-to-docker-36472476)




# AUFS

: short for Advanced multi layered Unification File System


- Developed by Junjiro Okajima in 2006

- 이전의 UnionFS에서 완전히 새로쓰임

- 신뢰성과 성능 개선을 목적으로 like writable branch balancing같은 새로운 컨셉이 소개됨

Linux File System의 Union Mount를 구현

- AUFS의 처음 full name은 "Another UnionFS" 이였으나, version 2부터 "Advanced multi layered Unification File System"로 바뀜


- aufs는 writable branch balancing 기능을 제공

몇개의 파티션을 writing 하는 동안 setup을 할 수 있음

=> 다른 여러개의 파일 시스템을 하나로 통합하여 사용할 수 있음

모든 새로운 파일이나 수정된 파일들끼리 여유 메모리 공간, 부모 directory의 존재, 랜덤하거나 그렇지 않은 것(??)들을 기반으로 분할 됨

=>이미지에 대한 변경사항을 메모리에 저장해 두고 새로 쓰거나 변경된 파일을 읽을 경우 메인메모리에서 저장한 파일을 로드함

이러한 데이터는 USB 메모리에도 저장이 가능하여 다양하게 활용될 수 있음



* Why to use AuFS instead of unionfs ? 

: http://www.unionfs.org/


(UnionFS, AUFS가 다른 점 좀 더 찾아보기)



# Docker와 AuFS

: Docker는 LxC와 AuFS의 제공을 위해 시작. 즉 file system으로 AuFS를 사용


- copy-on-write 제공

=> Docker에서 이미지 생성 시, base image에 포인터로 연결을 한 후 이미지를 생성하므로 디스크 write가 발생하지 않고 base image에서 파일시스템으로 분기할 때 해당 내용을 디스크에 기록


- stacking, 변경된 이미지로 커밋은 새로운 파일 시스템 레이어로 구현됨



(http://www.slideshare.net/colinsurprenant/docker-introduction-dev-ops-mtl)



가벼운 이미지의 구현은, Github와 같은 Docker Hub라는 docker만의 repository를 탄생시키게 되었고

 Docker 생태계에 큰 중추가 되고있음.



'




1. ubuntu 설치


virtualbox

ubuntu-desktop-14.04.iso


Memory 2GB, HDD 20GB

Network Interfaces

eth0(bridge mode) 192.168.168.106/24

eth1(NAT) - 10.0.3.15/24



 > ssh로 작업할 예정




2. GRUB 부트로더 설정 (CLI 모드로 실행되게)


$ sudo vi /etc/default/grub 


GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"

GRUB_CMDLINE_LINUX=""

#GRUB_TERMINAL=console

를 아래와 같이 수정


#GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"

GRUB_CMDLINE_LINUX="text"

GRUB_TERMINAL=console




'System > Linux OS ' 카테고리의 다른 글

gcc / gdb  (0) 2015.12.24
man  (0) 2015.12.24
Linux LVM  (0) 2015.08.12
[Linux] 리눅스 모니터링  (0) 2015.04.22
[ubuntu] 디스크 늘리기(ESXi기반의 VM)  (0) 2015.04.21

1. 애매해다(X) -> 모호하다


2. 양식(X) -> 서식


3. 식비(X) -> 밥값


4. 잔업(X) -> 시간 외 업무


5. 망년회(X) -> 송년회


6. 견출지(X) -> 찾음표


7. 유도리(X) -> 융통성


8. 익(X) -> 다음 날


9. 잔반(X) -> 남은 음식


10. 왔다리 갔다리(X) -> 왔다 갔다다


11. 사양(X) -> 성능


12. 삐까삐까하다(X) -> 번쩍번쩍하다


13. 뗑깡(X) -> 생떼


14. 쇼부(X) -> 승부, 흥정


15. 금일(X) -> 오늘


16. 땡땡이 무늬(X) -> 물방울 무늬


17. 하명(X) -> 명령, 지시



'그냥' 카테고리의 다른 글

[서평] 모바일트렌드 2016, 커넥팅랩, 미래의창  (0) 2016.01.03


UNIX v6로 배우는 커널의 원리와 구조 (한빛미디어)

http://v6.cuzuco.com/v6.pdf






##### 14. 시스템 부팅




<개요>


- 커널 프로그램을 메모리로 읽어야 함(약 40KByte)

- 당시에는 메모리 용량이 작아서 ROM에 저장해 놓을 수 없었음

=> 단계를 나누어 작은 크기부터 읽은 후 큰 크기의 프로그램을 읽는 점진적 형태로 부팅을 수행

1. 부트로더를 읽는 프로그램을 먼저 메모리로 올리고,

2. 부트로더를 읽고,

3. 실제 커널 프로그램을 읽음




<Unix V6의 부팅과정>


1. ROM에 저장되어있는 Boot Strap Loader Program에서, Root Disk의 블록번호 0에 저장된 Boot Strap Program을 읽어서 메모리의 0x0으로 읽어옴

* Boot Strap Program은 시스템 관리자가 /etc/mkfs을 실행하여 파일 시스템을 구축할 때 블록 디바이스의 0번째 블록에 위치하도록 설정


2. Boot Strap Program은 Root Disk의 fs에서 /Unix나 /rkunix에 있는 Kernel Program의 본체를 메모리의 0x0으로 계속하여 읽어서 실행


3. kernel은 시스템을 초기화 함



<부팅, low.s>

--------------------------------------------------------------------------

/*

 *    커널 본체(?)의 하위 어드레스 부분

*/


1.    . = 0^.                            // 프로그램이 메모리로 로드될 때 주소가 0x0 임

2.        br    1f                       // 최초 실행 명령어, label 1로 brach

3.        4                               

4.        

5.        /* 중간 생략 */

6.

7.    . = 40^.

8.    .global    start,    dump   

9.    1:    jmp    start               // start로 jump

10.         jmp    dump

--------------------------------------------------------------------------





### 14.1.1 start


<start, m40.s> 

--------------------------------------------------------------------------

/*

 *    <처리내용>

 *

 *    1. 커널 APR 초기화

 *        - 최초의 커널공간을 설정

 *        - 커널 APR(Active Page Register, PAR과 PDR) 설정 (참고. p460, 표 14.1 커널 APR 초기 설정)

 *            a. APR0~5 : 물리메모리의 0~0137777를 할당. 물리어드레스 = 가상어드레스영역. 앞부분에 커널프로그램의 본체가 로드 됨

 *            b. APR6 : 커널 프로그램 뒤의 1KByte 영역 할당. proc[0]의 PRDA(user 구조체와 커널스택)이 할당

 *                            현재 실행 중인 프로세스의 PRDA이며, 프로세스 전환히 함께 전환 됨

 *            c. APR7 : 물리메모리의 최상위 영역 할당(0760000~07777777)

 *                            PDP-11/40이나 주변 디바이스 레지스터를 할당하여 PDP-11/40과 주변장치를 제어

 *            d. SP는 APR6 영역의 맨 끝을 가리키도록 함

  *        - 커널 APR은 PAR6을 제외하고 시스템 동작 중에는 값이 바뀌지 않음

 *            => 실행 프로세스의 PAR6은, user 구조체로 접근할 수 있는 전역변수 u(0140000)를 사용하여         

 *                해당 data segment의 physical memory address로 설정 (참조. p65, 그림 2.13 물리 어드레스 계산)

 *            (PAR, Page Address Register, 11~0 bit, physical memory block address의 base address register, 64bit 단위)

 * 

 *    2. MMU 초기화

 *        - SR0을 설정하여 MMU를 활성화 하면 "physical address <-> logical address"가 시작 됨 (가상메모리 사용을 시작 함)

 *            MMU는 SR0과 SR2라는 Status Register를 가짐 (참고. p41)

 *            SR0 : 메모리 관리 유효화 플래그와 에러 정보에 사용

 *            SR2 : 실행할 명령어의 16bit logical address

 *        - 커널 프로그램의 bss와 proc[0]의 PPDA를 0으로 초기화 (참고. p59)

 *                PPDA : 프로세스의 메모리 영역 중 Data Segment의 "user구조체 + 커널 스택 영역" 

 *                bss : 프로세스의 메모리 영역 중 Data Segment의 Data 영역에 있는 정적 변수가 위치하는 영역

 *        - 이전 모드를 user mode로 설정한 후 main() 실행 

 * 

 *    3. miain() 수행

 * 

*/


0610 /* ------------------------- */ 


0611 .globl start, _end, _edata, _main 

0612 start: 


/* MMU가 이미 활성화 되어있으면 비활성화가 될 때까지 진행하지 않음 */

0613 bit $1,SSR0 / SSR0 : SR0의 어드레스, SR0[0] bit가 서 있으면, MMU에서 메모리 관리 활성화 (SSRO = 177572)

0614 bne start / loop if restart 

0615 reset 

0616 


0617 / initialize systems segments, 커널 APR0-5의 초기화

0618 

0619 mov $KISA0,r0 / KISA0 = 172340, 커널 APR의 PAR

0620 mov $KISD0,r1 / KISD0 = 172300, 커널 APR의 PDR

0621 mov $200,r4 

0622 clr r2 / r2 클리어 

0623 mov $6,r3 


0624 1: 

0625 mov r2,(r0)+ 

0626 mov $77406,(r1)+ / 4k rw

0627 add r4,r2 

0628 sob r3,1b 

0629 

/*

* APR은 0~7까지 8쌍이 존재하며, 한 쌍의 APR은 한 페이지에 대응

* _edata : 데이터영역, _etext : 텍스트영역, _end : bss영역의 하한 어드레스를 가리킴 

* => 프로그램 컴파일 시 링커에 의해서 심볼 테이블로 저장

*/

0630 / initialize user segment, 커널 APR6 초기화

0631 

0632 mov $_end+63.,r2 

0633 ash $-6,r2 

0634 bic $!1777,r2 / PAR6 설정값 계산

0635 mov r2,(r0)+ / ksr = sysu / APR이 64byte 단위로 물리 어드레스를 관리하므로 반올림 할 때

0636 mov $USIZE-1\<8|6,(r1)+ / 6비트 오른쪽으로 시프트하여 하위 10bit를 남기고 0으로 초기호 

0637 

0638 / initialize io segment, 커널 APR7 초기화

0639 / set up counts on supervisor segments 

0640 

0641 mov $IO,(r0)+ 

0642 mov $77406,(r1)+ / rw 4k 

0643 

0644 / get a sp and start segmentation 

0645 / SP 초기화 및 MMU 활성

0646 mov $_u+[USIZE*64.],sp 

0647 inc SSR0 

0648 

0649 / clear bss

0650 / bss 활성화

0651 mov $_edata,r0  

0652 1:

0653 clr (r0)+

0654 cmp r0,$_end

0655 blo 1b

0656

0657 / clear user block

0658 / proc[0] user 커널 스택 영역을 0으로 초기화 

0659 mov $_u,r0

0660 1:

0661 clr (r0)+

0662 cmp r0,$_u+[USIZE*64.]

0663 blo 1b

0664

0665 / set up previous mode and call main

0666 / on return, enter user mode at 0R

0667 / main() 호출

0668 mov $30000,PS

0669 jsr pc,_main

0670 mov $170000,-(sp)

0671 clr -(sp)

0672 rtt


--------------------------------------------------------------------------



### 14.1.2 main() 



<처리내용>


1. 메모리 초기화


- proc[0]의 PPDA이하를 0으로 초기화 한 후 빈 영역의 관리를 위해서 coremap[]에 추가.

map 구조체 : 물리 메모리와 스와프 영역의 빈 영역을 관리 (빈 영역의 어드레스 크기를 나타냄) (참고. p134)

(coremap[] : 물리 메모리 관리영역(APR의 최소단위인 64bytes 단위) , swapmap[] : swap 메모리 관리영역(512bytes, 블록단위)


- MAXMEM 설정

: 실제 빈 영역의 크기를 나타내는 maxmem에는 실제 빈 영역의 크기와 MAXMEM 중 더 작은 값을 설정


int maxmem;    (system.h, maxmem)

#define MAXMEM    (64*32)    (param.h, MAXMEM)


2. swap 영역 초기화


- swapmap[]

- mfree() 확보

- swplo 블록에서 mswap 블록까지의 영역을 swapswap에 swap 영역으로 등록


(conf.c)

int swplo    4000;

int nswap    872;


3. clock 장치 초기화


4. proc[0] 생성

- proc[0] : 시스템 프로세스 스케줄러


5. I/O자원 초기화


6. proc[1] 생성 

- proc[1] : /etc/init을 실행하는 사용자 프로세스로 inode[]에 넣어둔 명령어들을 실행


* inode : 파일크기, 접근권한, 데이터가 저장된 블록 디바이스의 블록 번호정보 등을 포함하는 파일의 속성 데이터

블록 디바이스에 저장되어 있으며, 커널은 파일을 사용하기 위해 해당 파일의 inode를 읽음




<inode[], ken/main.c>


1511 /* 1561 UISD->r[0] = 077406; 

1512 * Icode is the octal bootstrap 

1513 * program executed in user mode

1514 * to bring up the system. 

1515 */ 

1516 int icode[] 

1517 {

1518     0104413, /* sys exec; init; initp */ 

1519     0000014, 

1520     0000010, 

1521     0000777, 

1522     0000014, /* initp: init; 0 */ 

1523     0000000, 

1524     0062457, /* init: */ 

1525     0061564, 

1526     0064457, 

1527     0064556, 

1528     0000164, 

1529 };



=> C언어 판

1    char *init = "/etc/init";

2    execl(init, init, 0);

3    while(1);



< main(), ken/main.c >


1550 main() 

1551 { 

1552     extern schar; 

1553     register i, *p; 

1554 

1555     /* 

1556     *     zero and free all of core  메모리와 스택영역 초기화

1557     */ 

1558 

1559     updlock = 0; 

1560     i = *ka6 + USIZE;                 // i에 proc[0]의 PRDA 영역의 뒤에 어드레스를 설정

ka6은 커널의 APR6의 어드레스(KISA6)이 설정되어 있으므로 "*ka6"으로 커널 APR6 값 가져오기

1561     UISD->r[0] = 077406;         // UISD, UISA : 사용자 APR0의 PAR, PDR의 어드레스 (seg.h에 define되어있음)

1562     for(;;) {     

1563         UISA->r[0] = i; 

1564         if(fuibyte(0) < 0)             // fuibyte() : 이전 모드의 가상 어드레스 공간의 데이터를 한 바이트만큼 복사하는 함수

 전 모드가 user mode이므로 fuibyte(0)은 사용자 APR0에 할당된 페이지의 처음부터 데이터를 복사하기 시작

1565             break; 

1566         clearseg(i);                       // 성공 시 수행루틴

1567         maxmem++;                     // coremap을 증가시키기 

1568         mfree(coremap, 1, i);        //  coremap 초기화

1569         i++; 

1570     } 

1571     if(cputype == 70) 

1572    for(i=0; i<62; i=+2) { 

1573         UBMAP->r[i] = i<<12; 

1574         UBMAP->r[i+1] = 0; 

1575     } 

1576     printf("mem = %l\n", maxmem*5/16); 

1577     printf("RESTRICTED RIGHTS\n\n"); 

1578     printf("Use, duplication or disclosure is subject to\n"); 

1579     printf("restrictions stated in Contract with Western\n"); 

1580     printf("Electric Company, Inc.\n"); 

1581 

1582     maxmem = min(maxmem, MAXMEM);

1583     mfree(swapmap, nswap, swplo); 

1584 

1585     /* 

1586     * set up system process, 프로세스 0 생성

1587     */ 

1588 

1589     proc[0].p_addr = *ka6;     

1590     proc[0].p_size = USIZE; 

1591      proc[0].p_stat = SRUN;

1592     proc[0].p_flag =| SLOAD|SSYS;     // SSYS : 시스템 프로세스, 스와프아웃의 대상이 되지 않음

1593     u.u_procp = &proc[0]; 

1594 

1595     /*

1596     * determine clock, 클록장치 초기화

1597     */ 

1598 

1599     UISA->r[7] = ka6[1]; /* io segment */        // 사용자 APR7에 커널 APR7 값을 설정 => fuiword()가 I/O 영역에 접근할 수 있도록 설정

1600    UISD->r[7] = 077406; 


// CLOCK1 : 전원주파수 클록 레지스터의 어드레스

// CLOCK2 :  프로그래머블 클록 자아치의 레지스터의 어드레스


< CLOCK, ken/main.c >

#define CLOCK1    0177546

#define CLOCK2    0172540


1601     lks = CLOCK1;                         

1602     if(fuiword(lks) == -1) {     // CLOCK1에 대해 fuiworkd()를 수행

1603         lks = CLOCK2;             // 실패하면 CLOCK2에 재수행

1604         if(fuiword(lks) == -1) 

1605             panic("no clock");     // CLOCK1, CLOCK2 둘 다 실패하면 pannic()으로 실행 중지

1606     } 

1607     *lks = 0115;     // 초기값이 왜 뒤에있을까.. 미리 설정되어있어야 하는게 아닐까? 전역변수 같은데 딴데서 먼저 했나보네~~

1608 

1609    /* 

1610     * set up ’known’ i-nodes, 자원 초기화

1611     */ 

1612 

1613     cinit(); 

1614     binit(); 

1615     iinit(); 

1616     rootdir = iget(rootdev, ROOTINO); 

1617     rootdir->i_flag =& ~ILOCK; 

1667     while(nt >= 128) { 

1618         u.u_cdir = iget(rootdev, ROOTINO); 

1619         u.u_cdir->i_flag =& ~ILOCK; 

1621         /* 

1622         * make init process             , 프로세스 1 생성

1623         * enter scheduling loop 

1624         * with system process 

1625         */ 

1626 

1627         if(newproc()) {         // proc[1]을 생성


//  proc[1]의 데이터영역의 어드레스 0에 inode[]를 복사하고 리턴

//

1628             expand(USIZE+1);             

1629             estabur(0, 1, 0, 0); 

1630             copyout(icode, 0, sizeof icode);   

1632             * Return goes to loc. 0 of user init 

1633             * code just copied out. 

1634             */ 

1635             return;     // return 되면 main()을 실행했던 위치로 돌아가서 값을 스택에 쌓고, rtt 명령을 실행

// rtt명령 : 스택의 처음부터 pc에 0, PSW에 0170000을 읽음

// 현모드, 이전모드가 사용자 모드 상태이며, 사용자 공간의 어드레스 0부터 명령이 실행

// 어드레스 0에 icode[]가 복사되어 있기 때문에 /etc/init을 실행하여 처리

1636         } 

1637         sched();         // proc[0]이 실행하여, 스와핑 대상이 없으므로 proc[0]은 sleep하고 제어권은 proc[1]로 이동

1638     } 

1639 /* ------------------------- */





### 14.1.3 /etc/init


* 사용자 프로그램, 자세한 내용은 UPM(8) 참조


1. 등록된 터미널에 대한 프로세스를 생성

2. 각 프로세스는 터미널의 다이얼 업 접속, 사용자의 로그인을 기다림. 

사용자가 로그인하면 쉘 프로그램을 실행

3. /etc/init는 이후 무한 루프로 들어가서 프로세스 처리를 계속


> 스케줄러는 sched(), switch() 실행을 계속 수행

> /etc/init : 등록된 터미널에 대응하는 프로세스를 생성하고 고아 프로세스의 처리 루프를 계속 수행

> 각 터미널에 대응하는 프로세스 터미널의 다이얼 업 접속과 사용자의 로그인을 기다림







'System > Linux Kernel' 카테고리의 다른 글

커널에서 원하는 값을 가지고오기 위해 clz를 하는 이유  (0) 2016.01.16
system(), fork()  (0) 2015.12.24
Device Tree, 리눅스 커널 4.0  (0) 2015.08.29
메모리관리  (0) 2015.08.18
인터럽트 / 트랩  (0) 2015.08.16

레고 오페라

레고 타워브릿지


~~~~ 가 생겼당






언제 조립하지 ㅋㅋㅋㅋ




'취미 ㅋㅋ' 카테고리의 다른 글

버터치킨커리  (0) 2016.02.13
뼈다귀 감자탕  (0) 2016.02.13
레고 탐정사무소  (0) 2015.11.30
레고 선물  (0) 2015.11.30
레고 심슨 퀵이마트  (0) 2015.11.30

레고 탐정사무소 







네번째 레고 조립!

두번째 모듈러닷 >_<




'취미 ㅋㅋ' 카테고리의 다른 글

뼈다귀 감자탕  (0) 2016.02.13
레고 TBC...  (0) 2015.12.01
레고 선물  (0) 2015.11.30
레고 심슨 퀵이마트  (0) 2015.11.30
레고 캠퍼밴  (0) 2015.11.30

레고 생일케이크, 

레고 골드 미니 피규어 







선물로 주신 분들.. 감사합니다!!  (꾸벅)




'취미 ㅋㅋ' 카테고리의 다른 글

레고 TBC...  (0) 2015.12.01
레고 탐정사무소  (0) 2015.11.30
레고 심슨 퀵이마트  (0) 2015.11.30
레고 캠퍼밴  (0) 2015.11.30
레고 펫샵  (0) 2015.11.30

세번째 레고

심슨 퀵이마트!!


아직 지붕은 완성 전 사진!

브릭누락으로 레고에 콜.. 












2주간 기다렸다가, 지금은 완성 끝!





'취미 ㅋㅋ' 카테고리의 다른 글

레고 탐정사무소  (0) 2015.11.30
레고 선물  (0) 2015.11.30
레고 캠퍼밴  (0) 2015.11.30
레고 펫샵  (0) 2015.11.30
버터치킨커리  (0) 2015.09.24

두번째 레고, 캠퍼밴!


타동네 홈플가서 득템









ㅋㅋㅋㅋㅋ 잼따. 한 번 뜯으면 그 자리에서 끝장보기...@_@




'취미 ㅋㅋ' 카테고리의 다른 글

레고 선물  (0) 2015.11.30
레고 심슨 퀵이마트  (0) 2015.11.30
레고 펫샵  (0) 2015.11.30
버터치킨커리  (0) 2015.09.24
근대된장국 가지덮밥(안심근대가지덮밥, 가지표고덮밥)  (0) 2015.09.24

첫번째 레고! 

애완동물 가게, 펫샵!!






시리즈 다 만들고 시푸당.....





'취미 ㅋㅋ' 카테고리의 다른 글

레고 심슨 퀵이마트  (0) 2015.11.30
레고 캠퍼밴  (0) 2015.11.30
버터치킨커리  (0) 2015.09.24
근대된장국 가지덮밥(안심근대가지덮밥, 가지표고덮밥)  (0) 2015.09.24
밑반찬  (0) 2015.09.24

+ Recent posts