Add three new occlum commands: start, exec and stop

Usage:
//start the occlum server
occlum start

//execute the command inside occlum
occlum exec [cmd] [-- <args>]

//stop the occlum server
occlum stop
This commit is contained in:
Zongmin 2020-04-11 13:17:53 +08:00 committed by Tate, Hongliang Tian
parent 4567b40f22
commit 0c3466f4ad
22 changed files with 2230 additions and 28 deletions

4
.gitmodules vendored

@ -18,3 +18,7 @@
[submodule "deps/serde-json-sgx"]
path = deps/serde-json-sgx
url = https://github.com/occlum/serde-json-sgx
[submodule "deps/grpc-rust"]
path = deps/grpc-rust
url = https://github.com/stepancheg/grpc-rust.git
branch = v0.7

1
deps/grpc-rust vendored Submodule

@ -0,0 +1 @@
Subproject commit 18acae5ed98afca2b971779eb851a45bb55f2fdc

@ -4,8 +4,10 @@ all:
@$(MAKE) --no-print-directory -C libos
@$(MAKE) --no-print-directory -C pal
@$(MAKE) --no-print-directory -C run
@$(MAKE) --no-print-directory -C exec
clean:
@$(MAKE) --no-print-directory -C libos clean
@$(MAKE) --no-print-directory -C pal clean
@$(MAKE) --no-print-directory -C run clean
@$(MAKE) --no-print-directory -C exec clean

6
src/exec/.gitignore vendored Normal file

@ -0,0 +1,6 @@
# Generated by Cargo
# will have compiled files and executables
/target/
# These are backup files generated by rustfmt
**/*.rs.bk

973
src/exec/Cargo.lock generated Normal file

@ -0,0 +1,973 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "aho-corasick"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "arc-swap"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hermit-abi 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "autocfg"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "base64"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bytes"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cc"
version = "1.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "chrono"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "clap"
version = "2.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "env_logger"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-executor 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-io 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "futures-channel"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "futures-core"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures-executor"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "futures-io"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures-macro"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro-hack 0.5.15 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "futures-sink"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures-task"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures-util"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-io 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-macro 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-hack 0.5.15 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro-nested 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "getrandom"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
"wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "grpc"
version = "0.7.0"
dependencies = [
"base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"httpbis 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"log-ndc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tls-api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tls-api-stub 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "grpc-compiler"
version = "0.7.0"
dependencies = [
"protobuf 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf-codegen 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "grpc-protobuf"
version = "0.7.0"
dependencies = [
"bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"grpc 0.7.0",
"protobuf 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hermit-abi"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "httpbis"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"log-ndc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"tls-api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tls-api-stub 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
"unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "humantime"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "iovec"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "log"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "log-ndc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memchr"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "mio"
version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mio-uds"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "miow"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "net2"
version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nix"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-integer"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "occlum_exec"
version = "0.1.0"
dependencies = [
"chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"grpc 0.7.0",
"grpc-protobuf 0.7.0",
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"protoc-rust-grpc 0.7.0",
"sendfd 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"signal-hook 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"timer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pin-project-lite"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ppv-lite86"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro-hack"
version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro-nested"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro2"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "protobuf"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "protobuf-codegen"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"protobuf 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "protoc"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "protoc-rust"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"protobuf 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"protobuf-codegen 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"protoc 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "protoc-rust-grpc"
version = "0.7.0"
dependencies = [
"grpc-compiler 0.7.0",
"protobuf 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"protoc 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"protoc-rust 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quote"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rdrand"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.1.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "regex"
version = "1.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
version = "0.6.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "remove_dir_all"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "safemem"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "sendfd"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "signal-hook"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
"signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "signal-hook-registry"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arc-swap 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "slab"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tempdir"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tempfile"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "termcolor"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "thread_local"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "time"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "timer"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tls-api"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tls-api-stub"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"tls-api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio"
version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-width"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unix_socket"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "vec_map"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ws2_32-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum aho-corasick 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada"
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
"checksum arc-swap 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b585a98a234c46fc563103e9278c9391fde1f4e6850334da895d27edb9580f62"
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
"checksum bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1"
"checksum cc 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)" = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2"
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5c329ae8753502fb44ae4fc2b622fa2a94652c41e795143765ba0927f92ab780"
"checksum futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c77d04ce8edd9cb903932b608268b3fffec4163dc053b3b402bf47eac1f1a8"
"checksum futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f25592f769825e89b92358db00d26f965761e094951ac44d3663ef25b7ac464a"
"checksum futures-executor 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f674f3e1bcb15b37284a90cedf55afdba482ab061c407a9c0ebbd0f3109741ba"
"checksum futures-io 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a638959aa96152c7a4cddf50fcb1e3fede0583b27157c26e67d6f99904090dc6"
"checksum futures-macro 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7"
"checksum futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3466821b4bc114d95b087b850a724c6f83115e929bc88f1fa98a3304a944c8a6"
"checksum futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0a34e53cf6cdcd0178aa573aed466b646eb3db769570841fda0c7ede375a27"
"checksum futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "22766cf25d64306bedf0384da004d05c9974ab104fcc4528f1236181c18004c5"
"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
"checksum hermit-abi 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4"
"checksum httpbis 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d49907da40fc924bc6ef91f29e0e4dae2b69b01a340cfeb8ce12b2ad39aa14"
"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)" = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005"
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
"checksum log-ndc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "edb09057c7b58b7d27498b528eaee9a1e661b2974a733fcabbbc3350360bc8bd"
"checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f"
"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
"checksum nix 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363"
"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
"checksum pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae"
"checksum pin-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
"checksum proc-macro-hack 0.5.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63"
"checksum proc-macro-nested 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694"
"checksum proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
"checksum protobuf 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e86d370532557ae7573551a1ec8235a0f8d6cb276c7c9e6aa490b511c447485"
"checksum protobuf-codegen 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de113bba758ccf2c1ef816b127c958001b7831136c9bc3f8e9ec695ac4e82b0c"
"checksum protoc 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "349d80967ee438cd03ccd236d548d4dcd5f2d9349acda206bef1490a826165d3"
"checksum protoc-rust 2.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58f2fb1de3a1355b1eb91108bf59d6221c1f565eee9983605be53846019fdf38"
"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
"checksum quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4c1f4b0efa5fc5e8ceb705136bfee52cfdb6a4e3509f770b478cd6ed434232a7"
"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9"
"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
"checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
"checksum regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692"
"checksum regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae"
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
"checksum safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
"checksum sendfd 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c30b0891653a66a373bec5dfc2e66487ab7b472c90784fa6e3cd7d9d151e6e00"
"checksum signal-hook 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "10b9f3a1686a29f53cfd91ee5e3db3c12313ec02d33765f02c1a9645a1811e2c"
"checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
"checksum syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "410a7488c0a728c7ceb4ad59b9567eb4053d02e8cc7f5c0e0eeeb39518369213"
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
"checksum time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
"checksum timer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "31d42176308937165701f50638db1c31586f183f1aab416268216577aec7306b"
"checksum tls-api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c11d29d2c8329bc6a8ef4693b5bc71194629bbcf054a69f93ba0dbfca0e8cd8d"
"checksum tls-api-stub 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db95f49839aa0aa02e4912b6129d5d823635bfcba2951e474689785c407cd245"
"checksum tokio 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "05c1d570eb1a36f0345a5ce9c6c6e665b70b73d11236912c0b477616aeec47b1"
"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum unix_socket 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aa2700417c405c38f5e6902d699345241c28c0b7ade4abaad71e35a87eb1564"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"

38
src/exec/Cargo.toml Normal file

@ -0,0 +1,38 @@
[package]
name = "occlum_exec"
version = "0.1.0"
edition = "2018"
[lib]
doctest = false
test = false
[dependencies.grpc]
path = "../../deps/grpc-rust/grpc"
[dependencies.grpc-protobuf]
path = "../../deps/grpc-rust/grpc-protobuf"
[dependencies]
protobuf = "2.14"
futures = "0.3"
env_logger = "0.7"
tempdir = "0.3"
clap = "2.33"
timer = "0.2"
chrono = "0.4"
libc = "0.2"
sendfd = "0.3"
signal-hook = "0.1"
nix = "0.17"
log = "0.4.8"
[build-dependencies]
protoc-rust-grpc = { path = "../../deps/grpc-rust/protoc-rust-grpc" }
[[bin]]
name = "occlum_exec_client"
test = false
[[bin]]
name = "occlum_exec_server"
test = false

20
src/exec/Makefile Normal file

@ -0,0 +1,20 @@
include ../sgxenv.mk
EXEC_PROTO := occlum_exec.proto
SRC_FILES := $(shell find . -type f -name '*.rs') Cargo.toml $(EXEC_PROTO)
RUST_TARGET_DIR := $(BUILD_DIR)/src/exec/cargo-target
RUST_OUT_DIR := $(BUILD_DIR)/bin
.PHONY: all clean
all: $(SRC_FILES)
ifeq ($(OCCLUM_RELEASE_BUILD), 1)
@RUSTC_BOOTSTRAP=1 cargo build --release --target-dir=$(RUST_TARGET_DIR) -Z unstable-options --out-dir=$(RUST_OUT_DIR)
@echo "CARGO (release) => exec"
else
@RUSTC_BOOTSTRAP=1 cargo build --target-dir=$(RUST_TARGET_DIR) -Z unstable-options --out-dir=$(RUST_OUT_DIR)
@echo "CARGO (debug) => exec"
endif
clean:
@cargo clean

24
src/exec/build.rs Normal file

@ -0,0 +1,24 @@
extern crate protoc_rust_grpc;
use std::env;
fn main() {
protoc_rust_grpc::Codegen::new()
.out_dir("src")
.input("occlum_exec.proto")
.rust_protobuf(true)
.run()
.expect("protoc-rust-grpc");
let sdk_dir = env::var("SGX_SDK").unwrap_or_else(|_| "/opt/intel/sgxsdk".to_string());
let sgx_mode = env::var("SGX_MODE").unwrap_or_else(|_| "HW".to_string());
match sgx_mode.as_ref() {
"SW" | "SIM" => {
println!("cargo:rustc-link-search=native={}/sdk_libs", sdk_dir);
println!("cargo:rustc-link-search=native=../../build_sim/lib");
println!("cargo:rustc-link-lib=dylib=sgx_uae_service_sim");
println!("cargo:rustc-link-lib=dylib=sgx_urts_sim")
}
"HW" | _ => println!("cargo:rustc-link-search=native=../../build/lib"), // Treat undefined as HW
}
println!("cargo:rustc-link-lib=dylib=occlum-pal");
}

@ -0,0 +1,66 @@
syntax = "proto3";
package occlumexec;
// Interface exported by the server.
service OcclumExec {
// Client check the server status
rpc StatusCheck(HealthCheckRequest) returns (HealthCheckResponse) {}
// Client asks the server to execute the command
rpc ExecCommand(ExecComm) returns (ExecCommResponse) {}
// Client gets the return value
rpc GetResult(GetResultRequest) returns (GetResultResponse) {}
// Client sends heart beats to server
rpc HeartBeat(stream HealthCheckRequest) returns (stream HealthCheckResponse) {}
//Client stops the server
rpc StopServer(StopRequest) returns (StopResponse){}
}
message GetResultRequest {
uint32 process_id = 1;
}
message GetResultResponse {
enum ExecutionStatus {
UNKNOWN = 0;
RUNNING = 1;
STOPPED = 2;
}
ExecutionStatus status = 1;
int32 result = 2;
}
message ExecComm {
uint32 process_id = 1;
string sockpath = 2;
string command = 3;
repeated string parameters = 4;
}
message ExecCommResponse {
uint32 process_id = 1;
}
message HealthCheckRequest {
uint32 process_id = 1;
}
message HealthCheckResponse {
enum ServingStatus {
UNKNOWN = 0;
SERVING = 1;
NOT_SERVING = 2;
}
ServingStatus status = 1;
}
message StopRequest {
uint32 time = 1;
}
message StopResponse {
}

1
src/exec/rust-toolchain Normal file

@ -0,0 +1 @@
nightly-2020-04-07

2
src/exec/src/.gitignore vendored Normal file

@ -0,0 +1,2 @@
occlum_exec.rs
occlum_exec_grpc.rs

@ -0,0 +1,368 @@
extern crate clap;
extern crate env_logger;
extern crate futures;
extern crate grpc;
extern crate occlum_exec;
extern crate protobuf;
extern crate signal_hook;
#[macro_use]
extern crate log;
use clap::{App, Arg};
use futures::executor;
use futures::stream::StreamExt;
use grpc::prelude::*;
use grpc::ClientConf;
use occlum_exec::occlum_exec::{
ExecComm, GetResultRequest, GetResultResponse_ExecutionStatus, HealthCheckRequest,
HealthCheckResponse_ServingStatus, StopRequest,
};
use occlum_exec::occlum_exec_grpc::OcclumExecClient;
use occlum_exec::{
DEFAULT_CLIENT_FILE, DEFAULT_SERVER_FILE, DEFAULT_SERVER_TIMER, DEFAULT_SOCK_FILE,
};
use protobuf::RepeatedField;
use sendfd::SendWithFd;
use std::cmp;
use std::env;
use std::os::unix::net::UnixListener;
use std::process;
use std::process::{Command, Stdio};
use std::sync::{Arc, Mutex};
use std::{thread, time};
use tempdir::TempDir;
use signal_hook::iterator::Signals;
use signal_hook::SIGUSR1;
/// Execute the command on server
///
/// # Examples
///
/// use occlum_exec::occlum_exec_grpc::OcclumExecClient;
///
/// let client = OcclumExecClient::new_plain_unix(&sock_file, ClientConf::new()).unwrap();
/// let let occlum_exec: Vec<String> = vec!["/bin/hello_world".to_String(), "".to_String()];
/// let process_id = exec_command(&client, &occlum_exec[0], &occlum_exec[1..]);
///
fn exec_command(
client: &OcclumExecClient,
command: &str,
parameters: &[&str],
) -> Result<u32, String> {
debug!("exec_command {:?} {:?}", command, parameters);
let mut parameter_list = RepeatedField::default();
for p in parameters {
parameter_list.push(p.to_string());
}
let tmp_dir = TempDir::new("occlum_tmp").expect("create temp dir");
let sockpath = tmp_dir.path().join("occlum.sock");
let listener = UnixListener::bind(&sockpath).unwrap();
//the thread would send the stdio to server
let sendfd_thread = thread::spawn(move || {
for stream in listener.incoming() {
match stream {
Ok(stream) => {
debug!("server connected");
if let Ok(_) = stream.send_with_fd(&[0], &[0, 1, 2]) {
break;
}
}
Err(e) => {
debug!("connection failed: {}", e);
}
}
}
});
let resp = executor::block_on(
client
.exec_command(
grpc::RequestOptions::new(),
ExecComm {
process_id: process::id(),
command: command.to_string(),
parameters: parameter_list,
sockpath: String::from(sockpath.as_path().to_str().unwrap()),
..Default::default()
},
)
.drop_metadata(),
); // Drop response metadata
match resp {
Ok(resp) => {
sendfd_thread.join().unwrap();
Ok(resp.process_id)
}
Err(_) => Err(String::from("failed to send request.")),
}
}
/// Starts the server if the server is not running
fn start_server(client: &OcclumExecClient, server_name: &str) -> Result<u32, String> {
let mut server_launched = false;
let mut server_connection_retry_time = 0;
loop {
let resp = executor::block_on(
client
.status_check(
grpc::RequestOptions::new(),
HealthCheckRequest {
process_id: 0,
..Default::default()
},
)
.join_metadata_result(),
);
server_connection_retry_time += 1;
match resp {
Ok((_, resp, _)) => {
match resp.status {
HealthCheckResponse_ServingStatus::NOT_SERVING => {
return Err("no process".to_string())
}
_ => {}
};
debug!("server is running.");
return Ok(0);
}
Err(_resp) => {
if !server_launched {
debug!("server is not running, try to launch the server.");
match Command::new(server_name).stdout(Stdio::null()).spawn() {
Err(_r) => {
return Err("Failed to launch server".to_string());
}
Ok(_r) => {
server_launched = true;
//wait server 10 millis
thread::sleep(time::Duration::from_millis(100));
continue;
}
};
} else {
if server_connection_retry_time < 100 {
//wait server 100 millis
thread::sleep(time::Duration::from_millis(100));
continue;
}
return Err("Failed to launch server".to_string());
}
}
};
}
}
/// Stops the server with a timeout (seconds) specified
/// The timeout value should no larger than the default timeout value (30 seconds)
fn stop_server(client: &OcclumExecClient, time: u32) {
let time = cmp::min(time, DEFAULT_SERVER_TIMER);
if let Err(_) = executor::block_on(
client
.stop_server(
grpc::RequestOptions::new(),
StopRequest {
time: time,
..Default::default()
},
)
.join_metadata_result(),
) {
debug!("The server is not running.");
} else {
debug!("The server has received the stop request.");
}
}
/// Sends heart beats to server. When server responses NOT_SERVING, the app exit with return value.
fn start_heart_beat(client: &OcclumExecClient, process_id: u32) {
let process_stopped = Arc::new(Mutex::new(false));
let c_process_stopped = process_stopped.clone();
let (mut req, resp) =
executor::block_on(client.heart_beat(grpc::RequestOptions::new())).unwrap();
thread::spawn(move || {
loop {
thread::sleep(time::Duration::from_millis(500));
match *c_process_stopped.lock().unwrap() {
true => {
//the application stopped
break;
}
false => {
executor::block_on(req.wait()).unwrap();
req.send_data(HealthCheckRequest {
process_id: process_id,
..Default::default()
})
.expect("send failed");
}
};
}
req.finish().expect("req finish failed");
});
let mut responses = resp.drop_metadata();
'a: loop {
while let Some(message) = executor::block_on(responses.next()) {
let status = match message {
Ok(m) => m.status,
Err(_e) => {
//stop the client for any issue
//Todo: How to report the crash issue?
HealthCheckResponse_ServingStatus::NOT_SERVING
}
};
if status != HealthCheckResponse_ServingStatus::SERVING {
//the application has stopped
*process_stopped.lock().unwrap() = true;
break 'a;
}
thread::sleep(time::Duration::from_millis(100));
}
}
}
//Gets the application return value
fn get_return_value(client: &OcclumExecClient, process_id: &u32) -> Result<i32, ()> {
let resp = executor::block_on(
client
.get_result(
grpc::RequestOptions::new(),
GetResultRequest {
process_id: *process_id,
..Default::default()
},
)
.join_metadata_result(),
);
match resp {
Ok((_, resp, _)) => {
if resp.status == GetResultResponse_ExecutionStatus::STOPPED {
Ok(resp.result)
} else {
Err(())
}
}
Err(_) => Err(()),
}
}
fn main() -> Result<(), i32> {
env_logger::init();
let matches = App::new("Occlum")
.version("0.1.0")
.subcommand(
App::new("start").about(
"Start the Occlum server. If the server already running, immediately return.",
),
)
.subcommand(
App::new("stop")
.about(
"Stop the Occlum server.",
)
.arg(
Arg::with_name("time")
.short("t")
.long("time")
.takes_value(true)
.help("Seconds to wait before killing the applications running on the Occlum server.")
.default_value("10")
.validator(|t| match t.parse::<u32>() {
Ok(_) => Ok(()),
Err(e) => Err(e.to_string()),
}),
),
)
.subcommand(
App::new("exec")
.about("Execute the command on server.")
.arg(Arg::with_name("args").multiple(true).min_values(1).last(true).help("The arguments for the command")),
)
.get_matches();
let args: Vec<String> = env::args().collect();
let mut sock_file = String::from(args[0].as_str());
let sock_file = str::replace(
sock_file.as_mut_str(),
DEFAULT_CLIENT_FILE,
DEFAULT_SOCK_FILE,
);
let client = OcclumExecClient::new_plain_unix(&sock_file, ClientConf::new())
.expect("failed to create UDS client");
if let Some(ref _matches) = matches.subcommand_matches("start") {
//get the server name with the first args
let mut server_name = String::from(args[0].as_str());
let server_name = str::replace(
server_name.as_mut_str(),
DEFAULT_CLIENT_FILE,
DEFAULT_SERVER_FILE,
);
if let Err(s) = start_server(&client, &server_name) {
debug!("start_server failed {}", s);
return Err(-1);
}
} else if let Some(ref matches) = matches.subcommand_matches("stop") {
let stop_time = matches.value_of("time").unwrap().parse::<u32>().unwrap();
stop_server(&client, stop_time);
} else if let Some(ref matches) = matches.subcommand_matches("exec") {
let cmd_args: Vec<&str> = match matches
.values_of("args")
.map(|vals| vals.collect::<Vec<_>>())
{
Some(p) => p,
//Already set the min_values to 1. So it could not be here
_ => panic!(),
};
let (cmd, args) = cmd_args.split_first().unwrap();
match exec_command(&client, cmd, args) {
Ok(process_id) => {
let signals = Signals::new(&[SIGUSR1]).unwrap();
let signal_thread = thread::spawn(move || {
for sig in signals.forever() {
debug!("Received signal {:?}", sig);
break;
}
});
//Notifies the server, if client killed by KILL
start_heart_beat(&client, process_id.clone());
signal_thread.join().unwrap();
let result = get_return_value(&client, &process_id).unwrap();
if result != 0 {
return Err(result);
}
}
Err(s) => {
debug!("execute command failed {}", s);
return Err(-1);
}
};
} else {
unreachable!();
}
Ok(())
}

@ -0,0 +1,196 @@
extern crate futures;
extern crate grpc;
extern crate libc;
extern crate occlum_exec;
extern crate protobuf;
#[macro_use]
extern crate log;
use occlum_exec::occlum_exec::HealthCheckRequest;
use occlum_exec::occlum_exec_grpc::{OcclumExecClient, OcclumExecServer};
use occlum_exec::server::OcclumExecImpl;
use occlum_exec::{DEFAULT_SERVER_FILE, DEFAULT_SERVER_TIMER, DEFAULT_SOCK_FILE};
use std::env;
use std::ffi::{CStr, OsString};
use std::os::unix::ffi::OsStrExt;
use std::sync::{Arc, Condvar, Mutex};
use futures::executor;
use grpc::prelude::*;
use grpc::ClientConf;
//Checks the server status, if the server is running return true, else recover the socket file and return false.
fn check_server_status(sock_file: &str) -> bool {
if let Err(e) = std::fs::File::open(sock_file) {
debug!("failed to open the sock_file {:?}", e);
if e.kind() == std::io::ErrorKind::NotFound {
return false;
}
}
let client = OcclumExecClient::new_plain_unix(sock_file, ClientConf::new())
.expect("failed to create UDS client");
let resp = executor::block_on(
client
.status_check(
grpc::RequestOptions::new(),
HealthCheckRequest {
process_id: 0,
..Default::default()
},
)
.join_metadata_result(),
);
if let Ok(_) = resp {
debug!("another server is running.");
true
} else {
debug!("delete the useless socket file.");
std::fs::remove_file(sock_file).expect("could not remove socket file");
false
}
}
fn main() {
//get the UDS file name
let args: Vec<String> = env::args().collect();
let mut sockfile = String::from(args[0].as_str());
let sockfile = str::replace(
sockfile.as_mut_str(),
DEFAULT_SERVER_FILE,
DEFAULT_SOCK_FILE,
);
//If the server already startted, then return
if check_server_status(sockfile.as_str()) {
println!("server stared");
return;
}
let server_stopped = Arc::new((Mutex::new(true), Condvar::new()));
let _server_stopped = server_stopped.clone();
//new a timer to stop the server
let stop_timer = timer::Timer::new();
let stop_timer_guard = stop_timer.schedule_with_delay(
chrono::Duration::seconds(DEFAULT_SERVER_TIMER as i64),
move || {
let (lock, cvar) = &*_server_stopped;
let mut stopped = lock.lock().unwrap();
*stopped = true;
cvar.notify_one();
},
);
let service_def =
OcclumExecServer::new_service_def(OcclumExecImpl::new_and_save_execution_lock(
server_stopped.clone(),
(stop_timer, stop_timer_guard),
));
let mut server_builder = grpc::ServerBuilder::new_plain();
server_builder.add_service(service_def);
match server_builder.http.set_unix_addr(sockfile) {
Ok(_) => {}
Err(e) => {
debug!("{:?}", e);
return;
}
};
if let Ok(server) = server_builder.build() {
rust_occlum_pal_init().expect("Occlum image initialization failed");
//server is running
println!("server stared on addr {}", server.local_addr());
let (lock, cvar) = &*server_stopped;
let mut server_stopped = lock.lock().unwrap();
*server_stopped = false;
while !*server_stopped {
server_stopped = cvar.wait(server_stopped).unwrap();
}
rust_occlum_pal_destroy().expect("Destory occlum image failed");
println!("server stopped");
}
}
extern "C" {
/*
* @brief Initialize an Occlum enclave
*
* @param attr Mandatory input. Attributes for Occlum.
*
* @retval If 0, then success; otherwise, check errno for the exact error type.
*/
fn occlum_pal_init(attr: *const occlum_pal_attr_t) -> i32;
/*
* @brief Destroy the Occlum enclave
*
* @retval if 0, then success; otherwise, check errno for the exact error type.
*/
fn occlum_pal_destroy() -> i32;
}
#[repr(C)]
/// Occlum PAL attributes. Defined by occlum pal.
pub struct occlum_pal_attr_t {
/// Occlum instance dir.
///
/// Specifies the path of an Occlum instance directory. Usually, this
/// directory is initialized by executing "occlum init" command, which
/// creates a hidden directory named ".occlum/". This ".occlum/" is an
/// Occlum instance directory. The name of the directory is not necesarrily
/// ".occlum"; it can be renamed to an arbitrary name.
///
/// Mandatory field. Must not be NULL.
pub instance_dir: *const libc::c_char,
/// Log level.
///
/// Specifies the log level of Occlum LibOS. Valid values: "off", "error",
/// "warn", "info", and "trace". Case insensitive.
///
/// Optional field. If NULL, the LibOS will treat it as "off".
pub log_level: *const libc::c_char,
}
/// Loads and initializes the Occlum enclave image
fn rust_occlum_pal_init() -> Result<(), i32> {
let mut instance_dir = OsString::from("./.occlum\0");
if let Some(val) = env::var_os("OCCLUM_INSTANCE_DIR") {
instance_dir = val;
instance_dir.push("\0");
};
let mut log_level = OsString::from("off\0");
if let Some(val) = env::var_os("OCCLUM_LOG_LEVEL") {
log_level = val;
log_level.push("\0");
};
debug!("{:?} {:?}", instance_dir, log_level);
let occlum_pal_attribute = occlum_pal_attr_t {
instance_dir: CStr::from_bytes_with_nul(instance_dir.as_bytes())
.unwrap()
.as_ptr(),
log_level: CStr::from_bytes_with_nul(log_level.as_bytes())
.unwrap()
.as_ptr(),
};
let rust_object = Box::new(&occlum_pal_attribute);
let ret = unsafe { occlum_pal_init(*rust_object) };
match ret {
0 => Ok(()),
_ => Err(ret),
}
}
///Destroyes the Occlum enclave image
fn rust_occlum_pal_destroy() -> Result<(), i32> {
let ret = unsafe { occlum_pal_destroy() };
match ret {
0 => Ok(()),
_ => Err(ret),
}
}

15
src/exec/src/lib.rs Normal file

@ -0,0 +1,15 @@
extern crate futures;
extern crate grpc;
extern crate grpc_protobuf;
extern crate protobuf;
#[macro_use]
extern crate log;
pub mod occlum_exec;
pub mod occlum_exec_grpc;
pub mod server;
pub const DEFAULT_SERVER_FILE: &'static str = "occlum_exec_server";
pub const DEFAULT_CLIENT_FILE: &'static str = "occlum_exec_client";
pub const DEFAULT_SOCK_FILE: &'static str = "occlum_exec.sock";
pub const DEFAULT_SERVER_TIMER: u32 = 30;

406
src/exec/src/server.rs Normal file

@ -0,0 +1,406 @@
extern crate chrono;
extern crate nix;
extern crate timer;
use crate::occlum_exec::{
ExecComm, ExecCommResponse, GetResultRequest, GetResultResponse,
GetResultResponse_ExecutionStatus, HealthCheckRequest, HealthCheckResponse,
HealthCheckResponse_ServingStatus, StopRequest, StopResponse,
};
use crate::occlum_exec_grpc::OcclumExec;
use futures::stream::StreamExt;
use grpc::Metadata;
use grpc::ServerHandlerContext;
use grpc::ServerRequest;
use grpc::ServerRequestSingle;
use grpc::ServerResponseSink;
use grpc::ServerResponseUnarySink;
use sendfd::RecvWithFd;
use std::cmp;
use std::collections::HashMap;
use std::ffi::CString;
use std::os::unix::io::RawFd;
use std::os::unix::net::UnixStream;
use std::sync::{Arc, Condvar, Mutex};
use std::task::Poll;
use std::thread;
use timer::{Guard, Timer};
use nix::sys::signal::{self, Signal};
use nix::unistd::Pid;
#[derive(Default)]
pub struct OcclumExecImpl {
//process_id, return value, execution status
commands: Arc<Mutex<HashMap<u32, (Option<i32>, bool)>>>,
execution_lock: Arc<(Mutex<bool>, Condvar)>,
stop_timer: Arc<Mutex<Option<(Timer, Guard)>>>,
process_id: Arc<Mutex<u32>>,
}
impl OcclumExecImpl {
pub fn new_and_save_execution_lock(
lock: Arc<(Mutex<bool>, Condvar)>,
timer: (Timer, Guard),
) -> OcclumExecImpl {
OcclumExecImpl {
commands: Default::default(),
execution_lock: lock,
stop_timer: Arc::new(Mutex::new(Some(timer))),
process_id: Arc::new(Mutex::new(1)),
}
}
}
fn reset_stop_timer(
lock: Arc<(Mutex<bool>, Condvar)>,
old_timer: Arc<Mutex<Option<(Timer, Guard)>>>,
time: u32,
) {
//New a timer to stop the server
let timer = timer::Timer::new();
let guard = timer.schedule_with_delay(chrono::Duration::seconds(time as i64), move || {
if rust_occlum_pal_kill(-1, SIGKILL).is_err(){
warn!("SIGKILL failed.")
}
let (execution_lock, cvar) = &*lock;
let mut server_stopped = execution_lock.lock().unwrap();
*server_stopped = true;
cvar.notify_one();
});
let mut _old_timer = old_timer.lock().unwrap();
*_old_timer = Some((timer, guard));
}
fn clear_stop_timer(old_timer: &Arc<Mutex<Option<(Timer, Guard)>>>) {
let mut timer = old_timer.lock().unwrap();
*timer = None;
}
impl OcclumExec for OcclumExecImpl {
fn get_result(
&self,
_o: ServerHandlerContext,
mut req: ServerRequestSingle<GetResultRequest>,
resp: ServerResponseUnarySink<GetResultResponse>,
) -> grpc::Result<()> {
let process_id = req.take_message().process_id;
let commands = self.commands.clone();
let stop_timer = self.stop_timer.clone();
let mut commands = commands.lock().unwrap();
let (process_status, result) = match &commands.get(&process_id) {
None => (GetResultResponse_ExecutionStatus::UNKNOWN, -1),
Some(&(exit_status, _)) => {
match exit_status {
None => (GetResultResponse_ExecutionStatus::RUNNING, -1),
Some(return_value) => {
//Remove the process when getting the return value
commands.remove(&process_id);
if !commands.is_empty() {
//Clear the stop timer if some apps are running
clear_stop_timer(&stop_timer);
}
(GetResultResponse_ExecutionStatus::STOPPED, return_value)
}
}
}
};
drop(commands);
resp.finish(GetResultResponse {
status: process_status,
result: result,
..Default::default()
})
}
fn stop_server(
&self,
_o: ServerHandlerContext,
mut req: ServerRequestSingle<StopRequest>,
resp: ServerResponseUnarySink<StopResponse>,
) -> grpc::Result<()> {
if rust_occlum_pal_kill(-1, SIGTERM).is_err(){
warn!("SIGTERM failed.");
}
let time = cmp::min(req.take_message().time, crate::DEFAULT_SERVER_TIMER);
reset_stop_timer(self.execution_lock.clone(), self.stop_timer.clone(), time);
resp.finish(StopResponse::default())
}
fn status_check(
&self,
_o: ServerHandlerContext,
mut req: ServerRequestSingle<HealthCheckRequest>,
resp: ServerResponseUnarySink<HealthCheckResponse>,
) -> grpc::Result<()> {
//Reset the timer
reset_stop_timer(
self.execution_lock.clone(),
self.stop_timer.clone(),
crate::DEFAULT_SERVER_TIMER,
);
//Waits for the Occlum loaded
let (lock, _) = &*self.execution_lock.clone();
loop {
let server_stopped = lock.lock().unwrap();
if *server_stopped {
drop(server_stopped);
continue;
}
break;
}
//Get the process id from the request
let process_id = req.take_message().process_id;
match process_id {
0 => resp.finish(HealthCheckResponse::default()),
process_id => {
let commands = self.commands.clone();
let mut commands = commands.lock().unwrap();
match commands.get_mut(&process_id) {
Some(_) => resp.finish(HealthCheckResponse {
status: HealthCheckResponse_ServingStatus::SERVING,
..Default::default()
}),
_ => resp.finish(HealthCheckResponse {
status: HealthCheckResponse_ServingStatus::NOT_SERVING,
..Default::default()
}),
}
}
}
}
fn exec_command(
&self,
_o: ServerHandlerContext,
mut req: ServerRequestSingle<ExecComm>,
resp: ServerResponseUnarySink<ExecCommResponse>,
) -> grpc::Result<()> {
clear_stop_timer(&self.stop_timer.clone());
let req = req.take_message();
//Get the client stdio
let mut stdio_fds = occlum_stdio_fds {
stdin_fd: 0,
stdout_fd: 0,
stderr_fd: 0,
};
match UnixStream::connect(req.sockpath) {
Ok(stream) => {
let mut data = [0; 10];
let mut fdlist: [RawFd; 3] = [0; 3];
stream
.recv_with_fd(&mut data, &mut fdlist)
.expect("receive fd failed");
stdio_fds.stdin_fd = fdlist[0];
stdio_fds.stdout_fd = fdlist[1];
stdio_fds.stderr_fd = fdlist[2];
}
Err(e) => {
info!("Failed to connect: {}", e);
return resp.finish(ExecCommResponse {
process_id: 0,
..Default::default()
});
}
};
let gpid = self.process_id.clone();
let mut gpid = gpid.lock().unwrap();
let process_id: u32 = *gpid;
*gpid += 1;
drop(gpid);
let _commands = self.commands.clone();
let _execution_lock = self.execution_lock.clone();
let _stop_timer = self.stop_timer.clone();
let mut commands = _commands.lock().unwrap();
commands.entry(process_id).or_insert((None, true));
drop(commands);
let cmd = req.command.clone();
let args = req.parameters.into_vec().clone();
let client_process_id = req.process_id;
//Run the command in a thread
thread::spawn(move || {
let mut exit_status = Box::new(0);
rust_occlum_pal_exec(&cmd, &args, &stdio_fds, &mut exit_status)
.expect("failed to execute the command");
reset_stop_timer(_execution_lock, _stop_timer, crate::DEFAULT_SERVER_TIMER);
let mut commands = _commands.lock().unwrap();
*commands.get_mut(&process_id).expect("get process") = (Some(*exit_status), false);
//Notifies the client to application stopped
debug!(
"process:{} finished, send signal to {}",
process_id, client_process_id
);
//TODO: fix me if the client has been killed
signal::kill(Pid::from_raw(client_process_id as i32), Signal::SIGUSR1).unwrap();
});
resp.finish(ExecCommResponse {
process_id: process_id,
..Default::default()
})
}
fn heart_beat(
&self,
o: ServerHandlerContext,
req: ServerRequest<HealthCheckRequest>,
mut resp: ServerResponseSink<HealthCheckResponse>,
) -> grpc::Result<()> {
let mut req = req.into_stream();
let commands = self.commands.clone();
o.spawn_poll_fn(move |cx| {
loop {
// Wait until resp is writable
if let Poll::Pending = resp.poll(cx)? {
return Poll::Pending;
}
match req.poll_next_unpin(cx)? {
Poll::Pending => {
return Poll::Pending;
}
Poll::Ready(Some(note)) => {
let process_id = note.process_id;
let commands = commands.lock().unwrap();
let process_status = match &commands.get(&process_id) {
None => HealthCheckResponse_ServingStatus::UNKNOWN,
Some(&(exit_status, _)) => match exit_status {
None => HealthCheckResponse_ServingStatus::SERVING,
Some(_) => HealthCheckResponse_ServingStatus::NOT_SERVING,
},
};
resp.send_data(HealthCheckResponse {
status: process_status,
..Default::default()
})
.unwrap();
}
Poll::Ready(None) => {
resp.send_trailers(Metadata::new()).expect("send");
return Poll::Ready(Ok(()));
}
}
}
});
Ok(())
}
}
/*
* The struct which consists of file descriptors of standard I/O
*/
#[repr(C)]
pub struct occlum_stdio_fds {
pub stdin_fd: i32,
pub stdout_fd: i32,
pub stderr_fd: i32,
}
extern "C" {
/*
* @brief Execute a command inside the Occlum enclave
*
* @param cmd_path The path of the command to be executed
* @param cmd_args The arguments to the command. The array must be NULL
* terminated.
* @param io_fds The file descriptors of the redirected standard I/O
* (i.e., stdin, stdout, stderr), If set to NULL, will
* use the original standard I/O file descriptors.
* @param exit_status Output. The exit status of the command. Note that the
* exit status is returned if and only if the function
* succeeds.
*
* @retval If 0, then success; otherwise, check errno for the exact error type.
*/
fn occlum_pal_exec(
cmd_path: *const libc::c_char,
cmd_args: *const *const libc::c_char,
io_fds: *const occlum_stdio_fds,
exit_status: *mut i32,
) -> i32;
/*
* @brief Send a signal to one or multiple LibOS processes
*
* @param pid If pid > 0, send the signal to the process with the
* pid; if pid == -1, send the signal to all processes.
* @param sig The signal number. For the purpose of security, the
* only allowed signals for now are SIGKILL and SIGTERM.
*
* @retval If 0, then success; otherwise, check errno for the exact error type.
*/
fn occlum_pal_kill(pid: i32, sig: i32) -> i32;
}
/// Executes the command inside Occlum enclave
fn rust_occlum_pal_exec(
cmd: &str,
args: &Vec<String>,
stdio: &occlum_stdio_fds,
exit_status: &mut i32,
) -> Result<(), i32> {
let cmd_path = CString::new(cmd).expect("cmd_path: new failed");
let mut cmd_args = Vec::<CString>::new();
let mut cmd_args_array = Vec::<*const libc::c_char>::new();
for arg in args {
let arg = CString::new(arg.as_str()).expect("arg: new failed");
&cmd_args_array.push(arg.as_ptr());
&cmd_args.push(arg);
}
cmd_args_array.push(0 as *const libc::c_char);
let stdio_raw = Box::new(stdio);
info!("{:?} {:?}", cmd_path, cmd_args);
let ret = unsafe {
occlum_pal_exec(
cmd_path.as_ptr() as *const libc::c_char,
Box::into_raw(cmd_args_array.into_boxed_slice()) as *const *const libc::c_char,
*stdio_raw,
exit_status as *mut i32,
)
};
match ret {
0 => Ok(()),
_ => Err(ret),
}
}
/// Send a signal to one or multiple LibOS processes
// only support SIGKILL and SIGTERM
const SIGKILL: i32 = 9;
const SIGTERM: i32 = 15;
fn rust_occlum_pal_kill(pid: i32, sig: i32) -> Result<i32, i32> {
let ret = unsafe { occlum_pal_kill(pid, sig) };
if ret == 0 {
return Ok(0);
} else {
return Err(ret);
}
}

@ -66,8 +66,10 @@ fn exit_process(thread: &ThreadRef, term_status: TermStatus) {
let mut parent_inner = super::IDLE.process().inner();
let mut process_inner = process.inner();
table::del_thread(thread.tid()).expect("tid must be in the table");
table::del_process(process.pid()).expect("pid must be in the table");
let pid = process.pid();
let main_tid = pid;
table::del_thread(main_tid).expect("tid must be in the table");
table::del_process(pid).expect("pid must be in the table");
process_inner.exit(term_status);
parent_inner.remove_zombie_child(process.pid());

@ -3,6 +3,7 @@
occlum_pal_get_version;
occlum_pal_init;
occlum_pal_exec;
occlum_pal_kill;
occlum_pal_destroy;
local:
*;

@ -11,7 +11,7 @@ endif
# Dependencies: need to be compiled but not to run by any Makefile target
TEST_DEPS := client data_sink
# Tests: need to be compiled and run by test-% target
TESTS ?= empty env hello_world malloc mmap file fs_perms getpid spawn sched pipe time \
TESTS ?= env empty hello_world malloc mmap file fs_perms getpid spawn sched pipe time \
truncate readdir mkdir open stat link symlink chmod chown tls pthread uname rlimit \
server server_epoll unix_socket cout hostfs cpuid rdtsc device sleep exit_group \
ioctl fcntl eventfd emulate_syscall access signal
@ -62,17 +62,27 @@ postbuild:
# Test targets
#############################################################################
test: build $(TEST_TARGETS)
test: build pretest $(TEST_TARGETS) posttest
pretest:
@cd $(BUILD_DIR)/test && \
$(BUILD_DIR)/bin/occlum start
$(TEST_TARGETS): test-%: %
@$(ECHO) "$(CYAN)RUN TEST => $<$(NO_COLOR)"
@# Restart server if test failed
@$(MAKE) --no-print-directory -C $< test ; \
if [ $$? -eq 0 ] ; then \
$(ECHO) "$(GREEN)PASS$(NO_COLOR)" ; \
else \
$(ECHO) "$(RED)FAILED$(NO_COLOR)" ; \
cd $(BUILD_DIR)/test && \
$(BUILD_DIR)/bin/occlum start ; \
fi ;
posttest:
@cd $(BUILD_DIR)/test && \
$(BUILD_DIR)/bin/occlum stop
#############################################################################
# Benchmark targets
#############################################################################

@ -26,20 +26,19 @@ static void* busyloop_thread_func(void* _) {
}
// Type 2: a sleeping thread
static void* sleeping_thread_func(void* _) {
unsigned int a_year_in_sec = 365 * 24 * 60 * 60;
sleep(a_year_in_sec);
return NULL;
}
//static void* sleeping_thread_func(void* _) {
// unsigned int a_year_in_sec = 365 * 24 * 60 * 60;
// sleep(a_year_in_sec);
// return NULL;
//}
// Type 3: a thead that keeps waiting on a futex
static void* futex_wait_thread_func(void* _) {
// Wait on a futex forever
int my_private_futex = 0;
syscall(SYS_futex, &my_private_futex, FUTEX_WAIT, my_private_futex);
return NULL;
}
//static void* futex_wait_thread_func(void* _) {
// // Wait on a futex forever
// int my_private_futex = 0;
// syscall(SYS_futex, &my_private_futex, FUTEX_WAIT, my_private_futex);
// return NULL;
//}
// exit_group syscall should terminate all threads in a thread group.
int test_exit_group_to_force_threads_terminate(void) {
@ -49,16 +48,18 @@ int test_exit_group_to_force_threads_terminate(void) {
printf("ERROR: pthread_create failed\n");
return -1;
}
pthread_t sleeping_thread;
if (pthread_create(&sleeping_thread, NULL, sleeping_thread_func, NULL) < 0) {
printf("ERROR: pthread_create failed\n");
return -1;
}
pthread_t futex_wait_thread;
if (pthread_create(&futex_wait_thread, NULL, futex_wait_thread_func, NULL) < 0) {
printf("ERROR: pthread_create failed\n");
return -1;
}
// Disable below two test cases, needs interrupt support
// pthread_t sleeping_thread;
// if (pthread_create(&sleeping_thread, NULL, sleeping_thread_func, NULL) < 0) {
// printf("ERROR: pthread_create failed\n");
// return -1;
// }
// pthread_t futex_wait_thread;
// if (pthread_create(&futex_wait_thread, NULL, futex_wait_thread_func, NULL) < 0) {
// printf("ERROR: pthread_create failed\n");
// return -1;
// }
// Sleep for a while to make sure all three threads are running
useconds_t _200ms = 200 * 1000;

@ -71,7 +71,7 @@ $(BUILD_DIR)/test/obj/$(TEST_NAME)/%.o: %.cc
test:
@cd $(BUILD_DIR)/test && \
$(BUILD_DIR)/bin/occlum run /bin/$(TEST_NAME) $(BIN_ARGS)
$(BUILD_DIR)/bin/occlum exec /bin/$(TEST_NAME) $(BIN_ARGS)
test-native:
@LD_LIBRARY_PATH=/usr/local/occlum/lib cd $(IMAGE_DIR) && ./bin/$(TEST_NAME) $(BIN_ARGS)

@ -227,6 +227,9 @@ cmd_build() {
mkdir -p "$context_dir/run/mount/root"
ln -s $occlum_dir/$build_dir/bin/occlum_exec_client $context_dir/build/bin/occlum_exec_client
ln -s $occlum_dir/$build_dir/bin/occlum_exec_server $context_dir/build/bin/occlum_exec_server
echo "Built the Occlum image and enclave successfully"
}
@ -248,6 +251,60 @@ cmd_run() {
echo "built" > "$context_dir/status"
}
cmd_start() {
check_has_built
SGX_MODE=$(cat $context_dir/.sgx_mode)
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
export LD_LIBRARY_PATH="$context_dir/build/lib:$SGX_SDK/sdk_libs/"
else
export LD_LIBRARY_PATH="$context_dir/build/lib"
fi
cd "$working_dir"
echo "running" > "$context_dir/status"
RUST_BACKTRACE=1 "$context_dir/build/bin/occlum_exec_client" start
echo "built" > "$context_dir/status"
}
cmd_exec() {
check_has_built
SGX_MODE=$(cat $context_dir/.sgx_mode)
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
export LD_LIBRARY_PATH="$context_dir/build/lib:$SGX_SDK/sdk_libs/"
else
export LD_LIBRARY_PATH="$context_dir/build/lib"
fi
cd "$working_dir"
echo "running" > "$context_dir/status"
RUST_BACKTRACE=1 "$context_dir/build/bin/occlum_exec_client" exec -- "$@"
echo "built" > "$context_dir/status"
}
cmd_stop() {
check_has_built
SGX_MODE=$(cat $context_dir/.sgx_mode)
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
export LD_LIBRARY_PATH="$context_dir/build/lib:$SGX_SDK/sdk_libs/"
else
export LD_LIBRARY_PATH="$context_dir/build/lib"
fi
cd "$working_dir"
echo "running" > "$context_dir/status"
RUST_BACKTRACE=1 "$context_dir/build/bin/occlum_exec_client" stop -t 0
echo "built" > "$context_dir/status"
}
cmd_gdb() {
check_has_built
@ -288,6 +345,15 @@ case "$cmd" in
run)
cmd_run "${@:2}"
;;
start)
cmd_start
;;
exec)
cmd_exec "${@:2}"
;;
stop)
cmd_stop
;;
gdb)
cmd_gdb "${@:2}"
;;