From 5fa5b1464f2a0623bb7ee7c68ff6f9d18e744ed4 Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Sat, 9 Oct 2021 10:44:31 +0800 Subject: Configuration: automatic migration to the new "share" behavior. --- src/nxt_conf.h | 2 + src/nxt_conf_validation.c | 21 +++++++++ src/nxt_controller.c | 107 +++++++++++++++++++++++++++++++++++----------- src/nxt_main_process.c | 65 +++++++++++++++++++--------- src/nxt_main_process.h | 1 + src/nxt_runtime.c | 15 +++++++ src/nxt_runtime.h | 2 + 7 files changed, 167 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/nxt_conf.h b/src/nxt_conf.h index 149af39a..8b3565fd 100644 --- a/src/nxt_conf.h +++ b/src/nxt_conf.h @@ -72,6 +72,8 @@ typedef struct { nxt_mp_t *pool; nxt_str_t error; void *ctx; + nxt_mp_t *conf_pool; + nxt_uint_t ver; } nxt_conf_validation_t; diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index 55107cd6..5701ae17 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -1624,6 +1624,11 @@ static nxt_int_t nxt_conf_vldt_share(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data) { + u_char *p; + nxt_str_t name, temp; + + static nxt_str_t uri = nxt_string("$uri"); + if (nxt_conf_type(value) == NXT_CONF_ARRAY) { if (nxt_conf_array_elements_count(value) == 0) { return nxt_conf_vldt_error(vldt, "The \"share\" array " @@ -1636,6 +1641,22 @@ nxt_conf_vldt_share(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, /* NXT_CONF_STRING */ + if (vldt->ver < 12600) { + nxt_conf_get_string(value, &name); + + temp.length = name.length + uri.length; + + temp.start = nxt_mp_get(vldt->conf_pool, temp.length); + if (nxt_slow_path(temp.start == NULL)) { + return NXT_ERROR; + } + + p = nxt_cpymem(temp.start, name.start, name.length); + nxt_memcpy(p, uri.start, uri.length); + + nxt_conf_set_string(value, &temp); + } + return nxt_conf_vldt_share_element(vldt, value); } diff --git a/src/nxt_controller.c b/src/nxt_controller.c index 779a625d..7510d6f0 100644 --- a/src/nxt_controller.c +++ b/src/nxt_controller.c @@ -41,6 +41,8 @@ typedef struct { static nxt_int_t nxt_controller_prefork(nxt_task_t *task, nxt_process_t *process, nxt_mp_t *mp); +static nxt_int_t nxt_controller_file_read(nxt_task_t *task, const char *name, + nxt_str_t *str, nxt_mp_t *mp); static nxt_int_t nxt_controller_start(nxt_task_t *task, nxt_process_data_t *data); static void nxt_controller_process_new_port_handler(nxt_task_t *task, @@ -154,12 +156,9 @@ const nxt_process_init_t nxt_controller_process = { static nxt_int_t nxt_controller_prefork(nxt_task_t *task, nxt_process_t *process, nxt_mp_t *mp) { - ssize_t n; - nxt_int_t ret; - nxt_str_t *conf; - nxt_file_t file; + nxt_str_t ver; + nxt_int_t ret, num; nxt_runtime_t *rt; - nxt_file_info_t fi; nxt_controller_init_t ctrl_init; nxt_log(task, NXT_LOG_INFO, "controller started"); @@ -168,48 +167,98 @@ nxt_controller_prefork(nxt_task_t *task, nxt_process_t *process, nxt_mp_t *mp) nxt_memzero(&ctrl_init, sizeof(nxt_controller_init_t)); - conf = &ctrl_init.conf; + /* + * Since configuration version has only been introduced in 1.26, + * set the default version to 1.25. + */ + nxt_conf_ver = 12500; + + ret = nxt_controller_file_read(task, rt->conf, &ctrl_init.conf, mp); + if (nxt_slow_path(ret == NXT_ERROR)) { + return NXT_ERROR; + } + + if (ret == NXT_OK) { + ret = nxt_controller_file_read(task, rt->ver, &ver, mp); + if (nxt_slow_path(ret == NXT_ERROR)) { + return NXT_ERROR; + } + + if (ret == NXT_OK) { + num = nxt_int_parse(ver.start, ver.length); + + if (nxt_slow_path(num < 0)) { + nxt_alert(task, "failed to restore previous configuration: " + "invalid version string \"%V\"", &ver); + + nxt_str_null(&ctrl_init.conf); + + } else { + nxt_conf_ver = num; + } + } + } + +#if (NXT_TLS) + ctrl_init.certs = nxt_cert_store_load(task, mp); + + nxt_mp_cleanup(mp, nxt_controller_cert_cleanup, task, ctrl_init.certs, rt); +#endif + + process->data.controller = ctrl_init; + + return NXT_OK; +} + + +static nxt_int_t +nxt_controller_file_read(nxt_task_t *task, const char *name, nxt_str_t *str, + nxt_mp_t *mp) +{ + ssize_t n; + nxt_int_t ret; + nxt_file_t file; + nxt_file_info_t fi; nxt_memzero(&file, sizeof(nxt_file_t)); - file.name = (nxt_file_name_t *) rt->conf; + file.name = (nxt_file_name_t *) name; ret = nxt_file_open(task, &file, NXT_FILE_RDONLY, NXT_FILE_OPEN, 0); if (ret == NXT_OK) { ret = nxt_file_info(&file, &fi); + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; + } - if (nxt_fast_path(ret == NXT_OK && nxt_is_file(&fi))) { - conf->length = nxt_file_size(&fi); - conf->start = nxt_mp_alloc(mp, conf->length); - if (nxt_slow_path(conf->start == NULL)) { - nxt_file_close(task, &file); - return NXT_ERROR; + if (nxt_fast_path(nxt_is_file(&fi))) { + str->length = nxt_file_size(&fi); + str->start = nxt_mp_nget(mp, str->length); + if (nxt_slow_path(str->start == NULL)) { + goto fail; } - n = nxt_file_read(&file, conf->start, conf->length, 0); + n = nxt_file_read(&file, str->start, str->length, 0); + if (nxt_slow_path(n != (ssize_t) str->length)) { + goto fail; + } - if (nxt_slow_path(n != (ssize_t) conf->length)) { - conf->start = NULL; - conf->length = 0; + nxt_file_close(task, &file); - nxt_alert(task, "failed to restore previous configuration: " - "cannot read the file"); - } + return NXT_OK; } nxt_file_close(task, &file); } -#if (NXT_TLS) - ctrl_init.certs = nxt_cert_store_load(task, mp); + return NXT_DECLINED; - nxt_mp_cleanup(mp, nxt_controller_cert_cleanup, task, ctrl_init.certs, rt); -#endif +fail: - process->data.controller = ctrl_init; + nxt_file_close(task, &file); - return NXT_OK; + return NXT_ERROR; } @@ -293,6 +342,8 @@ nxt_controller_start(nxt_task_t *task, nxt_process_data_t *data) } vldt.conf = conf; + vldt.conf_pool = mp; + vldt.ver = nxt_conf_ver; ret = nxt_conf_validate(&vldt); @@ -1224,6 +1275,8 @@ nxt_controller_process_config(nxt_task_t *task, nxt_controller_request_t *req, vldt.conf = value; vldt.pool = c->mem_pool; + vldt.conf_pool = mp; + vldt.ver = NXT_VERNUM; rc = nxt_conf_validate(&vldt); @@ -1305,6 +1358,8 @@ nxt_controller_process_config(nxt_task_t *task, nxt_controller_request_t *req, vldt.conf = value; vldt.pool = c->mem_pool; + vldt.conf_pool = mp; + vldt.ver = NXT_VERNUM; rc = nxt_conf_validate(&vldt); diff --git a/src/nxt_main_process.c b/src/nxt_main_process.c index 16c6a297..559789df 100644 --- a/src/nxt_main_process.c +++ b/src/nxt_main_process.c @@ -63,6 +63,8 @@ static void nxt_main_port_modules_handler(nxt_task_t *task, static int nxt_cdecl nxt_app_lang_compare(const void *v1, const void *v2); static void nxt_main_port_conf_store_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg); +static nxt_int_t nxt_main_file_store(nxt_task_t *task, const char *tmp_name, + const char *name, u_char *buf, size_t size); static void nxt_main_port_access_log_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg); @@ -77,6 +79,8 @@ const nxt_sig_event_t nxt_main_process_signals[] = { }; +nxt_uint_t nxt_conf_ver; + static nxt_bool_t nxt_exiting; @@ -1419,11 +1423,10 @@ static void nxt_main_port_conf_store_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) { void *p; - size_t size; - ssize_t n; + size_t n, size; nxt_int_t ret; - nxt_file_t file; nxt_runtime_t *rt; + u_char ver[NXT_INT_T_LEN]; p = MAP_FAILED; @@ -1457,29 +1460,20 @@ nxt_main_port_conf_store_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) nxt_debug(task, "conf_store_handler(%uz): %*s", size, size, p); - nxt_memzero(&file, sizeof(nxt_file_t)); - rt = task->thread->runtime; - file.name = (nxt_file_name_t *) rt->conf_tmp; + if (nxt_conf_ver != NXT_VERNUM) { + n = nxt_sprintf(ver, ver + NXT_INT_T_LEN, "%d", NXT_VERNUM) - ver; - if (nxt_slow_path(nxt_file_open(task, &file, NXT_FILE_WRONLY, - NXT_FILE_TRUNCATE, NXT_FILE_OWNER_ACCESS) - != NXT_OK)) - { - goto error; - } - - n = nxt_file_write(&file, p, size, 0); - - nxt_file_close(task, &file); + ret = nxt_main_file_store(task, rt->ver_tmp, rt->ver, ver, n); + if (nxt_slow_path(ret != NXT_OK)) { + goto error; + } - if (nxt_slow_path(n != (ssize_t) size)) { - (void) nxt_file_delete(file.name); - goto error; + nxt_conf_ver = NXT_VERNUM; } - ret = nxt_file_rename(file.name, (nxt_file_name_t *) rt->conf); + ret = nxt_main_file_store(task, rt->conf_tmp, rt->conf, p, size); if (nxt_fast_path(ret == NXT_OK)) { goto cleanup; @@ -1502,6 +1496,37 @@ cleanup: } +static nxt_int_t +nxt_main_file_store(nxt_task_t *task, const char *tmp_name, const char *name, + u_char *buf, size_t size) +{ + ssize_t n; + nxt_int_t ret; + nxt_file_t file; + + nxt_memzero(&file, sizeof(nxt_file_t)); + + file.name = (nxt_file_name_t *) name; + + ret = nxt_file_open(task, &file, NXT_FILE_WRONLY, NXT_FILE_TRUNCATE, + NXT_FILE_OWNER_ACCESS); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ERROR; + } + + n = nxt_file_write(&file, buf, size, 0); + + nxt_file_close(task, &file); + + if (nxt_slow_path(n != (ssize_t) size)) { + (void) nxt_file_delete(file.name); + return NXT_ERROR; + } + + return nxt_file_rename(file.name, (nxt_file_name_t *) name); +} + + static void nxt_main_port_access_log_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) { diff --git a/src/nxt_main_process.h b/src/nxt_main_process.h index f9c974d8..80429b6c 100644 --- a/src/nxt_main_process.h +++ b/src/nxt_main_process.h @@ -23,6 +23,7 @@ nxt_int_t nxt_main_process_start(nxt_thread_t *thr, nxt_task_t *task, nxt_runtime_t *runtime); +NXT_EXPORT extern nxt_uint_t nxt_conf_ver; NXT_EXPORT extern const nxt_process_init_t nxt_discovery_process; NXT_EXPORT extern const nxt_process_init_t nxt_controller_process; NXT_EXPORT extern const nxt_process_init_t nxt_router_process; diff --git a/src/nxt_runtime.c b/src/nxt_runtime.c index 8a86d38a..a30d332b 100644 --- a/src/nxt_runtime.c +++ b/src/nxt_runtime.c @@ -839,6 +839,21 @@ nxt_runtime_conf_init(nxt_task_t *task, nxt_runtime_t *rt) slash = "/"; } + ret = nxt_file_name_create(rt->mem_pool, &file_name, "%s%sversion%Z", + rt->state, slash); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ERROR; + } + + rt->ver = (char *) file_name.start; + + ret = nxt_file_name_create(rt->mem_pool, &file_name, "%s.tmp%Z", rt->ver); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ERROR; + } + + rt->ver_tmp = (char *) file_name.start; + ret = nxt_file_name_create(rt->mem_pool, &file_name, "%s%sconf.json%Z", rt->state, slash); if (nxt_slow_path(ret != NXT_OK)) { diff --git a/src/nxt_runtime.h b/src/nxt_runtime.h index 0fb8c9a1..2037fc5d 100644 --- a/src/nxt_runtime.h +++ b/src/nxt_runtime.h @@ -65,6 +65,8 @@ struct nxt_runtime_s { const char *log; const char *modules; const char *state; + const char *ver; + const char *ver_tmp; const char *conf; const char *conf_tmp; const char *control; -- cgit