# RedLeaf
## 1. Introduction
Protection, Isolation -> 서로 믿지 못하는 애들끼리 간섭하게 둘 수 없다.
- 40년 동안 뭘 하고 있냐.
- Monolithic(다 믿음)에 Process(Virtual Memory, Context Switching)를 쓰고 있다.
40년동안 얼마나 hw sw가 발전했는데 이걸 아직도 쓰고 있냐 <-- Singularity
이거 너무 투박하다. 좀 더 fine-grained 뭐가 필요하다.
HW로도 있었지만 SW로도 이런 방법을 찾고자 했는데 그 중 SW를 보면.
+Safe Language로 해서 Isolation을 달성하고자 한다.
+alpha가 필요하다. 단순 Language로는 부족하고, 그 중 하나가. Fault Isolation이다. Fault가 퍼지면 안 된다. Fault가 Isolated 되어야 한다.
## 2. Isolation in Language-Based Systems
지금까지 언어 특성을 이용한 시스템이 있었다.
태초에 Spin이 있었다 (Modular-3) - 포인터가 boundary를 넘어 공유되기 때문에 fault isolation 실패
목표: Fault Isolation은 언어만으로는 불충분. domain 모델 만들고 등등. Fine-grained isolation.
J-kernel (Java) - 공유된 객체의 interface를 감싸는 모델(proxy 개념). dynamic했지만 우리는 static하게 바꿨다. ownership, move 특성이 없기 때문에 deep copy 필요
KaffeOS (Java) - 모든 포인터 감시. write barrier. 객체를 생성한 객체가 제거되더라도 다른 객체들이 접근 가능. deep-copy 해야됨 -> 느림.
Singularity (Sing#) - single ownership 원리 적용. zero-copy 가능. SW 레벨 isolation 어느 정도 해냄. 하지만 GC는 느리다.
### RedLeaf (Rust)
J-kernel에서 proxy 개념.
KaffeOS, Singularity에서 heap isolation 개념.
+Rust를 썼어요 곁들였어요!
(단순히 C 자리에 Rust를 쓰는 게 아니다. 이거는 Rust의 특성을 exploit하지 못한다. 수업 때 다들 배웠죠?)
**zero-copy 유지
fault isolation
transparent recovery of device drivers
그러면서 빠름**
어떻게 이게 가능하냐?
**Rust 소개** (move, immutable reference) - Singularity에 일부 영향. (single ownership)
(Singularity와 다르게)
* ownership 시스템 -> 컴파일 타임에 수명을 앎 -> 런타임 gc 없음 -> 빠름.
* read-only borrow를 이용해서 zero-copy 유지하면서 transparent domain recovery.
* Singularity에서는 ownership 넘길 수밖에 없었지만,
* caller가 callee에게 레퍼런스를 보내기 때문에 값이 안 바뀜이 보장됨. recovery 가능
* OS와 언어의 co-design에서 탈출.
## 3. RedLeaf Architecture
RedLeaf는 microkernel입니다.
모든 실행은 ring 0. single address. 하드웨어 레벨에서 protection 하지 않지만 SW가 해줌.
domain은 isolation의 단위.
Fault Isolation이 뭐냐. Domain안에서 Fault가 나도 다른 domain에 영향을 주지 않아야 한다.
더 정확하게 이렇게 정의했다.
1. crashing domain 내부에서 돌아가는 thread를 모두 찾아서 caller에게 Err 반환.
(Why? Crashing domain안의 obj는 inconsistent state라서 thread를 더 진행시켜도 나오는 값이 undefined)
3. domain을 실행하려는 시도가 더 있다면 err 반환함 (터트리면 안 됨)
4. domain이 들고 있는 모든 resource를 drop. (다른 domain이 crashing domain의 객체를 가리킬 수 없음) 그래서 leak가 없다.
5. domain이 생성했지만 move된 resource는 여전히 남아있음.
SW Protection 1 -> Heap Isolation
Singularity에서 봤던 (shared/private) Heap isolation을 한다.
Private은 자기만 접근 가능. Shared는 inter-process.
**(Remote Reference)RRef<T>** 타입: special pointer. domain-id(소유자 명시), borrow-count(immutable reference 개수), 실제 데이터. 이렇게 들고 있음
-> Fail 했을 때 Return Error. 해당 Domain의 메모리를 정리한다.
어떻게? -> Private은 갖다 버린다. Shared는 RRef Entry보고 corrupt된 domain이 소유한 객체 찾는다. 만약??? Immutable Ref가 없으면 버리고 있으면 유지.
(RRef가 RRef를 가리킬 수도 있음. domain이 소유한 객체 찾을 때 traverse.)
Domain은 이걸 communication을 통해 다른 Domain으로 넘길 수 있다.(소유권 이전 가능)
이때, How to commuicate with other domains?
Old : IPC
Singularity : Contract-based Channel(메세지 queue)
RedLeaf : Follows (메세지 대신에) thread migrating 모델 차용.
Thread가 Domain을 넘어다녀요. Stack을 유지한 채로.
뭔소리냐. Communicaion = Function call이 된다.
-> 각 Domain은 각자의 Interface를 정의할 수 있다.
Cross-domain call(communication)이 발생해서 RRef 소유권이 넘어갔어. 이걸 어떻게 알 거냐.
Proxy 끼어 든다. - IDL Compiler 자동 생성한다.(IDL코드 보여줄 수 있음)
동시에 transparent하다. caller는 똑같은 interface를 쓴다.
Proxy와 IDL Compiler는 추가로 하는 기능이 몇 개 있다.
1. proxy: Unwinding - Continuation 저장. Domain 터지면 돌아온다. Error를 반환한다.
2. IDL: (Static time) Interface가 올바른지(Exchangeable type을 받고 RpcResult를 반환)를 체크한다.
Shadow device driver
Recovery? proxy가 error를 뱉으면 다시 실행시킨다.
Exchangeable type이 뭐냐? private heap에 접근할 수 없는 애들
1. RRef
2. subset of copy primitive: u32, u64 등
3. 얘네들로 이루어진 것들(tuple, array, trait 등)
Safety
Rust의 safety guarantee를 사용하기 위해서 몇 가지 조건이 필요하다.
- kernel과 trusted library를 제외하면 모두 Safe Rust.
- Rust Compiler 믿습니다.
- Library도 믿습니다.
- Dynamic linking에 따라오는 문제점들
- Linking되는 Domain의 타입이 system 전체에서 같은 의미인지 알아야 함
- Trusted compilation environment -> 내가 믿는 컴파일러가 있음.
- microkernel can check that domains are compiled against the same versions of IDL interface definitions, and with the same compiler version, and flags.
- Compiler가 Sign할 거임
## Evaluation