Skip to content
This repository was archived by the owner on Oct 26, 2021. It is now read-only.

Commit 63527d8

Browse files
committed
Add Workldr trait, use it to load internal wasmldr
In parallel with the Backend trait, this commit adds a Workldr trait for handling `wasmldr` (and any future workldr implementations.) We've also got a naive function for picking the "best" workldr (there's only one, so that's easy) and using that for `exec` if nothing was passed on the CLI. Signed-off-by: Will Woods <[email protected]>
1 parent 50eb2f6 commit 63527d8

File tree

3 files changed

+82
-6
lines changed

3 files changed

+82
-6
lines changed

src/main.rs

+27-6
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,11 @@
5757
#![feature(asm)]
5858

5959
mod backend;
60+
mod workldr;
6061
mod protobuf;
6162

6263
use backend::{Backend, Command};
64+
use workldr::Workldr;
6365

6466
use std::convert::TryInto;
6567
use std::path::PathBuf;
@@ -78,7 +80,7 @@ struct Info {}
7880
#[derive(StructOpt)]
7981
struct Exec {
8082
/// The payload to run inside the keep
81-
code: PathBuf,
83+
code: Option<PathBuf>,
8284
}
8385

8486
#[derive(StructOpt)]
@@ -95,9 +97,24 @@ fn main() -> Result<()> {
9597
Box::new(backend::sgx::Backend),
9698
];
9799

100+
let workldrs: &[Box<dyn Workldr>] = &[
101+
#[cfg(feature = "wasmldr")]
102+
Box::new(workldr::wasmldr::Wasmldr),
103+
];
104+
98105
match Options::from_args() {
99106
Options::Info(_) => info(backends),
100-
Options::Exec(e) => exec(backends, e),
107+
Options::Exec(e) => {
108+
// FUTURE: accept tenant-provided shim, or fall back to builtin..
109+
let backend = backend(backends);
110+
let shim_bytes = backend.shim();
111+
if let Some(path) = e.code {
112+
let map = mmarinus::Kind::Private.load::<mmarinus::perms::Read, _>(&path)?;
113+
exec(backend, shim_bytes, map)
114+
} else {
115+
exec(backend, shim_bytes, workldr(workldrs).exec())
116+
}
117+
},
101118
}
102119
}
103120

@@ -149,12 +166,16 @@ fn backend(backends: &[Box<dyn Backend>]) -> &dyn Backend {
149166
}
150167
}
151168

152-
fn exec(backends: &[Box<dyn Backend>], opts: Exec) -> Result<()> {
153-
let backend = backend(backends);
169+
#[inline]
170+
fn workldr(workldrs: &[Box<dyn Workldr>]) -> &dyn Workldr {
171+
// NOTE: this is stupid, but we only have one workldr, so... ¯\_(ツ)_/¯
172+
&*workldrs[0]
173+
}
154174

155-
let map = mmarinus::Kind::Private.load::<mmarinus::perms::Read, _>(&opts.code)?;
175+
fn exec(backend: &dyn Backend, shim: impl AsRef<[u8]>, exec: impl AsRef<[u8]>) -> Result<()> {
176+
//let map = mmarinus::Kind::Private.load::<mmarinus::perms::Read, _>(&opts.code)?;
156177

157-
let keep = backend.keep(backend.shim(), &map)?;
178+
let keep = backend.keep(shim.as_ref(), exec.as_ref())?;
158179
let mut thread = keep.clone().spawn()?.unwrap();
159180
loop {
160181
match thread.enter()? {

src/workldr/mod.rs

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
// FUTURE: right now we only have one Workldr, `wasmldr`.
4+
// In the future there may be other workload types - in theory we can run
5+
// any static PIE ELF binary. We could have a Lua interpreter, or a
6+
// JavaScript interpreter, or whatever.
7+
// So there's two parts to this trait - call them KeepSetup and Engine.
8+
//
9+
// KeepSetup is the part that actually sets up the Keep for the Workload,
10+
// which might involve setting up network sockets, storage devices, etc.
11+
// This part must be implemented by any Workldr, since we want the
12+
// Enarx environment to be platform-agnostic.
13+
//
14+
// Engine is the (workload-specific) portion that actually interprets or
15+
// executes the workload. It's responsible for taking the sockets / devices
16+
// etc. that were set up by KeepSetup and making them usable in a way that
17+
// the workload will understand.
18+
//
19+
// So: someday we might want to split this into two traits, and we might
20+
// have multiple Workldrs for different languages/environments, and we
21+
// might need to examine the workload and determine which Workldr is
22+
// the right one to use. But first... we gotta make wasmldr work.
23+
24+
#[cfg(feature = "wasmldr")]
25+
pub mod wasmldr;
26+
27+
/// A trait for the "Workloader" - shortened to Workldr, also known as "exec"
28+
/// (as in Backend::keep(shim, exec) [q.v.]) and formerly known as the "code"
29+
/// layer. This is the part that runs inside the keep, prepares the workload
30+
/// environment, and then actually executes the tenant's workload.
31+
///
32+
/// Basically, this is a generic view of wasmldr.
33+
pub trait Workldr {
34+
/// The name of the Workldr
35+
fn name(&self) -> &'static str;
36+
37+
/// The builtin Workldr binary (e.g. wasmldr)
38+
fn exec(&self) -> &'static [u8];
39+
}
40+

src/workldr/wasmldr/mod.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
pub struct Wasmldr;
4+
5+
impl crate::workldr::Workldr for Wasmldr {
6+
#[inline]
7+
fn name(&self) -> &'static str {
8+
"wasmldr"
9+
}
10+
11+
#[inline]
12+
fn exec(&self) -> &'static [u8] {
13+
include_bytes!(concat!(env!("OUT_DIR"), "/bin/wasmldr"))
14+
}
15+
}

0 commit comments

Comments
 (0)