Skip to content

Commit

Permalink
Merge pull request #70 from dpfens/change_entrypoint
Browse files Browse the repository at this point in the history
Add WasmEntryPoint directive to change/specify entrypoints
  • Loading branch information
gzurl authored Jan 23, 2024
2 parents c389304 + ebfaaea commit a26641d
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 3 deletions.
1 change: 1 addition & 0 deletions mod_wasm/httpd.conf
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ LoadModule wasm_module modules/mod_wasm.so
<Location /hello-wasm>
SetHandler wasm-handler
WasmModule /usr/local/apache2/wasm_modules/rust-wasm/hello_wasm.wasm
WasmEntryPoint _start
</Location>

###################################################################
Expand Down
21 changes: 20 additions & 1 deletion mod_wasm/modules/wasm/mod_wasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ static void register_hooks(apr_pool_t *p)
#define WASM_DIRECTIVE_WASMMAPDIR "WasmMapDir"
#define WASM_DIRECTIVE_WASMENABLECGI "WasmEnableCGI"
#define WASM_DIRECTIVE_WASMMAPCGIFILENAMES "WasmMapCGIFileNames"
#define WASM_DIRECTIVE_WASMENTRYPOINT "WasmEntryPoint"

static const char *wasm_directive_WasmModule(cmd_parms *cmd, void *mconfig, const char *word1)
{
Expand Down Expand Up @@ -518,6 +519,17 @@ static const char *wasm_directive_WasmMapCGIFileNames(cmd_parms *cmd, void *mcon
return NULL;
}

static const char *wasm_directive_WasmEntryPoint(cmd_parms *cmd, void *mconfig, const char *entrypoint)
{
x_cfg *cfg = (x_cfg *) mconfig;
int ret = wasm_config_entrypoint_set(cfg->loc, entrypoint);
if ( ret != OK )
ap_log_error(APLOG_MARK, APLOG_ERR, ret, NULL,
"wasm_directive_WasmEntryPoint() - ERROR! Couldn't set entrypoint '%s' to Wasm config '%s'!", entrypoint, cfg->loc);

return NULL;
}

/*
* List of directives specific to our module.
*/
Expand All @@ -542,7 +554,7 @@ static const command_rec directives[] =
wasm_directive_WasmEnv,
NULL,
OR_OPTIONS,
"Set environtment variable for the Wasm Module"
"Set environment variable for the Wasm Module"
),
AP_INIT_TAKE1(
WASM_DIRECTIVE_WASMDIR,
Expand Down Expand Up @@ -572,6 +584,13 @@ static const command_rec directives[] =
OR_OPTIONS,
"Whether SCRIPT_FILENAME should be mapped based on WasmMapDir mounts when running as a CGI"
),
AP_INIT_TAKE1(
WASM_DIRECTIVE_WASMENTRYPOINT,
wasm_directive_WasmEntryPoint,
NULL,
OR_OPTIONS,
"Set entrypoint for the Wasm Module"
),
{NULL}
};

Expand Down
45 changes: 45 additions & 0 deletions wasm_runtime/src/c_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,38 @@ pub extern "C" fn wasm_executionctx_stdin_set(executionctx_id: *const c_char, bu
}


/// Set the entrypoint for loaded Wasm Module to an existing Wasm Config.
///
/// Wasm config must have been previously created.
///
/// In case of error, the reason is printed to stderr and returns -1.
/// Otherwise, it returns 0.
///
/// Due to String management differences between C and Rust, this function uses `unsafe {}` code.
/// So `config_id` and `entrypoint` must be a valid pointer to a null-terminated C char array. Otherwise, code might panic.
/// In addition, `config_id` and `entrypoint` must contain valid ASCII chars that can be converted into UTF-8 encoding.
///
/// # Examples (C Code)
///
/// ```
/// wasm_config_entrypoint_set("Drupal", "_start");
/// wasm_config_entrypoint_set("WordPress", "run");
/// ```
#[no_mangle]
pub extern "C" fn wasm_config_entrypoint_set(config_id: *const c_char, entrypoint: *const c_char) -> c_int {
let config_id_str = const_c_char_to_str(config_id);
let entrypoint_str = const_c_char_to_str(entrypoint);

match WasmConfig::set_entrypoint_for_config(config_id_str, entrypoint_str) {
Ok(_) => 0,
Err(e) => {
eprintln!("ERROR! C-API: Couldn't set entrypoint for Wasm config \"{}\": {}", config_id_str, e);
-1
}
}
}


/// Run the given Wasm execution context
///
/// In case of error, the reason is printed to stderr and returns -1.
Expand Down Expand Up @@ -638,4 +670,17 @@ mod tests {
// assert
assert_eq!(val, 0);
}

#[test]
fn wasm_config_entrypoint_set_general() {
let config_id = CString::new("test_config").unwrap();

// test
wasm_config_create(config_id.as_ptr());
let entrypoint = CString::new("run").unwrap();
let val = wasm_config_entrypoint_set(config_id.as_ptr(), entrypoint.as_ptr());

// asserts
assert_eq!(val, 0);
}
}
28 changes: 28 additions & 0 deletions wasm_runtime/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use path_slash::PathBufExt as _;
pub struct WasmConfig {
pub id: String,
pub module_id: String,
pub entrypoint: String,
pub wasi_args: Vec<String>,
pub wasi_envs: Vec<(String, String)>,
pub wasi_dirs: Vec<String>,
Expand Down Expand Up @@ -59,6 +60,7 @@ impl WasmConfig {
wasi_envs: Vec::new(),
wasi_dirs: Vec::new(),
wasi_mapdirs: Vec::new(),
entrypoint: "_start".to_string() // defaults to "_start"
};

// insert created WasmConfig object into the HashMap
Expand Down Expand Up @@ -212,6 +214,32 @@ impl WasmConfig {
Ok(())
}

// Set the entrypoint for a loaded Wasm Module to an existing Wasm config
///
/// It checks for wrong `config_id`
/// Returns Result<(), String>, so that in case of error the String will contain the reason.
///
pub fn set_entrypoint_for_config(config_id: &str, entrypoint: &str) -> Result<(), String> {

// get write access to the WasmConfig HashMap
let mut configs = WASM_RUNTIME_CONFIGS.write()
.expect("ERROR! Poisoned RwLock WASM_RUNTIME_CONFIGS on write()");

// check for existing config_id in the loaded configurations
let wasm_config = match configs.get_mut(config_id) {
Some(c) => c,
None => {
let error_msg = format!("Wasm config \'{}\' not found while setting entrypoint \'{}\'", config_id, entrypoint);
return Err(error_msg);
}
};

// setting module in Wasm config
wasm_config.entrypoint = entrypoint.to_string();

Ok(())
}

pub fn get_mapped_path(config_id: &str, path: &str) -> Result<Option<String>, String> {
let configs = WASM_RUNTIME_CONFIGS
.read()
Expand Down
6 changes: 4 additions & 2 deletions wasm_runtime/src/execution_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub struct WasmExecutionCtx {
pub wasi_mapdirs: Vec<(String, String)>,
pub wasi_stdin: Vec<u8>,
pub wasi_stdout: Arc<RwLock<Vec<u8>>>,
pub entrypoint: String
}

impl WasmExecutionCtx {
Expand Down Expand Up @@ -65,6 +66,7 @@ impl WasmExecutionCtx {
wasi_mapdirs: wasm_config.wasi_mapdirs.clone(),
wasi_stdin: Vec::new(),
wasi_stdout: Arc::new(RwLock::new(Vec::new())),
entrypoint: wasm_config.entrypoint.clone()
};

Self::try_insert(wasm_executionctx)
Expand Down Expand Up @@ -154,8 +156,8 @@ impl WasmExecutionCtx {
}
};

// invoke default "_start" function for the given Wasm execution context
wasm_engine::invoke_wasm_function(&wasm_executionctx, "_start")?;
// invoke entrypoint for the given Wasm execution context (default is "_start")
wasm_engine::invoke_wasm_function(&wasm_executionctx, &wasm_executionctx.entrypoint)?;

// read stdout from the Wasm execution context and return it
let wasm_module_stdout = Self::read_stdout(&wasm_executionctx);
Expand Down

0 comments on commit a26641d

Please sign in to comment.