From e9e5ddd5a5d9ce99768833137eac2551a710becf Mon Sep 17 00:00:00 2001 From: Tiago Natel de Moura Date: Mon, 9 Mar 2020 16:28:25 +0000 Subject: Refactor of process management. The process abstraction has changed to: setup(task, process) start(task, process_data) prefork(task, process, mp) The prefork() occurs in the main process right before fork. The file src/nxt_main_process.c is completely free of process specific logic. The creation of a process now supports a PROCESS_CREATED state. The The setup() function of each process can set its state to either created or ready. If created, a MSG_PROCESS_CREATED is sent to main process, where external setup can be done (required for rootfs under container). The core processes (discovery, controller and router) doesn't need external setup, then they all proceeds to their start() function straight away. In the case of applications, the load of the module happens at the process setup() time and The module's init() function has changed to be the start() of the process. The module API has changed to: setup(task, process, conf) start(task, data) As a direct benefit of the PROCESS_CREATED message, the clone(2) of processes using pid namespaces now doesn't need to create a pipe to make the child block until parent setup uid/gid mappings nor it needs to receive the child pid. --- src/nxt_java.c | 61 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 28 deletions(-) (limited to 'src/nxt_java.c') diff --git a/src/nxt_java.c b/src/nxt_java.c index 004907d6..c4145c1d 100644 --- a/src/nxt_java.c +++ b/src/nxt_java.c @@ -27,9 +27,10 @@ #include "nxt_jars.h" -static nxt_int_t nxt_java_pre_init(nxt_task_t *task, +static nxt_int_t nxt_java_setup(nxt_task_t *task, nxt_process_t *process, nxt_common_app_conf_t *conf); -static nxt_int_t nxt_java_init(nxt_task_t *task, nxt_common_app_conf_t *conf); +static nxt_int_t nxt_java_start(nxt_task_t *task, + nxt_process_data_t *data); static void nxt_java_request_handler(nxt_unit_request_info_t *req); static void nxt_java_websocket_handler(nxt_unit_websocket_frame_t *ws); static void nxt_java_close_handler(nxt_unit_request_info_t *req); @@ -49,8 +50,8 @@ NXT_EXPORT nxt_app_module_t nxt_app_module = { compat, nxt_string("java"), NXT_STRING(NXT_JAVA_VERSION), - nxt_java_pre_init, - nxt_java_init, + nxt_java_setup, + nxt_java_start, }; typedef struct { @@ -60,7 +61,8 @@ typedef struct { static nxt_int_t -nxt_java_pre_init(nxt_task_t *task, nxt_common_app_conf_t *conf) +nxt_java_setup(nxt_task_t *task, nxt_process_t *process, + nxt_common_app_conf_t *conf) { const char *unit_jars; @@ -115,24 +117,26 @@ nxt_java_module_jars(const char *jars[], int jar_count) static nxt_int_t -nxt_java_init(nxt_task_t *task, nxt_common_app_conf_t *conf) +nxt_java_start(nxt_task_t *task, nxt_process_data_t *data) { - jint rc; - char *opt, *real_path; - char **classpath_arr, **unit_jars, **system_jars; - JavaVM *jvm; - JNIEnv *env; - jobject cl, classpath; - nxt_str_t str; - nxt_int_t opt_len, real_path_len; - nxt_uint_t i, unit_jars_count, classpath_count, system_jars_count; - JavaVMOption *jvm_opt; - JavaVMInitArgs jvm_args; - nxt_unit_ctx_t *ctx; - nxt_unit_init_t java_init; - nxt_java_data_t data; - nxt_conf_value_t *value; - nxt_java_app_conf_t *c; + jint rc; + char *opt, *real_path; + char **classpath_arr, **unit_jars, **system_jars; + JavaVM *jvm; + JNIEnv *env; + jobject cl, classpath; + nxt_str_t str; + nxt_int_t opt_len, real_path_len; + nxt_uint_t i, unit_jars_count, classpath_count; + nxt_uint_t system_jars_count; + JavaVMOption *jvm_opt; + JavaVMInitArgs jvm_args; + nxt_unit_ctx_t *ctx; + nxt_unit_init_t java_init; + nxt_java_data_t java_data; + nxt_conf_value_t *value; + nxt_java_app_conf_t *c; + nxt_common_app_conf_t *app_conf; //setenv("ASAN_OPTIONS", "handle_segv=0", 1); @@ -140,7 +144,8 @@ nxt_java_init(nxt_task_t *task, nxt_common_app_conf_t *conf) jvm_args.nOptions = 0; jvm_args.ignoreUnrecognized = 0; - c = &conf->u.java; + app_conf = data->app; + c = &app_conf->u.java; if (c->options != NULL) { jvm_args.nOptions += nxt_conf_array_elements_count(c->options); @@ -338,8 +343,8 @@ nxt_java_init(nxt_task_t *task, nxt_common_app_conf_t *conf) goto env_failed; } - data.env = env; - data.ctx = nxt_java_startContext(env, c->webapp, classpath); + java_data.env = env; + java_data.ctx = nxt_java_startContext(env, c->webapp, classpath); if ((*env)->ExceptionCheck(env)) { nxt_alert(task, "Unhandled exception in application start"); @@ -353,8 +358,8 @@ nxt_java_init(nxt_task_t *task, nxt_common_app_conf_t *conf) java_init.callbacks.websocket_handler = nxt_java_websocket_handler; java_init.callbacks.close_handler = nxt_java_close_handler; java_init.request_data_size = sizeof(nxt_java_request_data_t); - java_init.data = &data; - java_init.shm_limit = conf->shm_limit; + java_init.data = &java_data; + java_init.shm_limit = app_conf->shm_limit; ctx = nxt_unit_init(&java_init); if (nxt_slow_path(ctx == NULL)) { @@ -367,7 +372,7 @@ nxt_java_init(nxt_task_t *task, nxt_common_app_conf_t *conf) /* TODO report error */ } - nxt_java_stopContext(env, data.ctx); + nxt_java_stopContext(env, java_data.ctx); if ((*env)->ExceptionCheck(env)) { (*env)->ExceptionDescribe(env); -- cgit From e2b53e16c60ba1e3bbbe59172c184e97f889326b Mon Sep 17 00:00:00 2001 From: Tiago Natel de Moura Date: Thu, 28 May 2020 14:57:41 +0100 Subject: Added "rootfs" feature. --- src/nxt_java.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 7 deletions(-) (limited to 'src/nxt_java.c') diff --git a/src/nxt_java.c b/src/nxt_java.c index c4145c1d..c7471509 100644 --- a/src/nxt_java.c +++ b/src/nxt_java.c @@ -26,6 +26,7 @@ #include "java/nxt_jni_URLClassLoader.h" #include "nxt_jars.h" +#include "nxt_java_mounts.h" static nxt_int_t nxt_java_setup(nxt_task_t *task, nxt_process_t *process, nxt_common_app_conf_t *conf); @@ -50,6 +51,8 @@ NXT_EXPORT nxt_app_module_t nxt_app_module = { compat, nxt_string("java"), NXT_STRING(NXT_JAVA_VERSION), + nxt_java_mounts, + nxt_nitems(nxt_java_mounts), nxt_java_setup, nxt_java_start, }; @@ -64,20 +67,66 @@ static nxt_int_t nxt_java_setup(nxt_task_t *task, nxt_process_t *process, nxt_common_app_conf_t *conf) { + char *path, *relpath, *p, *rootfs; + size_t jars_dir_len, rootfs_len; const char *unit_jars; + rootfs = (char *) process->isolation.rootfs; + rootfs_len = 0; + unit_jars = conf->u.java.unit_jars; if (unit_jars == NULL) { - unit_jars = NXT_JARS; + if (rootfs != NULL) { + unit_jars = "/"; + } else { + unit_jars = NXT_JARS; + } } - nxt_java_modules = realpath(unit_jars, NULL); - if (nxt_java_modules == NULL) { - nxt_alert(task, "realpath(%s) failed: %E", unit_jars, nxt_errno); + relpath = strdup(unit_jars); + if (nxt_slow_path(relpath == NULL)) { return NXT_ERROR; } + if (rootfs != NULL) { + jars_dir_len = strlen(unit_jars); + rootfs_len = strlen(rootfs); + + path = nxt_malloc(jars_dir_len + rootfs_len + 1); + if (nxt_slow_path(path == NULL)) { + free(relpath); + return NXT_ERROR; + } + + p = nxt_cpymem(path, process->isolation.rootfs, rootfs_len); + p = nxt_cpymem(p, relpath, jars_dir_len); + *p = '\0'; + + free(relpath); + + } else { + path = relpath; + } + + nxt_java_modules = realpath(path, NULL); + if (nxt_java_modules == NULL) { + nxt_alert(task, "realpath(\"%s\") failed %E", path, nxt_errno); + goto free; + } + + if (rootfs != NULL && strlen(path) > rootfs_len) { + nxt_java_modules = path + rootfs_len; + } + + nxt_debug(task, "JAVA MODULES: %s", nxt_java_modules); + return NXT_OK; + +free: + + nxt_free(path); + + return NXT_ERROR; } @@ -85,6 +134,7 @@ static char ** nxt_java_module_jars(const char *jars[], int jar_count) { char **res, *jurl; + uint8_t pathsep; nxt_int_t modules_len, jlen, i; const char **jar; @@ -95,9 +145,13 @@ nxt_java_module_jars(const char *jars[], int jar_count) modules_len = nxt_strlen(nxt_java_modules); + pathsep = nxt_java_modules[modules_len - 1] == '/'; + for (i = 0, jar = jars; *jar != NULL; jar++) { - jlen = nxt_length("file:") + modules_len + nxt_length("/") - + nxt_strlen(*jar) + 1; + jlen = nxt_length("file:") + modules_len + + (!pathsep ? nxt_length("/") : 0) + + nxt_strlen(*jar) + 1; + jurl = nxt_malloc(jlen); if (jurl == NULL) { return NULL; @@ -107,7 +161,11 @@ nxt_java_module_jars(const char *jars[], int jar_count) jurl = nxt_cpymem(jurl, "file:", nxt_length("file:")); jurl = nxt_cpymem(jurl, nxt_java_modules, modules_len); - *jurl++ = '/'; + + if (!pathsep) { + *jurl++ = '/'; + } + jurl = nxt_cpymem(jurl, *jar, nxt_strlen(*jar)); *jurl++ = '\0'; } -- cgit