diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4da5d26b80a267cd486a46d0d29d9692395fd2f2..558922685e374e3a4219f35c3439820b37ca762e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,6 +25,7 @@ lua_source(lua_sources lua/uuid.lua) lua_source(lua_sources lua/session.lua) lua_source(lua_sources lua/msgpackffi.lua) lua_source(lua_sources lua/interactive.lua) +lua_source(lua_sources lua/load_cfg.lua) file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/third_party/luafun) lua_source(lua_sources ../third_party/luafun/fun.lua) set(bin_sources) @@ -78,6 +79,7 @@ set (common_sources scramble.c tbuf.c opts.c + cfg.cc cpu_feature.c fiob.c ffisyms.cc @@ -106,7 +108,7 @@ set_source_files_compile_flags(${common_sources}) add_library(core STATIC ${common_sources}) add_dependencies(core generate_headers) -set (common_libraries cfg core small salad) +set (common_libraries core small salad) list(APPEND common_libraries ${LIBEV_LIBRARIES} @@ -160,22 +162,7 @@ set(TARANTOOL_CXX_FLAGS ${CMAKE_CXX_FLAGS} PARENT_SCOPE) function(tarantool_module mod) set (module_sources ${ARGN}) - set(cfg_c_flags "-Wno-unused -Wno-unused-parameter") - if (CMAKE_COMPILER_IS_CLANG) - set(cfg_c_flags "${cfg_c_flags} -Wno-semicolon-before-method-body") - endif() - set_source_files_properties( - ${CMAKE_SOURCE_DIR}/cfg/tarantool_${mod}_cfg.c - PROPERTIES COMPILE_FLAGS ${cfg_c_flags} - GENERATED True) - unset(cfg_c_flags) - add_executable(tarantool_${mod} - ${module_sources} - ${CMAKE_SOURCE_DIR}/cfg/tarantool_${mod}_cfg.c) - - set_source_files_properties(${recompiled_sources} - PROPERTIES OBJECT_DEPENDS - ${CMAKE_SOURCE_DIR}/cfg/tarantool_${mod}_cfg.h) + add_executable(tarantool_${mod} ${module_sources}) set_source_files_compile_flags( ${recompiled_sources} ${module_sources}) diff --git a/src/admin.cc b/src/admin.cc index ae2655433cca9c43aa05aa1adac852e3bfbc721f..130e0538218070e3c159c094cfee499ab799cb7b 100644 --- a/src/admin.cc +++ b/src/admin.cc @@ -39,6 +39,7 @@ #include "trivia/config.h" #include "trivia/util.h" #include "coio_buf.h" +#include <box/box.h> extern "C" { #include <lua.h> @@ -102,12 +103,15 @@ admin_handler(va_list ap) } void -admin_init(const char *bind_ipaddr, int admin_port) +admin_init(const char *bind_ipaddr, int admin_port, + void (*on_bind)(void *)) { if (admin_port == 0) return; static struct coio_service admin; coio_service_init(&admin, "admin", bind_ipaddr, admin_port, admin_handler, NULL); + if (on_bind) + evio_service_on_bind(&admin.evio_service, on_bind, NULL); evio_service_start(&admin.evio_service); } diff --git a/src/admin.h b/src/admin.h index 28de68c8207aa55dd0346669ee686afa7220da7e..050d7e8c20bceb163129c691f2e1d18c6c1ceeaa 100644 --- a/src/admin.h +++ b/src/admin.h @@ -28,6 +28,7 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -int admin_init(const char *bind_ipaddr, int admin_port); +int admin_init(const char *bind_ipaddr, int admin_port, + void (*on_bind)(void *)); #endif /* TARANTOOL_ADMIN_H_INCLUDED */ diff --git a/src/box/box.cc b/src/box/box.cc index c4595251944661b41c94b2b0d21230232b262233..56faea1b5627f18c7b47d41d0751d269d36acec5 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -30,11 +30,6 @@ #include <arpa/inet.h> #include <sys/wait.h> -extern "C" { -#include <cfg/warning.h> -#include <cfg/tarantool_box_cfg.h> -} /* extern "C" */ - #include <errcode.h> #include <recovery.h> #include "replica.h" @@ -57,6 +52,7 @@ extern "C" { #include "txn.h" #include "fiber.h" #include "access.h" +#include "cfg.h" static void process_replica(struct port *port, struct request *request); static void process_ro(struct port *port, struct request *request); @@ -109,7 +105,7 @@ process_replica(struct port *port, struct request *request) { if (!iproto_request_is_select(request->code)) { tnt_raise(ClientError, ER_NONMASTER, - cfg.replication_source); + cfg_gets("replication_source")); } return process_rw(port, request); } @@ -123,7 +119,8 @@ process_ro(struct port *port, struct request *request) } static int -recover_row(void *param __attribute__((unused)), struct iproto_packet *packet) +recover_row(void *param __attribute__((unused)), + struct iproto_packet *packet) { try { assert(packet->bodycnt == 1); /* always 1 for read */ @@ -142,14 +139,13 @@ recover_row(void *param __attribute__((unused)), struct iproto_packet *packet) } static void -box_enter_master_or_replica_mode(struct tarantool_cfg *conf) +box_enter_master_or_replica_mode(const char *replication_source) { - if (conf->replication_source != NULL) { + if (replication_source != NULL) { box_process = process_replica; recovery_wait_lsn(recovery_state, recovery_state->lsn); - recovery_follow_remote(recovery_state, - conf->replication_source); + recovery_follow_remote(recovery_state, replication_source); } else { box_process = process_rw; @@ -158,125 +154,148 @@ box_enter_master_or_replica_mode(struct tarantool_cfg *conf) } } +/* {{{ configuration bindings */ + void -box_leave_local_standby_mode(void *data __attribute__((unused))) +box_check_replication_source(const char *source) { - recovery_finalize(recovery_state); - - recovery_update_mode(recovery_state, cfg.wal_mode, - cfg.wal_fsync_delay); - - box_enter_master_or_replica_mode(&cfg); + if (source == NULL) + return; + /* check replication port */ + char ip_addr[32]; + int port; + if (sscanf(source, "%31[^:]:%i", ip_addr, &port) != 2) { + tnt_raise(ClientError, ER_CFG, + "replication source IP address is not recognized"); + } + if (port <= 0 || port >= USHRT_MAX) { + tnt_raise(ClientError, ER_CFG, + "invalid replication source port"); + } } -int -box_check_config(struct tarantool_cfg *conf) +static void +box_check_wal_mode(const char *mode_name) { - if (strindex(wal_mode_STRS, conf->wal_mode, - WAL_MODE_MAX) == WAL_MODE_MAX) { - out_warning(CNF_OK, "wal_mode %s is not recognized", conf->wal_mode); - return -1; - } - /* replication & hot standby modes can not work together */ - if (conf->replication_source != NULL && conf->local_hot_standby > 0) { - out_warning(CNF_OK, "replication and local hot standby modes " - "can't be enabled simultaneously"); - return -1; + int mode = strindex(wal_mode_STRS, mode_name, WAL_MODE_MAX); + if (mode == WAL_MODE_MAX) { + tnt_raise(ClientError, ER_CFG, + "wal_mode is not recognized"); } +} +static void +box_check_config() +{ + box_check_wal_mode(cfg_gets("wal_mode")); /* check replication mode */ - if (conf->replication_source != NULL) { - /* check replication port */ - char ip_addr[32]; - int port; - - if (sscanf(conf->replication_source, "%31[^:]:%i", - ip_addr, &port) != 2) { - out_warning(CNF_OK, "replication source IP address is not recognized"); - return -1; - } - if (port <= 0 || port >= USHRT_MAX) { - out_warning(CNF_OK, "invalid replication source port value: %i", port); - return -1; - } - } + box_check_replication_source(cfg_gets("replication_source")); /* check primary port */ - if (conf->primary_port != 0 && - (conf->primary_port <= 0 || conf->primary_port >= USHRT_MAX)) { - out_warning(CNF_OK, "invalid primary port value: %i", conf->primary_port); - return -1; - } + int primary_port = cfg_geti("primary_port"); + if (primary_port < 0 || primary_port >= USHRT_MAX) + tnt_raise(ClientError, ER_CFG, + "invalid primary port value"); /* check rows_per_wal configuration */ - if (conf->rows_per_wal <= 1) { - out_warning(CNF_OK, "rows_per_wal must be greater than one"); - return -1; + if (cfg_geti("rows_per_wal") <= 1) { + tnt_raise(ClientError, ER_CFG, + "rows_per_wal must be greater than one"); } - - return 0; } -int -box_reload_config(struct tarantool_cfg *old_conf, struct tarantool_cfg *new_conf) +extern "C" void +box_set_replication_source(const char *source) { - if (strcasecmp(old_conf->wal_mode, new_conf->wal_mode) != 0 || - old_conf->wal_fsync_delay != new_conf->wal_fsync_delay) { - - double new_delay = new_conf->wal_fsync_delay; - - /* Mode has changed: */ - if (strcasecmp(old_conf->wal_mode, new_conf->wal_mode)) { - if (strcasecmp(old_conf->wal_mode, "fsync") == 0 || - strcasecmp(new_conf->wal_mode, "fsync") == 0) { - out_warning(CNF_OK, "wal_mode cannot switch to/from fsync"); - return -1; - } - } + box_check_replication_source(source); + bool old_is_replica = recovery_state->remote; + bool new_is_replica = source != NULL; - /* - * Unless wal_mode=fsync_delay, wal_fsync_delay is - * irrelevant and must be 0. - */ - if (strcasecmp(new_conf->wal_mode, "fsync_delay") != 0) - new_delay = 0.0; + if (old_is_replica != new_is_replica || + (old_is_replica && + (strcmp(source, recovery_state->remote->source) != 0))) { + + if (recovery_state->finalize) { + if (recovery_state->remote) + recovery_stop_remote(recovery_state); + box_enter_master_or_replica_mode(source); + } else { + /* + * Do nothing, we're in local hot + * standby mode, the server + * will automatically begin following + * the remote when local hot standby + * mode is finished, see + * box_leave_local_hot_standby_mode() + */ + } + } +} +extern "C" void +box_set_wal_fsync_delay(double delay) +{ + recovery_update_fsync_delay(recovery_state, delay); +} - recovery_update_mode(recovery_state, new_conf->wal_mode, new_delay); +extern "C" void +box_set_wal_mode(const char *mode_name) +{ + box_check_wal_mode(mode_name); + enum wal_mode mode = (enum wal_mode) + strindex(wal_mode_STRS, mode_name, WAL_MODE_MAX); + if (mode != recovery_state->wal_mode && + (mode == WAL_FSYNC || recovery_state->wal_mode == WAL_FSYNC)) { + tnt_raise(ClientError, ER_CFG, + "wal_mode cannot switch to/from fsync"); } + recovery_update_mode(recovery_state, mode); +} - if (old_conf->snap_io_rate_limit != new_conf->snap_io_rate_limit) - recovery_update_io_rate_limit(recovery_state, new_conf->snap_io_rate_limit); - bool old_is_replica = old_conf->replication_source != NULL; - bool new_is_replica = new_conf->replication_source != NULL; +extern "C" void +box_set_log_level(int level) +{ + say_set_log_level(level); +} - if (old_is_replica != new_is_replica || - (old_is_replica && - (strcmp(old_conf->replication_source, new_conf->replication_source) != 0))) { +extern "C" void +box_set_io_collect_interval(double interval) +{ + ev_set_io_collect_interval(loop(), interval); +} - if (recovery_state->finalize != true) { - out_warning(CNF_OK, "Could not propagate %s before local recovery finished", - old_is_replica == true ? "slave to master" : - "master to slave"); +extern "C" void +box_set_snap_io_rate_limit(double limit) +{ + recovery_update_io_rate_limit(recovery_state, limit); +} - return -1; - } - if (recovery_state->remote) { - recovery_stop_remote(recovery_state); - } +extern "C" void +box_set_too_long_threshold(double threshold) +{ + too_long_threshold = threshold; +} - box_enter_master_or_replica_mode(new_conf); - } - if (old_conf->io_collect_interval != - new_conf->io_collect_interval) { +/* }}} configuration bindings */ - ev_set_io_collect_interval(loop(), - new_conf->io_collect_interval); +void +box_leave_local_standby_mode(void *data __attribute__((unused))) +{ + if (recovery_state->finalize) { + /* + * Nothing to do: this happens when the server + * binds to both ports, and one of the callbacks + * is called first. + */ + return; } - if (old_conf->too_long_threshold != new_conf->too_long_threshold) - too_long_threshold = new_conf->too_long_threshold; - return 0; + recovery_finalize(recovery_state); + + box_set_wal_mode(cfg_gets("wal_mode")); + box_set_wal_fsync_delay(cfg_getd("wal_fsync_delay")); + + box_enter_master_or_replica_mode(cfg_gets("replication_source")); } void @@ -291,7 +310,7 @@ box_free(void) } static void -box_engine_init() +engine_init() { MemtxFactory *memtx = new MemtxFactory(); engine_register(memtx); @@ -300,44 +319,76 @@ box_engine_init() void box_init() { + box_check_config(); title("loading", NULL); - replication_prefork(cfg.snap_dir, cfg.wal_dir); + + replication_prefork(cfg_gets("snap_dir"), cfg_gets("wal_dir")); stat_init(); - tuple_init(cfg.slab_alloc_arena, cfg.slab_alloc_minimal, - cfg.slab_alloc_factor); + tuple_init(cfg_getd("slab_alloc_arena"), + cfg_geti("slab_alloc_minimal"), + cfg_getd("slab_alloc_factor")); - box_engine_init(); + engine_init(); schema_init(); user_cache_init(); /* recovery initialization */ - recovery_init(cfg.snap_dir, cfg.wal_dir, - recover_row, NULL, box_snapshot_cb, cfg.rows_per_wal); - recovery_update_io_rate_limit(recovery_state, cfg.snap_io_rate_limit); - recovery_setup_panic(recovery_state, cfg.panic_on_snap_error, cfg.panic_on_wal_error); + recovery_init(cfg_gets("snap_dir"), cfg_gets("wal_dir"), + recover_row, NULL, box_snapshot_cb, + cfg_geti("rows_per_wal")); + recovery_update_io_rate_limit(recovery_state, + cfg_getd("snap_io_rate_limit")); + recovery_setup_panic(recovery_state, + cfg_geti("panic_on_snap_error"), + cfg_geti("panic_on_wal_error")); stat_base = stat_register(iproto_request_type_strs, IPROTO_DML_REQUEST_MAX); - recover_snap(recovery_state, cfg.replication_source); + recover_snap(recovery_state, cfg_gets("replication_source")); space_end_recover_snapshot(); recover_existing_wals(recovery_state); space_end_recover(); stat_cleanup(stat_base, IPROTO_DML_REQUEST_MAX); title("orphan", NULL); - if (cfg.local_hot_standby) { - say_info("starting local hot standby"); - recovery_follow_local(recovery_state, cfg.wal_dir_rescan_delay); - title("hot_standby", NULL); + recovery_follow_local(recovery_state, + cfg_getd("wal_dir_rescan_delay")); + title("hot_standby", NULL); + const char *bind_ipaddr = cfg_gets("bind_ipaddr"); + int primary_port = cfg_geti("primary_port"); + int admin_port = cfg_geti("admin_port"); + /* + * If neither of the ports is set, become a master right + * away (e.g. this is interactive mode or other + * application server configuration). + */ + if (primary_port == 0 && admin_port == 0) + box_leave_local_standby_mode(NULL); + else { + void (*on_bind)(void *) = NULL; + if (primary_port) { + iproto_init(bind_ipaddr, primary_port, + cfg_geti("readahead")); + } else { + /* + * If no prmary port is given, leave local + * host standby mode as soon as bound to the + * admin port. Otherwise, wait till we're + * bound to the master port. + */ + on_bind = box_leave_local_standby_mode; + } + if (admin_port) + admin_init(bind_ipaddr, admin_port, on_bind); + } + if (cfg_getd("io_collect_interval") > 0) { + ev_set_io_collect_interval(loop(), + cfg_getd("io_collect_interval")); } - iproto_init(cfg.bind_ipaddr, cfg.primary_port, cfg.readahead); - admin_init(cfg.bind_ipaddr, cfg.admin_port); - if (cfg.io_collect_interval > 0) - ev_set_io_collect_interval(loop(), cfg.io_collect_interval); - too_long_threshold = cfg.too_long_threshold; + too_long_threshold = cfg_getd("too_long_threshold"); } static void diff --git a/src/box/box.h b/src/box/box.h index 49fdc7fea2e4ceff761fa188bc10b8c6009676f7..a4b1c374478d3be194297a79a111b34c4f856ac7 100644 --- a/src/box/box.h +++ b/src/box/box.h @@ -45,7 +45,6 @@ struct tbuf; struct port; struct fio_batch; struct log_io; -struct tarantool_cfg; struct lua_State; /** To be called at program start. */ @@ -65,19 +64,6 @@ typedef void (*box_process_func)(struct port *port, struct request *request); extern box_process_func box_process; /** For read-only port. */ -/* - * Check storage-layer related options in the - * configuration file. - */ -int -box_check_config(struct tarantool_cfg *conf); -/* - * Take into effect storage-layer related - * changes in the server configuration. - */ -int -box_reload_config(struct tarantool_cfg *old_conf, struct tarantool_cfg *new_conf); - /** Non zero if snapshot is in progress. */ extern int snapshot_pid; /** Incremented with each next snapshot. */ @@ -106,6 +92,18 @@ const char *box_status(void); void box_leave_local_standby_mode(void *data __attribute__((unused))); +void +box_set_wal_fsync_delay(double delay); + +void +box_set_replication_source(const char *source); + +void box_set_wal_mode(const char *mode); +void box_set_log_level(int level); +void box_set_io_collect_interval(double interval); +void box_set_snap_io_rate_limit(double limit); +void box_set_too_long_threshold(double threshold); + #if defined(__cplusplus) } #endif /* defined(__cplusplus) */ diff --git a/src/box/lua/box.lua b/src/box/lua/box.lua index b95156ad3bb2021a038ac3f2cf35691b9e4cbb69..33344e49ac6dddc34d5545448e2b2517009e9824 100644 --- a/src/box/lua/box.lua +++ b/src/box/lua/box.lua @@ -8,10 +8,6 @@ function box.dostring(s, ...) return chunk(...) end --- User can redefine the hook -function box.on_reload_configuration() -end - require("bit") -- vim: set et ts=4 sts diff --git a/src/cfg.cc b/src/cfg.cc new file mode 100644 index 0000000000000000000000000000000000000000..25a5f10f250622cf6f8ecd240cf6f62491929810 --- /dev/null +++ b/src/cfg.cc @@ -0,0 +1,78 @@ +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "cfg.h" +#include "lua/utils.h" + +enum { MAX_OPT_NAME_LEN = 256, MAX_OPT_VAL_LEN = 256, MAX_STR_OPTS = 8 }; + +static void +cfg_get(const char *param) +{ + char buf[MAX_OPT_NAME_LEN]; + snprintf(buf, sizeof(buf), "return box.cfg.%s", param); + luaL_dostring(tarantool_L, buf); +} + +int +cfg_geti(const char *param) +{ + cfg_get(param); + int val = lua_tointeger(tarantool_L, -1); + lua_pop(tarantool_L, 1); + return val; +} + +const char * +cfg_gets(const char *param) +{ + /* Support simultaneous cfg_gets("str1") and cfg_gets("str2") */ + static char __thread values[MAX_STR_OPTS][MAX_OPT_VAL_LEN]; + static int __thread i = 0; + struct lua_State *L = tarantool_L; + char *val; + cfg_get(param); + if (lua_isnil(L, -1)) + val = NULL; + else { + val = values[i++ % MAX_STR_OPTS]; + snprintf(val, MAX_OPT_VAL_LEN, "%s", lua_tostring(L, -1)); + } + lua_pop(L, 1); + return val; +} + +double +cfg_getd(const char *param) +{ + cfg_get(param); + double val = lua_tonumber(tarantool_L, -1); + lua_pop(tarantool_L, 1); + return val; +} + diff --git a/src/cfg.h b/src/cfg.h new file mode 100644 index 0000000000000000000000000000000000000000..7bdefc022367aa471bc0ea2fe118b05b88fefff7 --- /dev/null +++ b/src/cfg.h @@ -0,0 +1,39 @@ +#ifndef INCLUDES_TARANTOOL_CFG_H +#define INCLUDES_TARANTOOL_CFG_H +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +int +cfg_geti(const char *param); + +const char * +cfg_gets(const char *param); + +double +cfg_getd(const char *param); +#endif /* INCLUDES_TARANTOOL_CFG_H */ diff --git a/src/errcode.c b/src/errcode.c index ed4faeb0d2222327c19d244a4317e2c7df0ceb0d..9cc3615e73f1922f02b5001eecc4e24bdd0d496a 100644 --- a/src/errcode.c +++ b/src/errcode.c @@ -1,4 +1,32 @@ #include "errcode.h" +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ #define ERRCODE_RECORD_MEMBER(s, f, d) { \ .errstr = #s, \ diff --git a/src/errcode.h b/src/errcode.h index 0063ca966637b40fc66427aa1c69fcbd3b9a3be7..41476d99f71be24b1cf0fadc37ed805c2d3d19be 100644 --- a/src/errcode.h +++ b/src/errcode.h @@ -107,6 +107,8 @@ enum { TNT_ERRMSG_MAX = 512 }; /* 55 */_(ER_SPACE_ACCESS_DENIED, 2, "%s access denied for user '%s' to space '%s'") \ /* 56 */_(ER_USER_MAX, 2, "A limit on the total number of users has been reached: %u") \ /* 57 */_(ER_NO_SUCH_ENGINE, 2, "Space engine '%s' does not exist") \ + /* 57 */_(ER_RELOAD_CFG, 2, "Can't set option '%s' dynamically") \ + /* 57 */_(ER_CFG, 2, "Incorrect option value: %s") \ /* diff --git a/src/ffisyms.cc b/src/ffisyms.cc index b82e23bd4a7d8cf14f3c841300501444f8aa143b..f6a0ba52181e73daf7430cb131af4704ac7d4190 100644 --- a/src/ffisyms.cc +++ b/src/ffisyms.cc @@ -1,11 +1,14 @@ #include <bit/bit.h> #include <lib/msgpuck/msgpuck.h> #include "scramble.h" +#include <box/box.h> #include <box/tuple.h> #include <box/lua/index.h> #include <box/lua/call.h> -#include <readline/readline.h> #include <lua/init.h> +#include <tarantool.h> +#include <stdio.h> +#include <readline/readline.h> /* * A special hack to cc/ld to keep symbols in an optimized binary. @@ -29,5 +32,13 @@ void *ffi_symbols[] = { (void *) boxffi_select, (void *) password_prepare, (void *) readline, - (void *) tarantool_lua_interactive + (void *) tarantool_lua_interactive, + (void *) load_cfg, + (void *) box_set_wal_fsync_delay, + (void *) box_set_replication_source, + (void *) box_set_wal_mode, + (void *) box_set_log_level, + (void *) box_set_io_collect_interval, + (void *) box_set_snap_io_rate_limit, + (void *) box_set_too_long_threshold, }; diff --git a/src/log_io.cc b/src/log_io.cc index 7fff98fd78e82c0c5f10068d48febadf91600957..475ec3c83b85f03d222eef237b3afd191efd7246 100644 --- a/src/log_io.cc +++ b/src/log_io.cc @@ -321,7 +321,9 @@ log_io_cursor_close(struct log_io_cursor *i) * Seek back to last known good offset. */ fseeko(l->f, i->good_offset, SEEK_SET); +#if 0 region_free(&fiber()->gc); +#endif } /** @@ -343,12 +345,14 @@ log_io_cursor_next(struct log_io_cursor *i, struct iproto_packet *packet) say_debug("log_io_cursor_next: marker:0x%016X/%zu", row_marker, sizeof(row_marker)); +#if 0 /* * Don't let gc pool grow too much. Yet to * it before reading the next row, to make * sure it's not freed along here. */ region_free_after(&fiber()->gc, 128 * 1024); +#endif restart: if (marker_offset > 0) diff --git a/src/lua/info.cc b/src/lua/info.cc index 75acc67e9db37ce4570eb7ef8f28c9d088689dce..e4e4599a0175bcb7c39e407860579f06f00f24bf 100644 --- a/src/lua/info.cc +++ b/src/lua/info.cc @@ -90,6 +90,14 @@ lbox_info_snapshot_pid(struct lua_State *L) return 1; } +static int +lbox_info_logger_pid(struct lua_State *L) +{ + lua_pushnumber(L, logger_pid); + return 1; +} + + static const struct luaL_reg lbox_info_dynamic_meta [] = { @@ -99,6 +107,7 @@ lbox_info_dynamic_meta [] = {"status", lbox_info_status}, {"uptime", lbox_info_uptime}, {"snapshot_pid", lbox_info_snapshot_pid}, + {"logger_pid", lbox_info_logger_pid}, {NULL, NULL} }; @@ -133,16 +142,6 @@ lbox_info_init_static_values(struct lua_State *L) lua_pushnumber(L, getpid()); lua_settable(L, -3); - /* logger_pid */ - lua_pushstring(L, "logger_pid"); - lua_pushnumber(L, logger_pid); - lua_settable(L, -3); - - /* config */ - lua_pushstring(L, "config"); - lua_pushstring(L, cfg_filename_fullpath); - lua_settable(L, -3); - /* build */ lua_pushstring(L, "build"); lua_newtable(L); diff --git a/src/lua/init.cc b/src/lua/init.cc index 853061e659beebbf5b49ee4383fa432b1f7b83ee..e2a8076cdbf0918b1a4088bedad196e932866c91 100644 --- a/src/lua/init.cc +++ b/src/lua/init.cc @@ -58,19 +58,15 @@ extern "C" { #include <ctype.h> #include "small/region.h" - -extern "C" { -#include <cfg/tarantool_box_cfg.h> -#include <cfg/warning.h> -} /* extern "C" */ +#include <readline/history.h> struct lua_State *tarantool_L; /* contents of src/lua/ files */ extern char uuid_lua[], session_lua[], msgpackffi_lua[], fun_lua[], - interactive_lua[]; -static const char *lua_sources[] = { uuid_lua, session_lua, interactive_lua, - NULL }; + load_cfg_lua[], interactive_lua[]; +static const char *lua_sources[] = { uuid_lua, session_lua, + load_cfg_lua, interactive_lua, NULL }; static const char *lua_modules[] = { "msgpackffi", msgpackffi_lua, "fun", fun_lua, NULL }; /* @@ -424,6 +420,8 @@ tarantool_lua(struct lua_State *L, } } +char *history = NULL; + extern "C" void tarantool_lua_interactive(char *line) { @@ -433,124 +431,8 @@ tarantool_lua_interactive(char *line) lua_pop(tarantool_L, 1); printf("%.*s", out->size, out->data); fiber_gc(); -} - -/** - * Check if the given literal is a number/boolean or string - * literal. A string literal needs quotes. - */ -static bool -is_string(const char *str) -{ - if (strcmp(str, "true") == 0 || strcmp(str, "false") == 0) - return false; - if (! isdigit(*str)) - return true; - char *endptr; - double r = strtod(str, &endptr); - /* -Wunused-result warning suppression */ - (void) r; - return *endptr != '\0'; -} - -static int -lbox_cfg_reload(struct lua_State *L) -{ - if (reload_cfg()) - luaL_error(L, cfg_log); - lua_pushstring(L, "ok"); - return 1; -} - -/** - * Make a new configuration available in Lua. - * We could perhaps make Lua bindings to access the C - * structure in question, but for now it's easier and just - * as functional to convert the given configuration to a Lua - * table and export the table into Lua. - */ -void -tarantool_lua_load_cfg(struct tarantool_cfg *cfg) -{ - struct lua_State *L = tarantool_L; - luaL_Buffer b; - char *key, *value; - - luaL_buffinit(L, &b); - tarantool_cfg_iterator_t *i = tarantool_cfg_iterator_init(); - luaL_addstring(&b, - "box.cfg = {}\n" - "setmetatable(box.cfg, {})\n" - "getmetatable(box.cfg).__index = " - "function(table, index)\n" - " table[index] = {}\n" - " setmetatable(table[index], getmetatable(table))\n" - " return rawget(table, index)\n" - "end\n" - "getmetatable(box.cfg).__call = " - "function(table, index)\n" - " local t = {}\n" - " for i, v in pairs(table) do\n" - " if type(v) ~= 'function' then\n" - " t[i] = v\n" - " end\n" - " end\n" - " return t\n" - "end\n"); - while ((key = tarantool_cfg_iterator_next(i, cfg, &value)) != NULL) { - if (value == NULL) - continue; - const char *quote = is_string(value) ? "'" : ""; - if (strchr(key, '.') == NULL) { - lua_pushfstring(L, "box.cfg.%s = %s%s%s\n", - key, quote, value, quote); - luaL_addvalue(&b); - } - free(value); - } - luaL_pushresult(&b); - if (luaL_loadstring(L, lua_tostring(L, -1)) != 0 || - lua_pcall(L, 0, 0, 0) != 0) { - panic("%s", lua_tostring(L, -1)); - } - lua_pop(L, 1); - - /* add box.cfg.reload() function */ - lua_getfield(L, LUA_GLOBALSINDEX, "box"); - lua_pushstring(L, "cfg"); - lua_gettable(L, -2); - lua_pushstring(L, "reload"); - lua_pushcfunction(L, lbox_cfg_reload); - lua_settable(L, -3); - lua_pop(L, 2); - - /* make box.cfg read-only */ - luaL_buffinit(L, &b); - luaL_addstring(&b, - "getmetatable(box.cfg).__newindex = " - "function(table, index)\n" - " error('Attempt to modify a read-only table')\n" - "end\n" - "getmetatable(box.cfg).__index = nil\n"); - luaL_pushresult(&b); - if (luaL_loadstring(L, lua_tostring(L, -1)) != 0 || - lua_pcall(L, 0, 0, 0) != 0) { - panic("%s", lua_tostring(L, -1)); - } - lua_pop(L, 1); - - /* - * Invoke a user-defined on_reload_configuration hook, - * if it exists. Do it after everything else is done. - */ - lua_getfield(L, LUA_GLOBALSINDEX, "box"); - lua_pushstring(L, "on_reload_configuration"); - lua_gettable(L, -2); - if (lua_isfunction(L, -1) && lua_pcall(L, 0, 0, 0) != 0) { - say_error("on_reload_configuration() hook failed: %s", - lua_tostring(L, -1)); - } - lua_pop(L, 1); /* cleanup stack */ + if (history) + add_history(line); } /** @@ -575,6 +457,7 @@ run_script(va_list ap) lua_getglobal(L, "dofile"); lua_pushstring(L, path); } else { + say_crit("version %s", tarantool_version()); lua_getglobal(L, "interactive"); } lbox_pcall(L); diff --git a/src/lua/init.h b/src/lua/init.h index 34d2fb3b7091c13cafb213096d415b9794596b63..34529787d9da67d68d553a4ea5681b8896ebdb53 100644 --- a/src/lua/init.h +++ b/src/lua/init.h @@ -33,7 +33,6 @@ struct lua_State; struct luaL_Reg; -struct tarantool_cfg; struct tbuf; /** @@ -69,12 +68,6 @@ tarantool_lua_free(); const char * tarantool_lua_tostring(struct lua_State *L, int index); -/** - * Make a new configuration available in Lua - */ -void -tarantool_lua_load_cfg(struct tarantool_cfg *cfg); - /** * Load and execute start-up file * @@ -87,6 +80,7 @@ void tarantool_lua(struct lua_State *L, struct tbuf *out, const char *str); +extern char *history; /** * Eval line and print output. */ diff --git a/src/lua/interactive.lua b/src/lua/interactive.lua index 5cf219356b2a612aa3599ee9a8a375e6b553c8b0..3ca5a37e050fe0dced42a4ea7ba35568fe34a66b 100644 --- a/src/lua/interactive.lua +++ b/src/lua/interactive.lua @@ -1,3 +1,5 @@ +-- interctive.lua -- internal file +-- local ffi = require('ffi') ffi.cdef([[ char *readline(const char *prompt); @@ -8,11 +10,12 @@ ffi.cdef([[ function interactive() while true do line = ffi.C.readline("tarantool> ") - if line then - ffi.C.tarantool_lua_interactive(line) - ffi.C.free(line) - else - break; + if line == nil then + return end + ffi.C.tarantool_lua_interactive(line) + ffi.C.free(line) end end + +jit.off(interactive) diff --git a/src/lua/load_cfg.lua b/src/lua/load_cfg.lua new file mode 100644 index 0000000000000000000000000000000000000000..b9d17f6b53f289396ebf2fa3a5f43176cb5fc2d9 --- /dev/null +++ b/src/lua/load_cfg.lua @@ -0,0 +1,96 @@ +-- load_cfg.lua - internal file + +local ffi = require('ffi') +ffi.cdef([[ +void load_cfg(); +void box_set_wal_mode(const char *mode); +void box_set_wal_fsync_delay(double); +void box_set_replication_source(const char *source); +void box_set_log_level(int level); +void box_set_io_collect_interval(double interval); +void box_set_too_long_threshold(double threshold); +void box_set_snap_io_rate_limit(double limit); +]]) + +-- all available options +local default_cfg = { + admin_port = nil, + primary_port = nil, + bind_ipaddr = "INADDR_ANY", + slab_alloc_arena = 1.0, + slab_alloc_minimal = 64, + slab_alloc_factor = 2.0, + work_dir = nil, + snap_dir = ".", + wal_dir = ".", + logger = nil, + logger_nonblock = true, + log_level = 5, + io_collect_interval = nil, + readahead = 16320, + snap_io_rate_limit = nil, + too_long_threshold = 0.5, + wal_mode = "write", + rows_per_wal = 500000, + wal_dir_rescan_delay= 0.1, + panic_on_snap_error = true, + panic_on_wal_error = false, + replication_source = nil, + custom_proc_title = nil, + pid_file = nil, + background = false, + username = nil , + coredump = false, +} + +-- dynamically settable options +local dynamic_cfg = { + wal_mode = ffi.C.box_set_wal_mode, + wal_fsync_delay = ffi.C.box_set_wal_fsync_delay, + replication_source = ffi.C.box_set_replication_source, + log_level = ffi.C.box_set_log_level, + io_collect_interval = ffi.C.box_set_io_collect_interval, + too_long_threshold = ffi.C.box_set_too_long_threshold, + snap_io_rate_limit = ffi.C.box_set_snap_io_rate_limit, +} + +local function reload_cfg(oldcfg, newcfg) + if newcfg == nil then + newcfg = {} + end + for key, val in pairs(newcfg) do + if dynamic_cfg[key] == nil then + box.raise(box.error.ER_RELOAD_CFG, + "Can't set option '"..key.."' dynamically"); + end + if val == "" then + val = nil + end + dynamic_cfg[key](val) + rawset(oldcfg, key, val) + end + if type(box.on_reload_configuration) == 'function' then + box.on_reload_configuration() + end +end + +function box.cfg(cfg) + if cfg == nil then + cfg = {} + end + for k,v in pairs(default_cfg) do + if cfg[k] == nil then + cfg[k] = v + end + end + box.cfg = setmetatable(cfg, + { + __newindex = function(table, index) + error('Attempt to modify a read-only table') + end, + __call = reload_cfg + }) + ffi.C.load_cfg() +end +jit.off(box.cfg) +jit.off(reload_cfg) diff --git a/src/recovery.cc b/src/recovery.cc index 0efbc2e7308c7655674d3510d52210c66f40a39b..08342a2068607fe93ef4cfd90bfb5da50e6483ac 100644 --- a/src/recovery.cc +++ b/src/recovery.cc @@ -215,7 +215,8 @@ recovery_init(const char *snap_dirname, const char *wal_dirname, assert(recovery_state == NULL); recovery_state = (struct recovery_state *) calloc(1, sizeof(struct recovery_state)); struct recovery_state *r = recovery_state; - recovery_update_mode(r, "none", 0); + recovery_update_mode(r, WAL_NONE); + recovery_update_fsync_delay(r, 0); assert(rows_per_wal > 1); @@ -236,18 +237,22 @@ recovery_init(const char *snap_dirname, const char *wal_dirname, } void -recovery_update_mode(struct recovery_state *r, - const char *mode, double fsync_delay) +recovery_update_mode(struct recovery_state *r, enum wal_mode mode) +{ + assert(mode < WAL_MODE_MAX); + r->wal_mode = mode; +} + +void +recovery_update_fsync_delay(struct recovery_state *r, double new_delay) { - r->wal_mode = (enum wal_mode) strindex(wal_mode_STRS, mode, WAL_MODE_MAX); - assert(r->wal_mode != WAL_MODE_MAX); /* No mutex lock: let's not bother with whether * or not a WAL writer thread is present, and * if it's present, the delay will be propagated * to it whenever there is a next lock/unlock of * wal_writer->mutex. */ - r->wal_fsync_delay = fsync_delay; + r->wal_fsync_delay = new_delay; } void @@ -560,7 +565,9 @@ recover_remaining_wals(struct recovery_state *r) result = -1; } +#if 0 region_free(&fiber()->gc); +#endif return result; } @@ -584,7 +591,10 @@ recover_existing_wals(struct recovery_state *r) panic("recover failed"); say_info("WALs recovered, confirmed lsn: %" PRIi64, r->confirmed_lsn); out: +#if 0 region_free(&fiber()->gc); +#endif + ; } void diff --git a/src/recovery.h b/src/recovery.h index 2d1eac753a1b24bfd6159328b5dec0a7f611841a..dc343d47a9c9e509a1ef64f649de7b66011e15ff 100644 --- a/src/recovery.h +++ b/src/recovery.h @@ -105,8 +105,8 @@ extern struct recovery_state *recovery_state; void recovery_init(const char *snap_dirname, const char *xlog_dirname, row_handler row_handler, void *row_handler_param, snapshot_handler snapshot_handler, int rows_per_wal); -void recovery_update_mode(struct recovery_state *r, - const char *wal_mode, double fsync_delay); +void recovery_update_mode(struct recovery_state *r, enum wal_mode mode); +void recovery_update_fsync_delay(struct recovery_state *r, double new_delay); void recovery_update_io_rate_limit(struct recovery_state *r, double new_limit); void recovery_free(); diff --git a/src/say.c b/src/say.c index 09f1ccc6446283d58191a6ba78a933e2f98ca4cd..b59d8244f7eb183b02ea0ca9b1ed3f324694b59b 100644 --- a/src/say.c +++ b/src/say.c @@ -84,14 +84,20 @@ say_init(const char *argv0) } void -say_logger_init(char *logger, int *level, int nonblock) +say_set_log_level(int new_level) { - log_level = level; + *log_level = new_level; +} + +void +say_logger_init(const char *logger, int level, int nonblock) +{ + *log_level = level; int pipefd[2]; pid_t pid; char cmd[] = { "/bin/sh" }; char args[] = { "-c" }; - char *argv[] = { cmd, args, logger, NULL }; + char *argv[] = { cmd, args, (char *) logger, NULL }; char *envp[] = { NULL }; setvbuf(stderr, NULL, _IONBF, 0); diff --git a/src/say.h b/src/say.h index f55546fcf59e36aabb8aa6e641f9be529ef23109..15c3f2d495f342322e90723129fafdcffa8cb2ac 100644 --- a/src/say.h +++ b/src/say.h @@ -51,11 +51,14 @@ enum say_level { extern int sayfd; extern pid_t logger_pid; +void +say_set_log_level(int new_level); + /** Basic init. */ void say_init(const char *argv0); /* Move logging to a separate process. */ -void say_logger_init(char *logger, int *log_level, int nonblock); +void say_logger_init(const char *logger, int log_level, int nonblock); void vsay(int level, const char *filename, int line, const char *error, const char *format, va_list ap) diff --git a/src/tarantool.cc b/src/tarantool.cc index 4e85176ecd2b72efe992b54e9d49ca2ae084e36b..9edf77929932c2921c4bfc60fd122280621ba859 100644 --- a/src/tarantool.cc +++ b/src/tarantool.cc @@ -54,27 +54,23 @@ #include <stat.h> #include <limits.h> #include "trivia/util.h" -extern "C" { -#include <cfg/warning.h> -#include <cfg/tarantool_box_cfg.h> -#include <third_party/gopt/gopt.h> -} /* extern "C" */ #include "tt_pthread.h" #include "lua/init.h" #include "session.h" #include "box/box.h" #include "scoped_guard.h" #include "random.h" +#include <third_party/gopt/gopt.h> +#include "cfg.h" +#include <readline/history.h> -static pid_t master_pid; -const char *cfg_filename = NULL; -char *cfg_filename_fullpath = NULL; +static pid_t master_pid = getpid(); char *script = NULL; +char *pid_file = NULL; char *custom_proc_title; char status[64] = "unknown"; char **main_argv; int main_argc; -struct tarantool_cfg cfg; /** Signals handled after start as part of the event loop. */ static ev_signal ev_sigs[4]; static const int ev_sig_count = sizeof(ev_sigs)/sizeof(*ev_sigs); @@ -110,7 +106,7 @@ title(const char *role, const char *fmt, ...) bufptr += snprintf(bufptr, bufend - bufptr, "%s", s); } - int ports[] = { cfg.primary_port, cfg.admin_port }; + int ports[] = { cfg_geti("primary_port"), cfg_geti("admin_port") }; int *pptr = ports; const char *names[] = { "pri", "adm", NULL }; const char **nptr = names; @@ -123,132 +119,6 @@ title(const char *role, const char *fmt, ...) set_proc_title(buf); } -static int -load_cfg(struct tarantool_cfg *conf, int32_t check_rdonly) -{ - if (cfg_filename_fullpath != NULL) { - - FILE *f; - int32_t n_accepted, n_skipped, n_ignored; - - rewind(cfg_out); - - f = fopen(cfg_filename_fullpath, "r"); - - if (f == NULL) { - out_warning(CNF_OK, "can't open config `%s'", cfg_filename); - return -1; - } - - int syntax = parse_cfg_file_tarantool_cfg(conf, f, check_rdonly, - &n_accepted, - &n_skipped, - &n_ignored); - fclose(f); - - if (syntax != 0) - return -1; - if (n_accepted == 0) { - out_warning(CNF_OK, "empty configuration file '%s'", cfg_filename); - return -1; - } - if (n_skipped != 0) - return -1; - } - - if (check_cfg_tarantool_cfg(conf) != 0) - return -1; - - return box_check_config(conf); -} - -int -reload_cfg() -{ - static struct mutex *mutex = NULL; - struct tarantool_cfg new_cfg, aux_cfg; - - rewind(cfg_out); - - if (mutex == NULL) { - mutex = (struct mutex *) malloc(sizeof(*mutex)); - mutex_create(mutex); - } - - if (mutex_trylock(mutex) == true) { - out_warning(CNF_OK, "Could not reload configuration: it is being reloaded right now"); - return -1; - } - - - auto scoped_guard = make_scoped_guard([&] { - destroy_tarantool_cfg(&aux_cfg); - destroy_tarantool_cfg(&new_cfg); - - mutex_unlock(mutex); - }); - - init_tarantool_cfg(&new_cfg); - init_tarantool_cfg(&aux_cfg); - - /* - Prepare a copy of the original config file - for confetti, so that it can compare the new - file with the old one when loading the new file. - Load the new file and return an error if it - contains a different value for some read-only - parameter. - */ - if (dup_tarantool_cfg(&aux_cfg, &cfg) != 0 || - load_cfg(&aux_cfg, 1) != 0) - return -1; - /* - Load the new configuration file, but - skip the check for read only parameters. - new_cfg contains only defaults and - new settings. - */ - if (fill_default_tarantool_cfg(&new_cfg) != 0 || - load_cfg(&new_cfg, 0) != 0) - return -1; - - /* Check that no default value has been changed. */ - char *diff = cmp_tarantool_cfg(&aux_cfg, &new_cfg, 1); - if (diff != NULL) { - out_warning(CNF_OK, "Could not accept read only '%s' option", diff); - return -1; - } - - /* Now pass the config to the module, to take action. */ - if (box_reload_config(&cfg, &new_cfg) != 0) - return -1; - - /* All OK, activate the config. */ - swap_tarantool_cfg(&cfg, &new_cfg); - tarantool_lua_load_cfg(&cfg); - - return 0; -} - -/** Print the configuration file in YAML format. */ -void -show_cfg(struct tbuf *out) -{ - tarantool_cfg_iterator_t *i; - char *key, *value; - - tbuf_printf(out, "configuration:" CRLF); - i = tarantool_cfg_iterator_init(); - while ((key = tarantool_cfg_iterator_next(i, &cfg, &value)) != NULL) { - if (value) { - tbuf_printf(out, " - %s: \"%s\"" CRLF, key, value); - free(value); - } else { - tbuf_printf(out, " - %s: (null)" CRLF, key); - } - } -} - const char * tarantool_version(void) { @@ -359,8 +229,8 @@ sig_term_cb(int signo) { psignal(signo, ""); /* unlink pidfile. */ - if (cfg.pid_file != NULL) - unlink(cfg.pid_file); + if (pid_file != NULL) + unlink(pid_file); _exit(EXIT_SUCCESS); } @@ -452,10 +322,13 @@ create_pid(void) char buf[16] = { 0 }; pid_t pid; - if (cfg.pid_file == NULL) + pid_file = (char *) cfg_gets("pid_file"); + if (pid_file == NULL) return; - f = fopen(cfg.pid_file, "a+"); + pid_file = strdup(pid_file); + + f = fopen(pid_file, "a+"); if (f == NULL) panic_syserror("can't open pid file"); /* @@ -475,7 +348,7 @@ create_pid(void) if (fseeko(f, 0, SEEK_SET) != 0) panic_syserror("can't fseek to the beginning of pid file"); if (ftruncate(fileno(f), 0) == -1) - panic_syserror("ftruncate(`%s')", cfg.pid_file); + panic_syserror("ftruncate(`%s')", pid_file); } master_pid = getpid(); @@ -513,6 +386,90 @@ background() exit(EXIT_FAILURE); } +extern "C" void +load_cfg() +{ + const char *work_dir = cfg_gets("work_dir"); + if (work_dir != NULL && chdir(work_dir) == -1) + say_syserror("can't chdir to `%s'", work_dir); + + const char *username = cfg_gets("username"); + if (username != NULL) { + if (getuid() == 0 || geteuid() == 0) { + struct passwd *pw; + errno = 0; + if ((pw = getpwnam(username)) == 0) { + if (errno) { + say_syserror("getpwnam: %s", + username); + } else { + say_error("User not found: %s", + username); + } + exit(EX_NOUSER); + } + if (setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0 || seteuid(pw->pw_uid)) { + say_syserror("setgid/setuid"); + exit(EX_OSERR); + } + } else { + say_error("can't switch to %s: i'm not root", + username); + } + } + + if (cfg_geti("coredump")) { + struct rlimit c = { 0, 0 }; + if (getrlimit(RLIMIT_CORE, &c) < 0) { + say_syserror("getrlimit"); + exit(EX_OSERR); + } + c.rlim_cur = c.rlim_max; + if (setrlimit(RLIMIT_CORE, &c) < 0) { + say_syserror("setrlimit"); + exit(EX_OSERR); + } +#if defined(TARGET_OS_LINUX) && defined(HAVE_PRCTL_H) + if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { + say_syserror("prctl"); + exit(EX_OSERR); + } +#endif + } + + if (cfg_geti("background")) { + if (cfg_gets("logger") == NULL) { + say_crit("'background' requires 'logger' configuration option to be set"); + exit(EXIT_FAILURE); + } + if (cfg_gets("pid_file") == NULL) { + say_crit("'background' requires 'pid_file' configuration option to be set"); + exit(EXIT_FAILURE); + } + background(); + } else { + create_pid(); + } + + const char *proc_title = cfg_gets("custom_proc_title"); + /* init process title - used for logging */ + if (proc_title == NULL) { + custom_proc_title = (char *) malloc(1); + custom_proc_title[0] = '\0'; + } else { + custom_proc_title = (char *) malloc(strlen(proc_title) + 2); + strcpy(custom_proc_title, "@"); + strcat(custom_proc_title, proc_title); + } + say_logger_init(cfg_gets("logger"), + cfg_geti("log_level"), + cfg_geti("logger_nonblock")); + + say_crit("version %s", tarantool_version()); + say_crit("log level %i", cfg_geti("log_level")); + box_init(); +} + void tarantool_free(void) { @@ -525,14 +482,18 @@ tarantool_free(void) if (script) free(script); - if (cfg_filename_fullpath) - free(cfg_filename_fullpath); + else if (history) { + write_history(history); + clear_history(); + free(history); + } free_proc_title(main_argc, main_argv); /* unlink pidfile. */ - if (cfg.pid_file != NULL) - unlink(cfg.pid_file); - destroy_tarantool_cfg(&cfg); + if (pid_file != NULL) { + unlink(pid_file); + free(pid_file); + } session_free(); fiber_free(); @@ -543,11 +504,6 @@ tarantool_free(void) #ifdef HAVE_BFD symbols_free(); #endif - if (cfg_out) { - fclose(cfg_out); - free(cfg_log); - } - /* A hack for cc/ld, see ffisyms.c */ if (time(NULL) == 0) { /* never executed */ @@ -616,6 +572,13 @@ main(int argc, char **argv) argv++; argc--; script = abspath(argv[0]); + } else if (isatty(STDIN_FILENO)) { + /* load history file */ + char *home = getenv("HOME"); + history = (char *) malloc(PATH_MAX); + snprintf(history, PATH_MAX, "%s/%s", home, + ".tarantool_history"); + read_history(history); } random_init(); @@ -628,98 +591,6 @@ main(int argc, char **argv) main_argc = argc; main_argv = argv; - /* - * if config is not specified trying ./tarantool.cfg then - * /etc/tarantool.cfg - */ - if (cfg_filename == NULL) { - if (access(DEFAULT_CFG_FILENAME, F_OK) == 0) - cfg_filename = DEFAULT_CFG_FILENAME; - else if (access(DEFAULT_CFG, F_OK) == 0) - cfg_filename = DEFAULT_CFG; - } - if (cfg_filename != NULL) - cfg_filename_fullpath = abspath(cfg_filename); - - cfg_out = open_memstream(&cfg_log, &cfg_logsize); - - if (fill_default_tarantool_cfg(&cfg) != 0 || load_cfg(&cfg, 0) != 0) { - panic("can't load config:%.*s", (int) cfg_logsize, cfg_log); - } - - if (cfg.work_dir != NULL && chdir(cfg.work_dir) == -1) - say_syserror("can't chdir to `%s'", cfg.work_dir); - - if (cfg.username != NULL) { - if (getuid() == 0 || geteuid() == 0) { - struct passwd *pw; - errno = 0; - if ((pw = getpwnam(cfg.username)) == 0) { - if (errno) { - say_syserror("getpwnam: %s", - cfg.username); - } else { - say_error("User not found: %s", - cfg.username); - } - exit(EX_NOUSER); - } - if (setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0 || seteuid(pw->pw_uid)) { - say_syserror("setgit/setuid"); - exit(EX_OSERR); - } - } else { - say_error("can't switch to %s: i'm not root", cfg.username); - } - } - - if (cfg.coredump) { - struct rlimit c = { 0, 0 }; - if (getrlimit(RLIMIT_CORE, &c) < 0) { - say_syserror("getrlimit"); - exit(EX_OSERR); - } - c.rlim_cur = c.rlim_max; - if (setrlimit(RLIMIT_CORE, &c) < 0) { - say_syserror("setrlimit"); - exit(EX_OSERR); - } -#if defined(TARGET_OS_LINUX) && defined(HAVE_PRCTL_H) - if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { - say_syserror("prctl"); - exit(EX_OSERR); - } -#endif - } - - if (cfg.background) { - if (cfg.logger == NULL) { - say_crit("'background' requires 'logger' configuration option to be set"); - exit(EXIT_FAILURE); - } - if (cfg.pid_file == NULL) { - say_crit("'background' requires 'pid_file' configuration option to be set"); - exit(EXIT_FAILURE); - } - background(); - } else { - create_pid(); - } - - /* init process title - used for logging */ - if (cfg.custom_proc_title == NULL) { - custom_proc_title = (char *) malloc(1); - custom_proc_title[0] = '\0'; - } else { - custom_proc_title = (char *) malloc(strlen(cfg.custom_proc_title) + 2); - strcpy(custom_proc_title, "@"); - strcat(custom_proc_title, cfg.custom_proc_title); - } - say_logger_init(cfg.logger, &cfg.log_level, cfg.logger_nonblock); - - say_crit("version %s", tarantool_version()); - say_crit("log level %i", cfg.log_level); - /* main core cleanup routine */ atexit(tarantool_free); @@ -731,9 +602,7 @@ main(int argc, char **argv) bool start_loop = false; try { - tarantool_lua_load_cfg(&cfg); int events = ev_activecnt(loop()); - box_init(); /* * Load user init script. The script should have access * to Tarantool Lua API (box.cfg, box.fiber, etc...) that diff --git a/src/tarantool.h b/src/tarantool.h index 29e194cfaebcc12fc13dff646d1ce060e7d550e5..2f15880f9f8b95491e7b1dc36e9f308aa883678c 100644 --- a/src/tarantool.h +++ b/src/tarantool.h @@ -35,15 +35,10 @@ extern "C" { #endif /* defined(__cplusplus) */ -struct tarantool_cfg; struct tbuf; -extern struct tarantool_cfg cfg; -extern char *cfg_filename_fullpath; extern char *custom_proc_title; -int reload_cfg(); extern char status[]; -void show_cfg(struct tbuf *out); const char *tarantool_version(void); /** * Get version (defined in PACKAGE_VERSION), packed into uint32_t @@ -57,6 +52,12 @@ double tarantool_uptime(void); void __attribute__((format (printf, 2, 3))) title(const char *role, const char *fmt, ...); +void +load_cfg(); + +void +reload_cfg(); + #if defined(__cplusplus) } /* extern "C" */ #endif /* defined(__cplusplus) */ diff --git a/test/big/big.lua b/test/big/big.lua index 6151ffcb34e85b4c5db8bde2cdbac49f002dc56f..5321dd281a94917a41108284ca1c629c01bb07cd 100644 --- a/test/big/big.lua +++ b/test/big/big.lua @@ -1 +1,9 @@ #!/usr/bin/env tarantool_box + +box.cfg{ + primary_port = os.getenv("PRIMARY_PORT"), + admin_port = os.getenv("ADMIN_PORT"), + slab_alloc_arena = 0.1, + pid_file = "tarantool.pid", + rows_per_wal = 50 +} diff --git a/test/big/suite.ini b/test/big/suite.ini index 8d369714a4520c8bd1ecfb9ae5ba9f190b888175..7992fca36e7a24b7271513a6ce6b15a672a31c7a 100644 --- a/test/big/suite.ini +++ b/test/big/suite.ini @@ -1,6 +1,5 @@ [default] core = tarantool script = big.lua -config = tarantool.cfg description = lua big tests lua_libs = lua/utils.lua lua/bitset.lua lua/index_random_test.lua lua/push.lua diff --git a/test/box/admin.result b/test/box/admin.result index d6b50efc763a34fd134bffc2b3fd00cae3a310af..ff9063f99d78994b0042ec57745da5f262eb8632 100644 --- a/test/box/admin.result +++ b/test/box/admin.result @@ -43,32 +43,27 @@ help() - box.cfg.reload() - box.coredump() ... -box.cfg() +box.cfg --- -- io_collect_interval: 0 - pid_file: box.pid +- pid_file: tarantool.pid slab_alloc_factor: 2 slab_alloc_minimal: 64 admin_port: <number> - logger: cat - >> tarantool.log - readahead: 16320 - wal_dir: . - logger_nonblock: true + primary_port: <number> log_level: 5 + logger_nonblock: true snap_dir: . coredump: false - background: false too_long_threshold: 0.5 + wal_mode: write rows_per_wal: 50 - wal_mode: fsync_delay - snap_io_rate_limit: 0 panic_on_snap_error: true panic_on_wal_error: false - local_hot_standby: false - slab_alloc_arena: 0.1 + wal_dir: . + readahead: 16320 bind_ipaddr: INADDR_ANY - wal_fsync_delay: 0 - primary_port: <number> + slab_alloc_arena: 0.1 + background: false wal_dir_rescan_delay: 0.1 ... box.stat() @@ -115,7 +110,7 @@ function test_box_info() local tmp = box.info() local num = {'pid', 'snapshot_pid', 'recovery_last_update', 'recovery_lag', 'uptime', 'logger_pid'} local buildstr = {'flags', 'target', 'compiler', 'options'} - local str = {'version', 'status', 'config'} + local str = {'version', 'status' } local failed = {} if check_type(tmp.lsn, 'cdata') == false then table.insert(failed1, 'box.info().lsn') diff --git a/test/box/admin.test.lua b/test/box/admin.test.lua index 673fd3b7465375fbf35d1bb5fd5814501444185b..3b1a1f2e8496b54549b2553e21acec8ffe612116 100644 --- a/test/box/admin.test.lua +++ b/test/box/admin.test.lua @@ -8,7 +8,7 @@ space:create_index('primary', { type = 'hash' }) --# push filter 'admin_port: .*' to 'admin_port: <number>' box.stat() help() -box.cfg() +box.cfg box.stat() space:insert{1, 'tuple'} box.snapshot() @@ -24,7 +24,7 @@ function test_box_info() local tmp = box.info() local num = {'pid', 'snapshot_pid', 'recovery_last_update', 'recovery_lag', 'uptime', 'logger_pid'} local buildstr = {'flags', 'target', 'compiler', 'options'} - local str = {'version', 'status', 'config'} + local str = {'version', 'status' } local failed = {} if check_type(tmp.lsn, 'cdata') == false then table.insert(failed1, 'box.info().lsn') diff --git a/test/box/bad_trigger.result b/test/box/bad_trigger.result index a7421fe612757e89b68d77ff8a3286d03f4325cf..2ae7f426758f61def7b044d299cb046a30066afe 100644 --- a/test/box/bad_trigger.result +++ b/test/box/bad_trigger.result @@ -15,8 +15,6 @@ select * from t0 where k0=0 errcode: ER_PROC_LUA errmsg: [string "function f1() nosuchfunction() end"]:1: attempt to call global 'nosuchfunction' (a nil value) ... -Connection is alive. - box.session.on_connect(nil, f1) --- ... diff --git a/test/box/bad_trigger.test.py b/test/box/bad_trigger.test.py index 2083ac3f8cdfa8046c7a44aba60e9c18f3b90c93..835f38a408a6356b1d8ee2de9e828895e07ece41 100644 --- a/test/box/bad_trigger.test.py +++ b/test/box/bad_trigger.test.py @@ -6,13 +6,9 @@ print """ # """ -admin("function f1() nosuchfunction() end") -admin("box.session.on_connect(f1)") -try: - con1 = BoxConnection('localhost', sql.port) - con1("select * from t0 where k0=0") - print "Connection is alive.\n" -except NetworkError as e: - print "Connection is dead: {0}.\n".format(e.message) +server.admin("function f1() nosuchfunction() end") +server.admin("box.session.on_connect(f1)") +con1 = BoxConnection('localhost', server.sql.port) +con1("select * from t0 where k0=0") # Clean-up -admin("box.session.on_connect(nil, f1)") +server.admin("box.session.on_connect(nil, f1)") diff --git a/test/box/box.lua b/test/box/box.lua index 6151ffcb34e85b4c5db8bde2cdbac49f002dc56f..710e3bf2ffd3c0587982b548c5eb65407ee0b4cd 100644 --- a/test/box/box.lua +++ b/test/box/box.lua @@ -1 +1,10 @@ #!/usr/bin/env tarantool_box +os = require('os') + +box.cfg{ + primary_port = os.getenv("PRIMARY_PORT"), + admin_port = os.getenv("ADMIN_PORT"), + slab_alloc_arena = 0.1, + pid_file = "tarantool.pid", + rows_per_wal = 50 +} diff --git a/test/box/cfg.result b/test/box/cfg.result index 9416c699de18c76345766804166b29edf2801185..2bcdbc2daa626f04cac0ea5d1b5c601bcbb7e65f 100644 --- a/test/box/cfg.result +++ b/test/box/cfg.result @@ -2,73 +2,62 @@ --# push filter 'admin_port: .*' to 'admin_port: <number>' box.cfg.nosuchoption = 1 --- -- error: '[string "getmetatable(box.cfg).__newindex = function(t..."]:2: Attempt to - modify a read-only table' +- error: '[string "-- load_cfg.lua - internal file..."]:89: Attempt to modify a read-only + table' ... t = {} for k,v in pairs(box.cfg) do if type(v) ~= 'table' and type(v) ~= 'function' then table.insert(t, k..': '..tostring(v)) end end --- ... t --- -- - 'io_collect_interval: 0' - - 'pid_file: box.pid' +- - 'pid_file: tarantool.pid' - 'slab_alloc_factor: 2' - 'slab_alloc_minimal: 64' - 'admin_port: <number> - - 'logger: cat - >> tarantool.log' - - 'readahead: 16320' + - 'primary_port: <number> - 'log_level: 5' - - 'rows_per_wal: 50' - 'logger_nonblock: true' - - 'too_long_threshold: 0.5' - 'snap_dir: .' - 'coredump: false' - - 'primary_port: <number> + - 'too_long_threshold: 0.5' + - 'wal_mode: write' + - 'rows_per_wal: 50' + - 'panic_on_snap_error: true' - 'panic_on_wal_error: false' - 'wal_dir: .' - - 'wal_mode: fsync_delay' - - 'slab_alloc_arena: 0.1' - - 'panic_on_snap_error: true' - - 'local_hot_standby: false' - - 'snap_io_rate_limit: 0' + - 'readahead: 16320' - 'bind_ipaddr: INADDR_ANY' - - 'wal_fsync_delay: 0' + - 'slab_alloc_arena: 0.1' - 'background: false' - 'wal_dir_rescan_delay: 0.1' ... -- must be read-only -box.cfg.reload() +box.cfg() --- -- ok ... t = {} for k,v in pairs(box.cfg) do if type(v) ~= 'table' and type(v) ~= 'function' then table.insert(t, k..': '..tostring(v)) end end --- ... t --- -- - 'io_collect_interval: 0' - - 'pid_file: box.pid' +- - 'pid_file: tarantool.pid' - 'slab_alloc_factor: 2' - 'slab_alloc_minimal: 64' - 'admin_port: <number> - - 'logger: cat - >> tarantool.log' - - 'readahead: 16320' + - 'primary_port: <number> - 'log_level: 5' - - 'rows_per_wal: 50' - 'logger_nonblock: true' - - 'too_long_threshold: 0.5' - 'snap_dir: .' - 'coredump: false' - - 'primary_port: <number> + - 'too_long_threshold: 0.5' + - 'wal_mode: write' + - 'rows_per_wal: 50' + - 'panic_on_snap_error: true' - 'panic_on_wal_error: false' - 'wal_dir: .' - - 'wal_mode: fsync_delay' - - 'slab_alloc_arena: 0.1' - - 'panic_on_snap_error: true' - - 'local_hot_standby: false' - - 'snap_io_rate_limit: 0' + - 'readahead: 16320' - 'bind_ipaddr: INADDR_ANY' - - 'wal_fsync_delay: 0' + - 'slab_alloc_arena: 0.1' - 'background: false' - 'wal_dir_rescan_delay: 0.1' ... diff --git a/test/box/cfg.test.lua b/test/box/cfg.test.lua index c6631f4df824919cc787f4c9de377548ed2468e6..ccacd0ee6228323619fbeff792ec6bb777c1c5df 100644 --- a/test/box/cfg.test.lua +++ b/test/box/cfg.test.lua @@ -4,7 +4,7 @@ box.cfg.nosuchoption = 1 t = {} for k,v in pairs(box.cfg) do if type(v) ~= 'table' and type(v) ~= 'function' then table.insert(t, k..': '..tostring(v)) end end t -- must be read-only -box.cfg.reload() +box.cfg() t = {} for k,v in pairs(box.cfg) do if type(v) ~= 'table' and type(v) ~= 'function' then table.insert(t, k..': '..tostring(v)) end end t --# clear filter diff --git a/test/box/fiber.result b/test/box/fiber.result index caffa03bf09e890e1ad13f44354e416419f4140a..2a338bffeed1fddce7ac0fff9405dd6190419522 100644 --- a/test/box/fiber.result +++ b/test/box/fiber.result @@ -167,10 +167,6 @@ space:delete{1936941424} --- - [1936941424, 'new', 1684234849] ... -box.cfg.reload() ---- -- ok -... -- must be read-only space:insert{1953719668} --- diff --git a/test/box/fiber.test.lua b/test/box/fiber.test.lua index ab9cb4ebcf7a8602c405bdbb47b9a3e5941523d2..ad7806e500ddd7b36df7463e6441abee102adbd3 100644 --- a/test/box/fiber.test.lua +++ b/test/box/fiber.test.lua @@ -48,7 +48,6 @@ space:update(1936941424, {{'-', 2, 1}}) space:update(1936941424, {{'-', 2, 1}}) space:update(1936941424, {{'+', 2, 1}}) space:delete{1936941424} -box.cfg.reload() -- must be read-only space:insert{1953719668} diff --git a/test/box/info.result b/test/box/info.result index c4ae9d5ee3fe2eca06ee8c6f6b6d0b645f3e874e..f998b0f30d8e07d00f28dbe82b5d9d5947b6a73c 100644 --- a/test/box/info.result +++ b/test/box/info.result @@ -20,7 +20,7 @@ string.match(box.info.pid, '^[1-9][0-9]*$') ~= nil --- - true ... -string.match(box.info.logger_pid, '^[1-9][0-9]*$') ~= nil +string.match(box.info.logger_pid, '^[0-9]+$') ~= nil --- - true ... @@ -40,10 +40,6 @@ box.info.status --- - primary ... -string.len(box.info.config) > 0 ---- -- true -... string.len(box.info.build.target) > 0 --- - true @@ -80,7 +76,6 @@ table.sort(t) t --- - - build - - config - logger_pid - lsn - pid diff --git a/test/box/info.test.lua b/test/box/info.test.lua index c02a627564f792bd362bc0c6212fba521f4a0551..716e7bd1c6e140e68007f8ae39f5babffccb2c2b 100644 --- a/test/box/info.test.lua +++ b/test/box/info.test.lua @@ -5,12 +5,11 @@ box.info[23] box.info['unknown_variable'] string.match(box.info.version, '^[1-9]') ~= nil string.match(box.info.pid, '^[1-9][0-9]*$') ~= nil -string.match(box.info.logger_pid, '^[1-9][0-9]*$') ~= nil +string.match(box.info.logger_pid, '^[0-9]+$') ~= nil box.info.lsn > 0 box.info.recovery_lag box.info.recovery_last_update box.info.status -string.len(box.info.config) > 0 string.len(box.info.build.target) > 0 string.len(box.info.build.compiler) > 0 string.len(box.info.build.flags) > 0 diff --git a/test/box/lua/require_init.lua b/test/box/lua/require_init.lua index b32a392a0932790d67103d04c68edc51b929764a..e7152bef72d00ee83d018703a0387d493cf38ff9 100644 --- a/test/box/lua/require_init.lua +++ b/test/box/lua/require_init.lua @@ -1,4 +1,5 @@ #!/usr/bin/env tarantool_box +box.load_cfg() mod = require("require_mod") package_path = package.path package_cpath = package.cpath diff --git a/test/box/lua/test_init.lua b/test/box/lua/test_init.lua index 6919a633af3290fdc1baf3199a6479a9900758f5..02900967a053427ede559fe2a518c234ebca081d 100644 --- a/test/box/lua/test_init.lua +++ b/test/box/lua/test_init.lua @@ -1,4 +1,5 @@ #!/usr/bin/env tarantool_box +box.load_cfg() -- testing start-up script floor = require("math").floor diff --git a/test/box/misc.result b/test/box/misc.result index 93806232d54deabc0e39c1f2424249373cef2d02..c67e1939055ab2f237077e577bb2672908c11636 100644 --- a/test/box/misc.result +++ b/test/box/misc.result @@ -33,7 +33,6 @@ t - info - ipc - net - - on_reload_configuration - pack - process - raise @@ -199,6 +198,8 @@ t; - 'box.error.ER_CREATE_SPACE : 9' - 'box.error.ER_TUPLE_FORMAT_LIMIT : 16' - 'box.error.ER_FIELD_TYPE : 23' + - 'box.error.ER_CFG : 59' + - 'box.error.ER_UNKNOWN_SCHEMA_OBJECT : 49' - 'box.error.ER_OK : 0' - 'box.error.ER_NO_SUCH_ENGINE : 57' - 'box.error.ER_TUPLE_NOT_FOUND : 4' @@ -216,7 +217,7 @@ t; - 'box.error.ER_INVALID_MSGPACK : 20' - 'box.error.ER_SPACE_ACCESS_DENIED : 55' - 'box.error.ER_KEY_PART_COUNT : 31' - - 'box.error.ER_UNKNOWN_SCHEMA_OBJECT : 49' + - 'box.error.ER_RELOAD_CFG : 58' - 'box.error.ER_USER_EXISTS : 46' - 'box.error.ER_MEMORY_ISSUE : 2' - 'box.error.ER_ILLEGAL_PARAMS : 1' diff --git a/test/box/reconfigure.result b/test/box/reconfigure.result index 935ccdcce078a3a185140e48a95f21c9209bccd9..17d1412ebaef603869400ed0cccc5da9ed9e068c 100644 --- a/test/box/reconfigure.result +++ b/test/box/reconfigure.result @@ -2,85 +2,37 @@ box.cfg.too_long_threshold --- - 0.5 ... -box.cfg.reload() ---- -- error: 'Could not accept read only ''slab_alloc_arena'' option. - - Could not accept read only ''primary_port'' option. - - Could not accept read only ''admin_port'' option. - - Could not accept read only ''rows_per_wal'' option. - - Could not accept read only ''pid_file'' option. - - Could not accept read only ''logger'' option. - - empty configuration file ''tarantool.cfg''. - -' -... -box.cfg.too_long_threshold ---- -- 0.5 -... -box.cfg.reload() +-- good +box.cfg{too_long_threshold=0.2} --- -- ok ... box.cfg.too_long_threshold --- -- 2 +- 0.2 ... -box.cfg.snap_io_rate_limit ---- -- 10 -... -box.cfg.io_collect_interval +-- good +box.cfg{snap_io_rate_limit=10} --- -- 0.01 -... -box.cfg.reload() ---- -- error: 'empty configuration file ''tarantool.cfg''. - -' -... -box.cfg.too_long_threshold ---- -- 2 ... box.cfg.snap_io_rate_limit --- - 10 ... -box.cfg.reload() ---- -- ok -... -box.cfg.snap_io_rate_limit ---- -- 1 -... -box.cfg.reload() +box.cfg.io_collect_interval --- -- error: 'can''t open config `tarantool.cfg''. - -' +- null ... -box.cfg.reload() +box.cfg{io_collect_interval=0.001} --- -- ok ... -box.cfg.too_long_threshold +box.cfg.io_collect_interval --- -- 0.5 +- 0.001 ... -# -# A test case for http://bugs.launchpad.net/bugs/712447: -# Valgrind reports use of not initialized memory after 'reload -# configuration' -# +-- A test case for http://bugs.launchpad.net/bugs/712447: +-- Valgrind reports use of not initialized memory after 'reload +-- configuration' +-- space = box.schema.create_space('tweedledum', { id = 0 }) --- ... @@ -95,11 +47,8 @@ box.snapshot() --- - ok ... -box.cfg.reload() +box.cfg{} --- -- error: 'can''t open config `tarantool.cfg''. - -' ... space:insert{2, 'tuple2'} --- @@ -109,10 +58,6 @@ box.snapshot() --- - ok ... -box.cfg.reload() ---- -- ok -... space:insert{3, 'tuple3'} --- - [3, 'tuple3'] @@ -121,24 +66,48 @@ box.snapshot() --- - ok ... -# -# A test case for https://github.com/tarantool/tarantool/issues/112: -# Tarantool crashes with SIGSEGV during reload configuration -# -box.cfg.reload() +-- A test case for https://github.com/tarantool/tarantool/issues/112: +-- Tarantool crashes with SIGSEGV during reload configuration +-- +-- log level +box.cfg{log_level=5} --- -- ok ... -box.cfg.reload() +-- constants +box.cfg{custom_proc_title="custom proc title"} --- -- error: 'Could not accept read only ''custom_proc_title'' option. - -' +- error: Can't set option 'custom_proc_title' dynamically ... -box.cfg.reload() +box.cfg{wal_dir="dynamic"} --- -- ok +- error: Can't set option 'wal_dir' dynamically +... +box.cfg{snap_dir="dynamic"} +--- +- error: Can't set option 'snap_dir' dynamically +... +box.cfg{logger="new logger"} +--- +- error: Can't set option 'logger' dynamically +... +-- bad1 +box.cfg{slab_alloc_arena=0.2} +--- +- error: Can't set option 'slab_alloc_arena' dynamically +... +box.cfg.slab_alloc_arena +--- +- 0.1 ... space:drop() --- ... +box.cfg{snap_io_rate_limit=0} +--- +... +box.cfg{io_collect_interval=0} +--- +... +box.cfg{too_long_threshold=0.5} +--- +... diff --git a/test/box/reconfigure.test.lua b/test/box/reconfigure.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..236b5de8688a3d397e04d0a6de91fa0792778453 --- /dev/null +++ b/test/box/reconfigure.test.lua @@ -0,0 +1,44 @@ +box.cfg.too_long_threshold +-- good +box.cfg{too_long_threshold=0.2} +box.cfg.too_long_threshold +-- good +box.cfg{snap_io_rate_limit=10} +box.cfg.snap_io_rate_limit +box.cfg.io_collect_interval +box.cfg{io_collect_interval=0.001} +box.cfg.io_collect_interval + +-- A test case for http://bugs.launchpad.net/bugs/712447: +-- Valgrind reports use of not initialized memory after 'reload +-- configuration' +-- +space = box.schema.create_space('tweedledum', { id = 0 }) +space:create_index('primary', { type = 'hash'}) +space:insert{1, 'tuple'} +box.snapshot() +box.cfg{} + +space:insert{2, 'tuple2'} +box.snapshot() +space:insert{3, 'tuple3'} +box.snapshot() + +-- A test case for https://github.com/tarantool/tarantool/issues/112: +-- Tarantool crashes with SIGSEGV during reload configuration +-- +-- log level +box.cfg{log_level=5} +-- constants +box.cfg{custom_proc_title="custom proc title"} +box.cfg{wal_dir="dynamic"} +box.cfg{snap_dir="dynamic"} +box.cfg{logger="new logger"} +-- bad1 +box.cfg{slab_alloc_arena=0.2} +box.cfg.slab_alloc_arena + +space:drop() +box.cfg{snap_io_rate_limit=0} +box.cfg{io_collect_interval=0} +box.cfg{too_long_threshold=0.5} diff --git a/test/box/reconfigure.test.py b/test/box/reconfigure.test.py deleted file mode 100644 index e20aac1bea1c8351c794959ca5e1436e08185662..0000000000000000000000000000000000000000 --- a/test/box/reconfigure.test.py +++ /dev/null @@ -1,55 +0,0 @@ -# encoding: utf-8 -# -admin("box.cfg.too_long_threshold") -# bad1 -server.reconfigure("box/tarantool_bad1.cfg", override=['']) -admin("box.cfg.too_long_threshold") -# good -server.reconfigure("box/tarantool_good.cfg") -admin("box.cfg.too_long_threshold") -admin("box.cfg.snap_io_rate_limit") -admin("box.cfg.io_collect_interval") -# empty -server.reconfigure("box/tarantool_empty.cfg") -admin("box.cfg.too_long_threshold") -admin("box.cfg.snap_io_rate_limit") -server.reconfigure("box/snap_io_rate_limit.cfg") -admin("box.cfg.snap_io_rate_limit") - -# no config -server.reconfigure(None) - -# cleanup -# restore default -server.reconfigure(self.suite_ini["config"]) -admin("box.cfg.too_long_threshold") - -print """# -# A test case for http://bugs.launchpad.net/bugs/712447: -# Valgrind reports use of not initialized memory after 'reload -# configuration' -#""" -admin("space = box.schema.create_space('tweedledum', { id = 0 })") -admin("space:create_index('primary', { type = 'hash'})") -admin("space:insert{1, 'tuple'}") -admin("") -admin("box.snapshot()") -server.reconfigure(None) -admin("space:insert{2, 'tuple2'}") -admin("box.snapshot()") -server.reconfigure("box/tarantool_good.cfg") -admin("space:insert{3, 'tuple3'}") -admin("box.snapshot()") - -print """# -# A test case for https://github.com/tarantool/tarantool/issues/112: -# Tarantool crashes with SIGSEGV during reload configuration -#""" -server.reconfigure("box/tarantool_wo_cpt.cfg") -server.reconfigure("box/tarantool_with_cpt.cfg") - -# Cleanup -server.reconfigure(self.suite_ini["config"]) -admin("space:drop()") - -# vim: syntax=python diff --git a/test/box/suite.ini b/test/box/suite.ini index fb6121f0b0875bfd8c0ee6245afc65a2d0da4f82..0a020dd5a8378fcc73179d3a9cb019d4a808065c 100644 --- a/test/box/suite.ini +++ b/test/box/suite.ini @@ -2,8 +2,7 @@ core = tarantool description = tarantool/box, minimal configuration script = box.lua -config = tarantool.cfg -disabled = +disabled = configuration.test.py reconfigure.test.py valgrind_disabled = admin_coredump.test.lua release_disabled = errinj.test.lua errinj_index.test.lua lua_libs = lua/fiber.lua lua/fifo.lua diff --git a/test/box/xlog.test.py b/test/box/xlog.test.py index 213e04f5715d8c24d30366a37dd340b88f70bea3..db67d2d6e115b59bc131c7971cda6cc744846cfc 100644 --- a/test/box/xlog.test.py +++ b/test/box/xlog.test.py @@ -16,11 +16,11 @@ wal = os.path.join(server.vardir, "00000000000000000002.xlog") server.start() -admin("space = box.schema.create_space('tweedledum', { id = 0 })") +server.admin("space = box.schema.create_space('tweedledum', { id = 0 })") if os.access(wal_inprogress, os.F_OK): print "00000000000000000002.xlog.inprogress exists" -admin("space:create_index('primary', { type = 'hash' })") +server.admin("space:create_index('primary', { type = 'hash' })") if os.access(wal, os.F_OK) and not os.access(wal_inprogress, os.F_OK): print "00000000000000000002.xlog.inprogress has been successfully renamed" @@ -34,7 +34,7 @@ server.start() wal_inprogress = os.path.join(server.vardir, "00000000000000000004.xlog.inprogress") wal = os.path.join(server.vardir, "00000000000000000004.xlog") -admin("box.space[0]:insert{3, 'third tuple'}") +server.admin("box.space[0]:insert{3, 'third tuple'}") if os.access(wal_inprogress, os.F_OK): print "00000000000000000004.xlog.inprogress exists" diff --git a/test/lib/preprocessor.py b/test/lib/preprocessor.py index 8f445df97f38e54f5e826ed47952d1a20c7add87..bf565ab31d0d1f606f05b9f8ba53b1b85e2a7295 100644 --- a/test/lib/preprocessor.py +++ b/test/lib/preprocessor.py @@ -19,16 +19,19 @@ class LuaPreprocessorException(Exception): def __str__(self): return "lua preprocessor error: " + repr(self.value) -class State(object): - def __init__(self, suite_ini, curcon, server): +class TestState(object): + def __init__(self, suite_ini, default_server, create_server): self.delimiter = '' self.suite_ini = suite_ini - self.curcon = [curcon] - self.tarantool_server = server self.environ = Namespace() + self.create_server = create_server + self.servers = { 'default': default_server } + self.connections = { 'default': default_server.admin } + # curcon is an array since we may have many connections + self.curcon = [self.connections['default']] nmsp = Namespace() - setattr(nmsp, 'admin_port', self.suite_ini['servers']['default'].admin.port) - setattr(nmsp, 'primary_port', self.suite_ini['servers']['default'].sql.port) + setattr(nmsp, 'admin_port', default_server.admin.port) + setattr(nmsp, 'primary_port', default_server.sql.port) setattr(self.environ, 'default', nmsp) def parse_preprocessor(self, string): @@ -125,97 +128,71 @@ class State(object): def server(self, ctype, sname, opts): if ctype == 'create': - if sname in self.suite_ini['servers']: + if sname in self.servers: raise LuaPreprocessorException('Server {0} already exists'.format(repr(sname))) - temp = self.tarantool_server() - if 'configuration' in opts: - temp.cfgfile_source = opts['configuration'][1:-1] - else: - temp.cfgfile_source = self.suite_ini['config'] + temp = self.create_server() if 'need_init' in opts: temp.need_init = True if opts['need_init'] == 'True' else False if 'script' in opts: temp.script = opts['script'][1:-1] + temp.rpl_master = None if 'rpl_master' in opts: - temp.rpl_master = (self.suite_ini['servers'][opts['rpl_master']] if (not opts['rpl_master'] == 'None') else None) - elif 'hot_master' in opts: - temp.hot_master = (self.suite_ini['servers'][opts['hot_master']] if (not opts['hot_master'] == 'None') else None) + temp.rpl_master = self.servers[opts['rpl_master']] temp.vardir = os.path.join(self.suite_ini['vardir'], sname) temp.name = sname - self.suite_ini['servers'][sname] = temp - self.suite_ini['servers'][sname].deploy(silent=True) + self.servers[sname] = temp + self.servers[sname].deploy(silent=True) nmsp = Namespace() setattr(nmsp, 'admin_port', temp.admin.port) setattr(nmsp, 'primary_port', temp.sql.port) + if temp.rpl_master: + setattr(nmsp, 'master_port', temp.rpl_master.sql.port) setattr(self.environ, sname, nmsp) elif ctype == 'start': - if sname not in self.suite_ini['servers']: + if sname not in self.servers: raise LuaPreprocessorException('Can\'t start nonexistent server '+repr(sname)) - self.suite_ini['servers'][sname].start(silent=True) - self.suite_ini['connections'][sname] = [self.suite_ini['servers'][sname].admin, sname] + self.servers[sname].start(silent=True) + self.connections[sname] = self.servers[sname].admin try: - self.suite_ini['connections'][sname][0]('print(\'Started? I\'t seems to me, that yep\')', silent=True) + self.connections[sname]('return true', silent=True) except socket.error as e: LuaPreprocessorException('Can\'t start server '+repr(sname)) elif ctype == 'stop': - if sname not in self.suite_ini['servers']: + if sname not in self.servers: raise LuaPreprocessorException('Can\'t stop nonexistent server '+repr(sname)) - self.suite_ini['servers'][sname].stop() - for cname in [k for k, v in self.suite_ini['connections'].iteritems() if v[1] == 'sname']: - self.suite_ini['connections'][cname][0].disconnect() - self.suite_ini['connections'].pop(cname) + self.connections[sname].disconnect() + self.connections.pop(sname) + self.servers[sname].stop() elif ctype == 'deploy': pass - elif ctype == 'reconfigure': - if sname not in self.suite_ini['servers']: - raise LuaPreprocessorException('Can\'t reconfigure nonexistent server '+repr(sname)) - temp = self.suite_ini['servers'][sname] - if 'rpl_master' in opts: - temp.rpl_master = (self.suite_ini['servers'][opts['rpl_master']] if (not opts['rpl_master'] == 'None') else None) - elif 'hot_master' in opts: - temp.hot_master = (self.suite_ini['servers'][opts['hot_master']] if (not opts['hot_master'] == 'None') else None) - if 'configuration' in opts: - temp.reconfigure(opts['configuration'][1:-1], silent = True) - else: - temp.config = self.suite_ini['config'] - if temp.script != None: - if os.path.exists(temp.script_dst): - os.unlink(temp.script_dst) - if 'script' in opts: - temp.script = opts['script'][1:-1] - shutil.copy(temp.script, temp.script_dst) - temp.restart() - nmsp = Namespace() - setattr(nmsp, 'admin_port', temp.admin.port) - setattr(nmsp, 'primary_port', temp.sql.port) - setattr(self.environ, sname, nmsp) elif ctype == 'cleanup': - if sname not in self.suite_ini['servers']: + if sname not in self.servers: raise LuaPreprocessorException('Can\'t cleanup nonexistent server '+repr(sname)) - self.suite_ini['servers'][sname].cleanup() + self.servers[sname].cleanup() delattr(self.environ, sname) else: raise LuaPreprocessorException('Unknown command for server: '+repr(ctype)) - def connection(self, ctype, cname, sname): + def connection(self, ctype, cnames, sname): + # we always get a list of connections as input here + cname = cnames[0] if ctype == 'create': - if sname not in self.suite_ini['servers']: + if sname not in self.servers: raise LuaPreprocessorException('Can\'t create connection to nonexistent server '+repr(sname)) - if cname[0] in self.suite_ini['connections']: + if cname in self.connections: raise LuaPreprocessorException('Connection {0} already exists'.format(repr(cname))) - self.suite_ini['connections'][cname[0]] = [AdminConnection('localhost', - self.suite_ini['servers'][sname].port), sname] - self.suite_ini['connections'][cname[0]][0].connect() + self.connections[cname] = AdminConnection('localhost', self.servers[sname].admin.port) + self.connections[cname].connect() elif ctype == 'drop': - if cname[0] not in self.suite_ini['connections']: + if cname not in self.connections: raise LuaPreprocessorException('Can\'t drop nonexistent connection '+repr(cname)) - self.suite_ini['connections'][cname[0]][0].disconnect() - self.suite_ini['connections'].pop(cname[0]) + self.connections[cname].disconnect() + self.connections.pop(cname) elif ctype == 'set': - for i in cname: - if not i in self.suite_ini['connections']: + for i in cnames: + if not i in self.connections: raise LuaPreprocessorException('Can\'t set nonexistent connection '+repr(cname)) - self.curcon = [self.suite_ini['connections'][i][0] for i in cname] + self.curcon = [self.connections[i] for i in cnames] else: raise LuaPreprocessorException('Unknown command for connection: '+repr(ctype)) @@ -239,16 +216,14 @@ class State(object): string = string[3:].strip() self.parse_preprocessor(string) - def flush(self): + def cleanup(self): sys.stdout.clear_all_filters() - a = self.suite_ini['servers']['default'] - self.suite_ini['servers'].pop('default') - for k, v in self.suite_ini['servers'].iteritems(): + # don't stop the default server + self.servers.pop('default') + for k, v in self.servers.iteritems(): v.stop(silent=True) v.cleanup() - for cname in [name for name, tup in self.suite_ini['connections'].iteritems() if tup[1] == 'sname']: - self.suite_ini['connections'][cname].disconnect() - self.suite_ini['connections'].pop(cname) - self.suite_ini['servers'] = {} - self.suite_ini['servers']['default'] = a + if k in self.connections: + self.connections[k].disconnect() + self.connections.pop(k) diff --git a/test/lib/tarantool-python b/test/lib/tarantool-python index 0f9d99ecb770586ca011800a6e3921c3353c7459..3beaebe341b278804960021eea03e24a89300bce 160000 --- a/test/lib/tarantool-python +++ b/test/lib/tarantool-python @@ -1 +1 @@ -Subproject commit 0f9d99ecb770586ca011800a6e3921c3353c7459 +Subproject commit 3beaebe341b278804960021eea03e24a89300bce diff --git a/test/lib/tarantool_connection.py b/test/lib/tarantool_connection.py index 3b2235a822964defe03e3b3389b59ca130b48ded..5537db8de8958f58e6ce4b7c357929003a92b990 100644 --- a/test/lib/tarantool_connection.py +++ b/test/lib/tarantool_connection.py @@ -30,10 +30,10 @@ class TarantoolConnection(object): self.host = host self.port = port self.is_connected = False - self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.socket.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1) def connect(self): + self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.socket.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1) self.socket.connect((self.host, self.port)) self.is_connected = True @@ -44,8 +44,6 @@ class TarantoolConnection(object): def reconnect(self): self.disconnect() - self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.socket.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1) self.connect() def opt_reconnect(self): @@ -54,7 +52,8 @@ class TarantoolConnection(object): Make use of this property and detect whether or not the socket is dead. Reconnect a dead socket, do nothing if the socket is good.""" try: - if self.socket.recv(0, socket.MSG_DONTWAIT) == '': + if not self.is_connected or \ + self.socket.recv(0, socket.MSG_DONTWAIT) == '': self.reconnect() except socket.error as e: if e.errno == errno.EAGAIN: diff --git a/test/lib/tarantool_server.py b/test/lib/tarantool_server.py index 6bb41259d8872616c2dcc4efa3268c0a218c1a00..004cff8b5d9787eb5aca65f7b3144a77ac341f8d 100644 --- a/test/lib/tarantool_server.py +++ b/test/lib/tarantool_server.py @@ -25,7 +25,7 @@ except ImportError: from lib.test import Test from lib.server import Server -from lib.preprocessor import State +from lib.preprocessor import TestState from lib.box_connection import BoxConnection from lib.admin_connection import AdminConnection @@ -65,7 +65,7 @@ class FuncTest(Test): class LuaTest(FuncTest): def execute(self, server): - ts = State(self.suite_ini, server.admin, TarantoolServer) + ts = TestState(self.suite_ini, server, TarantoolServer) cmd = None def send_command(command): @@ -98,7 +98,8 @@ class LuaTest(FuncTest): sys.stdout.write(result.replace("\r\n", "\n")) cmd.close() cmd = None - ts.flush() + # stop any servers created by the test, except the default one + ts.cleanup() class PythonTest(FuncTest): @@ -106,28 +107,6 @@ class PythonTest(FuncTest): execfile(self.name, dict(locals(), **server.__dict__)) -class TarantoolConfig(object): - def __init__(self, path): - self.path = path - - def parse(self): - cfg = {} - with open(self.path, 'r') as f: - for line in f: - line = [part.strip() for part in line.split('=', 1)] - if not line or not line[0] or line[0][0] == '#': - continue - if len(line) != 2: - raise Exception("Bad cfg line: {line}. file: {file}".format(\ - line = repr(line), file = repr(self.path))) - cfg[line[0]] = line[1] - return cfg - - def generate(self, original): - with open(self.path, 'w') as f: - for el in original.iteritems(): - f.write(' = '.join(el) + '\n') - class TarantoolLog(object): def __init__(self, path): self.path = path @@ -230,17 +209,9 @@ class GdbMixin(Mixin): class TarantoolServer(Server): default_tarantool = { "bin": "tarantool_box", - "config": "tarantool.cfg", "logfile": "tarantool.log", "pidfile": "box.pid", "name": "default"} - generate_ports = [ - 'primary_port', - 'admin_port', - ] - generated_props = [ - 'replication_source' - ] #----------------------------------PROPERTIES----------------------------------# @property def debug(self): @@ -272,28 +243,6 @@ class TarantoolServer(Server): def pidfile(self, val): self._pidfile = os.path.join(self.vardir, val) - @property - def cfgfile(self): - if not hasattr(self, '_cfgfile') or not self._cfgfile: - return os.path.join(self.vardir, self.default_tarantool["config"]) - return self._cfgfile - @cfgfile.setter - def cfgfile(self, val): - self._cfgfile = os.path.join(self.vardir, val) - - @property - def cfgfile_source(self): - if not hasattr(self, '_cfgfile_source'): - raise ValueError("No config-file is specified") - return self._cfgfile_source - @cfgfile_source.setter - def cfgfile_source(self, path): - if path == None: - if hasattr(self, '_cfgfile_source'): - delattr(self, '_cfgfile_source') - return - self._cfgfile_source = os.path.abspath(path) - @property def builddir(self): if not hasattr(self, '_builddir'): @@ -340,12 +289,9 @@ class TarantoolServer(Server): int(port) except ValueError as e: raise ValueError("Bad port number: '%s'" % port) - if not hasattr(self, 'admin') or self.admin is None: - self.admin = AdminConnection('localhost', port) - return - if self.admin.port != port: - self.admin.port = port - self.admin.reconnect() + if hasattr(self, 'admin'): + del self.admin + self.admin = AdminConnection('localhost', port) @property def _sql(self): @@ -357,12 +303,9 @@ class TarantoolServer(Server): port = int(port) except ValueError as e: raise ValueError("Bad port number: '%s'" % port) - if not hasattr(self, 'sql') or self.sql is None: - self.sql = BoxConnection('localhost', port) - return - if self.sql.port != port: - self.sql.port = port - self.sql.reconnect() + if hasattr(self, 'sql'): + del self.sql + self.sql = BoxConnection('localhost', port) @property def log_des(self): @@ -385,18 +328,6 @@ class TarantoolServer(Server): ' Server class, his derivation or None') self._rpl_master = val - @property - def hot_master(self): - if not hasattr(self, '_hot_master'): self._hot_master = None - return self._hot_master - @hot_master.setter - def hot_master(self, val): - if not isinstance(self, (TarantoolServer, None)): - raise ValueError('Hot-standby master must be Tarantool' - ' Server class, his derivation or None') - self._hot_master = val - - #------------------------------------------------------------------------------# def __new__(cls, ini=None): @@ -415,33 +346,28 @@ class TarantoolServer(Server): if _ini is None: _ini = {} ini = { - 'config': None, 'core': 'tarantool', 'gdb': False, 'script': None, 'lua_libs': [], - 'random_ports': True, 'valgrind': False, 'vardir': None, 'start_and_exit': False } ini.update(_ini) Server.__init__(self, ini) - self.generated_fields = self.generate_ports + self.generated_props self.testdir = os.path.abspath(os.curdir) self.re_vardir_cleanup += [ "*.snap", "*.xlog", "*.inprogress", - "*.cfg", "*.sup", "*.lua", "*.pid"] + "*.sup", "*.lua", "*.pid"] self.name = "default" self.conf = {} self.status = None #-----InitBasicVars-----# - self.cfgfile_source = ini['config'] self.core = ini['core'] self.gdb = ini['gdb'] self.script = ini['script'] self.lua_libs = ini['lua_libs'] - self.random_ports = ini['random_ports'] self.valgrind = ini['valgrind'] self._start_and_exit = ini['start_and_exit'] @@ -479,8 +405,9 @@ class TarantoolServer(Server): self.kill_old_server() self.cleanup() self.copy_files() - self.configure() - return + port = random.randrange(3300, 9999) + self._admin = find_port(port) + self._sql = find_port(port + 1) def deploy(self, silent=True): self.install(silent) @@ -489,43 +416,6 @@ class TarantoolServer(Server): else: self.start_and_exit() - def configure(self, config=None): - self.copy_config(config) - self.port = self.conf['admin_port'] - self._sql = self.conf['primary_port'] - self._admin = self.conf['admin_port'] - - def reconfigure(self, config, silent=False, override=['all']): - if config == None: - os.unlink(self.cfgfile) - else: - self.cfgfile_source = config - self.copy_config(override=override) - self.admin.execute("box.cfg.reload()", silent=silent) - - def copy_config(self, rand=True, override = ['all']): - override_all = (True if 'all' in override else False) - - port = random.randrange(3300, 9999) - for t in self.generate_ports: - if not t in self.conf: - self.conf[t] = find_port(port) - port += 1 - if not self.hot_master is None: - self.conf['primary_port'] = self.hot_master.sql.port - if not self.rpl_master is None and 'replication_source' in self.generated_fields: - self.conf['replication_source'] = \ - '127.0.0.1:'+str(self.rpl_master.conf['primary_port']) - - - basic = TarantoolConfig(self.cfgfile_source).parse() - addit = {} - for key in self.generated_fields: - if key in basic and (override_all or key in override) and key in self.conf: - addit[key] = str(self.conf[key]) - basic.update(addit) - TarantoolConfig(self.cfgfile).generate(basic) - def copy_files(self): if self.script: shutil.copy(self.script, self.script_dst) @@ -558,8 +448,12 @@ class TarantoolServer(Server): color_stdout((os.path.basename(self.binary) if not self.script else self.script_dst) + " \n", schema='path') color_stdout(self.version() + "\n", schema='version') - check_port(self.conf['admin_port']) + check_port(self.admin.port) + os.putenv("PRIMARY_PORT", str(self.sql.port)) + os.putenv("ADMIN_PORT", str(self.admin.port)) + if self.rpl_master: + os.putenv("MASTER_PORT", str(self.rpl_master.sql.port)) args = self.prepare_args() self.logfile_pos = self.logfile self.process = subprocess.Popen(args, @@ -608,11 +502,13 @@ class TarantoolServer(Server): 2) wait until server tells us his status """ + print self.logfile_pos.log_begin + print self.logfile_pos.path - self.logfile_pos.seek_from('entering the event loop\n', self.process if not self.gdb else None) + self.logfile_pos.seek_from('entering the event loop', self.process if not self.gdb else None) while True: try: - temp = AdminConnection('localhost', self.conf['admin_port']) + temp = AdminConnection('localhost', self.admin.port) ans = yaml.load(temp.execute('box.info.status'))[0] if ans in ('primary', 'hot_standby', 'orphan') or ans.startswith('replica'): return True @@ -665,14 +561,17 @@ class TarantoolServer(Server): return False def find_tests(self, test_suite, suite_path): - def patterned(test, patterns): - return [test for i in patterns if test.name.find(i) != -1] - tests = [PythonTest(k, test_suite.args, test_suite.ini) \ for k in sorted(glob.glob(os.path.join(suite_path, "*.test.py" )))] tests += [LuaTest(k, test_suite.args, test_suite.ini) \ for k in sorted(glob.glob(os.path.join(suite_path, "*.test.lua")))] - test_suite.tests = sum(map((lambda x: patterned(x, test_suite.args.tests)), tests), []) + test_suite.tests = [] + # don't sort, command line arguments must be run in + # the specified order + for name in test_suite.args.tests: + for test in tests: + if test.name.find(name) != -1: + test_suite.tests.append(test) def get_param(self, param = None): if not param is None: diff --git a/test/lib/test_suite.py b/test/lib/test_suite.py index b9d47f400ca9be59c5e47f0debf2e51e88105e36..edce44fafb767f1418598bdb518f1a64e74bb58a 100644 --- a/test/lib/test_suite.py +++ b/test/lib/test_suite.py @@ -53,7 +53,7 @@ class TestSuite: self.ini.update(dict(config.items("default"))) self.ini.update(self.args.__dict__) - for i in ["config", "script"]: + for i in ["script"]: self.ini[i] = os.path.join(suite_path, self.ini[i]) if i in self.ini else None for i in ["disabled", "valgrind_disabled", "release_disabled"]: self.ini[i] = dict.fromkeys(self.ini[i].split()) if i in self.ini else dict() @@ -61,8 +61,6 @@ class TestSuite: self.ini[i] = map(lambda x: os.path.join(suite_path, x), dict.fromkeys(self.ini[i].split()) if i in self.ini else dict()) - for i in ["random_ports"]: - self.ini[i] = True if i not in self.ini or self.ini[i].lower() == 'true' else False try: if self.ini['core'] == 'tarantool': self.server = TarantoolServer(self.ini) @@ -88,8 +86,6 @@ class TestSuite: return [] self.server.deploy(silent=False) if self.ini['core'] != 'unittest': - self.ini['servers'] = {'default' : self.server} - self.ini['connections'] = {'default' : [self.server.admin, 'default']} self.ini['vardir'] = self.args.vardir self.ini['builddir'] = self.args.builddir diff --git a/test/lib/unittest_server.py b/test/lib/unittest_server.py index e16e783b31d4f8bd9b4220bc4148292a6ec7c14a..12d72298658e73c84610d89cb9be8d1c213dc53a 100644 --- a/test/lib/unittest_server.py +++ b/test/lib/unittest_server.py @@ -24,12 +24,10 @@ class UnittestServer(Server): if _ini is None: _ini = {} ini = { - 'config': None, 'core': 'tarantool', 'gdb': False, 'init_lua': None, 'lua_libs': [], - 'random_ports': True, 'valgrind': False, 'vardir': None }; ini.update(_ini) diff --git a/test/module/box.lua b/test/module/box.lua index 6151ffcb34e85b4c5db8bde2cdbac49f002dc56f..490c35fb63a850efdcb86a8a644b3063534cc3a1 100644 --- a/test/module/box.lua +++ b/test/module/box.lua @@ -1 +1,8 @@ #!/usr/bin/env tarantool_box +box.cfg{ + primary_port = os.getenv("PRIMARY_PORT"), + admin_port = os.getenv("ADMIN_PORT"), + slab_alloc_arena = 0.1, + pid_file = "tarantool.pid", + rows_per_wal = 50 +} diff --git a/test/module/suite.ini b/test/module/suite.ini index 6dfc89b9a5e3d37df79f81cf623fae257457ba8e..0dede8fba9a77d53803c4ed063efcad5a29fc4d9 100644 --- a/test/module/suite.ini +++ b/test/module/suite.ini @@ -1,4 +1,3 @@ [default] script = box.lua description = tarantool/box, optional lua modules -config = tarantool.cfg diff --git a/test/replication/consistent.result b/test/replication/consistent.result index 76b31cafb00bfc495382ddf8bc16dc32b78e4ef9..c2bcd55ee174d0a8fcafff8f08b1a6b8e7abac56 100644 --- a/test/replication/consistent.result +++ b/test/replication/consistent.result @@ -1,4 +1,4 @@ ---# create server replica with configuration='replication/cfg/replica.cfg', rpl_master=default, script='replication/replica.lua' +--# create server replica with rpl_master=default, script='replication/replica.lua' --# start server replica --# set connection default box.schema.user.grant('guest', 'read,write,execute', 'universe') @@ -121,7 +121,12 @@ _print_lsn() -------------------- -- Replica to Master -------------------- ---# reconfigure server replica with configuration 'replication/cfg/replica_to_master.cfg', rpl_master=None +old_replication_source = box.cfg.replication_source +--- +... +box.cfg{replication_source=""} +--- +... --# set connection default _insert(11, 20, 'master') --- @@ -181,7 +186,9 @@ _print_lsn() ------------------- -- rollback Replica ------------------- ---# reconfigure server replica with configuration='replication/cfg/replica.cfg', rpl_master=default +box.cfg{replication_source=old_replication_source} +--- +... _select(11, 20) --- - [11, 'replica - 11'] @@ -213,7 +220,9 @@ _print_lsn() -------------------- -- Replica to Master -------------------- ---# reconfigure server replica with configuration='replication/cfg/replica_to_master.cfg', rpl_master=None +box.cfg{replication_source=""} +--- +... --# set connection default _insert(21, 30, 'master') --- @@ -283,7 +292,9 @@ _print_lsn() ------------------- -- rollback Replica ------------------- ---# reconfigure server replica with configuration='replication/cfg/replica.cfg', rpl_master=default +box.cfg{replication_source=old_replication_source} +--- +... _select(21, 30) --- - [21, 'replica - 21'] @@ -315,7 +326,9 @@ _print_lsn() -------------------- -- Replica to Master -------------------- ---# reconfigure server replica with configuration='replication/cfg/replica_to_master.cfg', rpl_master=None +box.cfg{replication_source=""} +--- +... --# set connection default _insert(31, 40, 'master') --- @@ -405,7 +418,9 @@ _print_lsn() ------------------- -- rollback Replica ------------------- ---# reconfigure server replica with configuration='replication/cfg/replica.cfg', rpl_master=default +box.cfg{replication_source=old_replication_source} +--- +... _select(31, 50) --- - [31, 'replica - 31'] diff --git a/test/replication/consistent.test.lua b/test/replication/consistent.test.lua index 2653467d9cf24ab59b12e678a8b802c3c7dece75..9cd4d4efbca70e7e983b27d936923c6b0b87d54c 100644 --- a/test/replication/consistent.test.lua +++ b/test/replication/consistent.test.lua @@ -1,4 +1,4 @@ ---# create server replica with configuration='replication/cfg/replica.cfg', rpl_master=default, script='replication/replica.lua' +--# create server replica with rpl_master=default, script='replication/replica.lua' --# start server replica --# set connection default box.schema.user.grant('guest', 'read,write,execute', 'universe') @@ -64,7 +64,8 @@ _print_lsn() -------------------- -- Replica to Master -------------------- ---# reconfigure server replica with configuration 'replication/cfg/replica_to_master.cfg', rpl_master=None +old_replication_source = box.cfg.replication_source +box.cfg{replication_source=""} --# set connection default _insert(11, 20, 'master') _select(11, 20) @@ -82,7 +83,7 @@ _print_lsn() ------------------- -- rollback Replica ------------------- ---# reconfigure server replica with configuration='replication/cfg/replica.cfg', rpl_master=default +box.cfg{replication_source=old_replication_source} _select(11, 20) --# set connection default -- Master LSN: @@ -97,7 +98,7 @@ _print_lsn() -------------------- -- Replica to Master -------------------- ---# reconfigure server replica with configuration='replication/cfg/replica_to_master.cfg', rpl_master=None +box.cfg{replication_source=""} --# set connection default _insert(21, 30, 'master') _select(21, 30) @@ -115,7 +116,7 @@ _print_lsn() ------------------- -- rollback Replica ------------------- ---# reconfigure server replica with configuration='replication/cfg/replica.cfg', rpl_master=default +box.cfg{replication_source=old_replication_source} _select(21, 30) --# set connection default @@ -131,7 +132,7 @@ _print_lsn() -------------------- -- Replica to Master -------------------- ---# reconfigure server replica with configuration='replication/cfg/replica_to_master.cfg', rpl_master=None +box.cfg{replication_source=""} --# set connection default _insert(31, 40, 'master') _select(31, 40) @@ -149,7 +150,7 @@ _print_lsn() ------------------- -- rollback Replica ------------------- ---# reconfigure server replica with configuration='replication/cfg/replica.cfg', rpl_master=default +box.cfg{replication_source=old_replication_source} _select(31, 50) --# set connection default _insert(41, 60, 'master') diff --git a/test/replication/hot_standby.lua b/test/replication/hot_standby.lua new file mode 100644 index 0000000000000000000000000000000000000000..5644a48ef46c2174265a51c483b99aee735c0e33 --- /dev/null +++ b/test/replication/hot_standby.lua @@ -0,0 +1,12 @@ +#!/usr/bin/env tarantool_box +os = require('os') +box.cfg({ + primary_port = os.getenv("MASTER_PORT"), + admin_port = os.getenv("ADMIN_PORT"), + slab_alloc_arena = 0.1, + pid_file = "tarantool.pid", + logger = "cat - >> tarantool.log", + custom_proc_title = "hot_standby", + wal_dir = "..", + snap_dir = "..", +}) diff --git a/test/replication/hot_standby.result b/test/replication/hot_standby.result index 61321e5c5267a0a267cf4385401e4e9fae930460..3b3060400dd93ab85bc9bca35a3e88ac4c2e0847 100644 --- a/test/replication/hot_standby.result +++ b/test/replication/hot_standby.result @@ -1,5 +1,5 @@ ---# create server hot_standby with configuration='replication/cfg/hot_standby.cfg', hot_master=default, script='replication/master.lua' ---# create server replica with configuration='replication/cfg/replica.cfg', rpl_master=default, script='replication/replica.lua' +--# create server hot_standby with script='replication/hot_standby.lua', rpl_master=default +--# create server replica with rpl_master=default, script='replication/replica.lua' --# start server hot_standby --# start server replica --# set connection default @@ -118,7 +118,9 @@ _select(1, 10) box.fiber.sleep(0.2) --- ... ---# set variable hot_standby_port to 'hot_standby.primary_port' +-- hot_standby.primary_port is garbage, since hot_standby.lua +-- uses MASTER_PORT environment variable for its primary_port +--# set variable hot_standby_port to 'hot_standby.master_port' a = box.net.box.new('127.0.0.1', hot_standby_port) --- ... diff --git a/test/replication/hot_standby.test.lua b/test/replication/hot_standby.test.lua index b392345c2bc95492650d89a5cca064d182176024..883f2796d0216e15bf602ee180125c0a5d5ea1a9 100644 --- a/test/replication/hot_standby.test.lua +++ b/test/replication/hot_standby.test.lua @@ -1,5 +1,5 @@ ---# create server hot_standby with configuration='replication/cfg/hot_standby.cfg', hot_master=default, script='replication/master.lua' ---# create server replica with configuration='replication/cfg/replica.cfg', rpl_master=default, script='replication/replica.lua' +--# create server hot_standby with script='replication/hot_standby.lua', rpl_master=default +--# create server replica with rpl_master=default, script='replication/replica.lua' --# start server hot_standby --# start server replica --# set connection default @@ -66,7 +66,9 @@ _select(1, 10) --# stop server default box.fiber.sleep(0.2) ---# set variable hot_standby_port to 'hot_standby.primary_port' +-- hot_standby.primary_port is garbage, since hot_standby.lua +-- uses MASTER_PORT environment variable for its primary_port +--# set variable hot_standby_port to 'hot_standby.master_port' a = box.net.box.new('127.0.0.1', hot_standby_port) a:call('_set_pri_lsn', box.info.lsn) a:close() diff --git a/test/replication/init_storage.test.py b/test/replication/init_storage.test.py index 3761a757777b0c2f9fc71f241884e085a1c830df..84599a8c31a8c089862e76004c6774720caaf2e5 100644 --- a/test/replication/init_storage.test.py +++ b/test/replication/init_storage.test.py @@ -3,7 +3,6 @@ import glob from lib.tarantool_server import TarantoolServer # master server -cfgfile_backup = server.cfgfile_source master = server master.admin("space = box.schema.create_space('test', {id = 42})") @@ -19,7 +18,7 @@ print 'replica test 1 (no such space)' print '-------------------------------------------------------------' replica = TarantoolServer(server.ini) -replica.cfgfile_source = 'replication/cfg/replica.cfg' +replica.script = 'replication/replica.lua' replica.vardir = os.path.join(server.vardir, 'replica') replica.rpl_master = master replica.deploy() @@ -38,7 +37,7 @@ print 'replica test 2 (must be ok)' print '-------------------------------------------------------------' replica = TarantoolServer(server.ini) -replica.cfgfile_source = 'replication/cfg/replica.cfg' +replica.script = 'replication/replica.lua' replica.vardir = os.path.join(server.vardir, 'replica') replica.rpl_master = master replica.deploy() @@ -52,6 +51,5 @@ replica.stop() replica.cleanup(True) server.stop() -server.cfgfile_source = cfgfile_backup server.deploy() diff --git a/test/replication/master.lua b/test/replication/master.lua index 6151ffcb34e85b4c5db8bde2cdbac49f002dc56f..9ad0b5ebdd8ca0469786d6ad816005507effdf79 100644 --- a/test/replication/master.lua +++ b/test/replication/master.lua @@ -1 +1,10 @@ #!/usr/bin/env tarantool_box +os = require('os') +box.cfg({ + primary_port = os.getenv("PRIMARY_PORT"), + admin_port = os.getenv("ADMIN_PORT"), + slab_alloc_arena = 0.1, + pid_file = "tarantool.pid", + logger = "cat - >> tarantool.log", + custom_proc_title = "master", +}) diff --git a/test/replication/replica.lua b/test/replication/replica.lua index 6151ffcb34e85b4c5db8bde2cdbac49f002dc56f..6815caec4637f2b0d070d93eb3f0bb8dbd1e08c1 100644 --- a/test/replication/replica.lua +++ b/test/replication/replica.lua @@ -1 +1,10 @@ #!/usr/bin/env tarantool_box +box.cfg({ + primary_port = os.getenv("PRIMARY_PORT"), + admin_port = os.getenv("ADMIN_PORT"), + replication_source = "127.0.0.1:"..os.getenv("MASTER_PORT"), + slab_alloc_arena = 0.1, + pid_file = "tarantool.pid", + logger = "cat - >> tarantool.log", + custom_proc_title = "replica", +}) diff --git a/test/replication/suite.ini b/test/replication/suite.ini index 05da9f65d53e3c9d543d7d14b445ab3f1fa90b33..792ebe9c8090f1d94405481d532cc288c0e989f5 100644 --- a/test/replication/suite.ini +++ b/test/replication/suite.ini @@ -2,6 +2,3 @@ core = tarantool script = master.lua description = tarantool/box, replication -#disabled = -config = cfg/master.cfg -random_ports = False diff --git a/test/replication/swap.result b/test/replication/swap.result index 9112d58f8467fa9613eb66eb34ed632cc47e81da..c2db559591541886ecfb35fe6ff234eb9927ed91 100644 --- a/test/replication/swap.result +++ b/test/replication/swap.result @@ -92,14 +92,11 @@ select * from t0 where k0 = 9 - [9, 'tuple 9'] ... swap servers -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok -... -box.cfg.reload() ---- -- ok ... +switch master to replica insert into t0 values (10, 'tuple 10') --- - [10, 'tuple 10'] @@ -181,14 +178,11 @@ select * from t0 where k0 = 19 - [19, 'tuple 19'] ... rollback servers configuration -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok -... -box.cfg.reload() ---- -- ok ... +switch replica to replica test 1 iteration insert into t0 values (20, 'tuple 20') --- @@ -271,14 +265,11 @@ select * from t0 where k0 = 29 - [29, 'tuple 29'] ... swap servers -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok ... +switch master to replica insert into t0 values (30, 'tuple 30') --- - [30, 'tuple 30'] @@ -360,14 +351,11 @@ select * from t0 where k0 = 39 - [39, 'tuple 39'] ... rollback servers configuration -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok ... +switch replica to replica test 2 iteration insert into t0 values (40, 'tuple 40') --- @@ -450,14 +438,11 @@ select * from t0 where k0 = 49 - [49, 'tuple 49'] ... swap servers -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok ... +switch master to replica insert into t0 values (50, 'tuple 50') --- - [50, 'tuple 50'] @@ -539,14 +524,11 @@ select * from t0 where k0 = 59 - [59, 'tuple 59'] ... rollback servers configuration -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok -... -box.cfg.reload() ---- -- ok ... +switch replica to replica test 3 iteration insert into t0 values (60, 'tuple 60') --- @@ -629,14 +611,11 @@ select * from t0 where k0 = 69 - [69, 'tuple 69'] ... swap servers -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok -... -box.cfg.reload() ---- -- ok ... +switch master to replica insert into t0 values (70, 'tuple 70') --- - [70, 'tuple 70'] @@ -718,14 +697,11 @@ select * from t0 where k0 = 79 - [79, 'tuple 79'] ... rollback servers configuration -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok ... +switch replica to replica test 4 iteration insert into t0 values (80, 'tuple 80') --- @@ -808,14 +784,11 @@ select * from t0 where k0 = 89 - [89, 'tuple 89'] ... swap servers -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok ... +switch master to replica insert into t0 values (90, 'tuple 90') --- - [90, 'tuple 90'] @@ -897,14 +870,11 @@ select * from t0 where k0 = 99 - [99, 'tuple 99'] ... rollback servers configuration -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok ... +switch replica to replica test 5 iteration insert into t0 values (100, 'tuple 100') --- @@ -987,14 +957,11 @@ select * from t0 where k0 = 109 - [109, 'tuple 109'] ... swap servers -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok -... -box.cfg.reload() ---- -- ok ... +switch master to replica insert into t0 values (110, 'tuple 110') --- - [110, 'tuple 110'] @@ -1076,14 +1043,11 @@ select * from t0 where k0 = 119 - [119, 'tuple 119'] ... rollback servers configuration -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok -... -box.cfg.reload() ---- -- ok ... +switch replica to replica test 6 iteration insert into t0 values (120, 'tuple 120') --- @@ -1166,14 +1130,11 @@ select * from t0 where k0 = 129 - [129, 'tuple 129'] ... swap servers -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok ... +switch master to replica insert into t0 values (130, 'tuple 130') --- - [130, 'tuple 130'] @@ -1255,14 +1216,11 @@ select * from t0 where k0 = 139 - [139, 'tuple 139'] ... rollback servers configuration -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok ... +switch replica to replica test 7 iteration insert into t0 values (140, 'tuple 140') --- @@ -1345,14 +1303,11 @@ select * from t0 where k0 = 149 - [149, 'tuple 149'] ... swap servers -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok ... +switch master to replica insert into t0 values (150, 'tuple 150') --- - [150, 'tuple 150'] @@ -1434,14 +1389,11 @@ select * from t0 where k0 = 159 - [159, 'tuple 159'] ... rollback servers configuration -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok -... -box.cfg.reload() ---- -- ok ... +switch replica to replica test 8 iteration insert into t0 values (160, 'tuple 160') --- @@ -1524,14 +1476,11 @@ select * from t0 where k0 = 169 - [169, 'tuple 169'] ... swap servers -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok -... -box.cfg.reload() ---- -- ok ... +switch master to replica insert into t0 values (170, 'tuple 170') --- - [170, 'tuple 170'] @@ -1613,14 +1562,11 @@ select * from t0 where k0 = 179 - [179, 'tuple 179'] ... rollback servers configuration -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok ... +switch replica to replica test 9 iteration insert into t0 values (180, 'tuple 180') --- @@ -1703,14 +1649,11 @@ select * from t0 where k0 = 189 - [189, 'tuple 189'] ... swap servers -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok ... +switch master to replica insert into t0 values (190, 'tuple 190') --- - [190, 'tuple 190'] @@ -1792,14 +1735,11 @@ select * from t0 where k0 = 199 - [199, 'tuple 199'] ... rollback servers configuration -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok ... +switch replica to replica test 10 iteration insert into t0 values (200, 'tuple 200') --- @@ -1882,14 +1822,11 @@ select * from t0 where k0 = 209 - [209, 'tuple 209'] ... swap servers -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok -... -box.cfg.reload() ---- -- ok ... +switch master to replica insert into t0 values (210, 'tuple 210') --- - [210, 'tuple 210'] @@ -1971,14 +1908,11 @@ select * from t0 where k0 = 219 - [219, 'tuple 219'] ... rollback servers configuration -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok -... -box.cfg.reload() ---- -- ok ... +switch replica to replica test 11 iteration insert into t0 values (220, 'tuple 220') --- @@ -2061,14 +1995,11 @@ select * from t0 where k0 = 229 - [229, 'tuple 229'] ... swap servers -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok ... +switch master to replica insert into t0 values (230, 'tuple 230') --- - [230, 'tuple 230'] @@ -2150,14 +2081,11 @@ select * from t0 where k0 = 239 - [239, 'tuple 239'] ... rollback servers configuration -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok ... +switch replica to replica test 12 iteration insert into t0 values (240, 'tuple 240') --- @@ -2240,14 +2168,11 @@ select * from t0 where k0 = 249 - [249, 'tuple 249'] ... swap servers -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok ... +switch master to replica insert into t0 values (250, 'tuple 250') --- - [250, 'tuple 250'] @@ -2329,14 +2254,11 @@ select * from t0 where k0 = 259 - [259, 'tuple 259'] ... rollback servers configuration -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok -... -box.cfg.reload() ---- -- ok ... +switch replica to replica test 13 iteration insert into t0 values (260, 'tuple 260') --- @@ -2419,14 +2341,11 @@ select * from t0 where k0 = 269 - [269, 'tuple 269'] ... swap servers -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok -... -box.cfg.reload() ---- -- ok ... +switch master to replica insert into t0 values (270, 'tuple 270') --- - [270, 'tuple 270'] @@ -2508,14 +2427,11 @@ select * from t0 where k0 = 279 - [279, 'tuple 279'] ... rollback servers configuration -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok ... +switch replica to replica test 14 iteration insert into t0 values (280, 'tuple 280') --- @@ -2598,14 +2514,11 @@ select * from t0 where k0 = 289 - [289, 'tuple 289'] ... swap servers -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok ... +switch master to replica insert into t0 values (290, 'tuple 290') --- - [290, 'tuple 290'] @@ -2687,14 +2600,11 @@ select * from t0 where k0 = 299 - [299, 'tuple 299'] ... rollback servers configuration -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok ... +switch replica to replica test 15 iteration insert into t0 values (300, 'tuple 300') --- @@ -2777,14 +2687,11 @@ select * from t0 where k0 = 309 - [309, 'tuple 309'] ... swap servers -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok -... -box.cfg.reload() ---- -- ok ... +switch master to replica insert into t0 values (310, 'tuple 310') --- - [310, 'tuple 310'] @@ -2866,14 +2773,11 @@ select * from t0 where k0 = 319 - [319, 'tuple 319'] ... rollback servers configuration -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok -... -box.cfg.reload() ---- -- ok ... +switch replica to replica test 16 iteration insert into t0 values (320, 'tuple 320') --- @@ -2956,14 +2860,11 @@ select * from t0 where k0 = 329 - [329, 'tuple 329'] ... swap servers -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok ... +switch master to replica insert into t0 values (330, 'tuple 330') --- - [330, 'tuple 330'] @@ -3045,14 +2946,11 @@ select * from t0 where k0 = 339 - [339, 'tuple 339'] ... rollback servers configuration -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok ... +switch replica to replica test 17 iteration insert into t0 values (340, 'tuple 340') --- @@ -3135,14 +3033,11 @@ select * from t0 where k0 = 349 - [349, 'tuple 349'] ... swap servers -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok ... +switch master to replica insert into t0 values (350, 'tuple 350') --- - [350, 'tuple 350'] @@ -3224,14 +3119,11 @@ select * from t0 where k0 = 359 - [359, 'tuple 359'] ... rollback servers configuration -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok -... -box.cfg.reload() ---- -- ok ... +switch replica to replica test 18 iteration insert into t0 values (360, 'tuple 360') --- @@ -3314,14 +3206,11 @@ select * from t0 where k0 = 369 - [369, 'tuple 369'] ... swap servers -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok -... -box.cfg.reload() ---- -- ok ... +switch master to replica insert into t0 values (370, 'tuple 370') --- - [370, 'tuple 370'] @@ -3403,14 +3292,11 @@ select * from t0 where k0 = 379 - [379, 'tuple 379'] ... rollback servers configuration -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok ... +switch replica to replica test 19 iteration insert into t0 values (380, 'tuple 380') --- @@ -3493,14 +3379,11 @@ select * from t0 where k0 = 389 - [389, 'tuple 389'] ... swap servers -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch replica to master +box.cfg{replication_source=''} --- -- ok ... +switch master to replica insert into t0 values (390, 'tuple 390') --- - [390, 'tuple 390'] @@ -3582,11 +3465,8 @@ select * from t0 where k0 = 399 - [399, 'tuple 399'] ... rollback servers configuration -box.cfg.reload() ---- -- ok -... -box.cfg.reload() +switch master to master +box.cfg{replication_source=''} --- -- ok ... +switch replica to replica diff --git a/test/replication/swap.test.py b/test/replication/swap.test.py index 9f3ac9b546a8e7276f3932332d76fbd66e4c1d69..fa4efc728d6217d0cb82cd8cdc27fa7011a55f87 100644 --- a/test/replication/swap.test.py +++ b/test/replication/swap.test.py @@ -17,12 +17,10 @@ def select_tuples(_server, begin, end, lsn): # master server master = server -cfgfile_bkp = server.cfgfile_source # replica server replica = TarantoolServer() replica.script = "replication/replica.lua" replica.rpl_master = master -replica.cfgfile_source = "replication/cfg/replica.cfg" replica.vardir = os.path.join(server.vardir, 'replica') replica.deploy() @@ -49,10 +47,12 @@ for i in range(REPEAT): print "swap servers" # reconfigure replica to master replica.rpl_master = None - replica.reconfigure("replication/cfg/replica_to_master.cfg", silent = False) + print("switch replica to master") + replica.admin("box.cfg{replication_source=''}") # reconfigure master to replica master.rpl_master = replica - master.reconfigure("replication/cfg/master_to_replica.cfg", silent = False) + print("switch master to replica") + master.admin("box.cfg{replication_source='127.0.0.1:%s'}" % replica.sql.port, silent=True) # insert to replica insert_tuples(replica, id, id + ID_STEP) @@ -69,15 +69,16 @@ for i in range(REPEAT): print "rollback servers configuration" # reconfigure replica to master master.rpl_master = None - master.reconfigure("replication/cfg/master.cfg", silent = False) + print("switch master to master") + master.admin("box.cfg{replication_source=''}") # reconfigure master to replica replica.rpl_master = master - replica.reconfigure("replication/cfg/replica.cfg", silent = False) + print("switch replica to replica") + replica.admin("box.cfg{replication_source='127.0.0.1:%s'}" % master.sql.port, silent=True) # Cleanup. replica.stop() replica.cleanup(True) server.stop() -server.cfgfile_source = cfgfile_bkp server.deploy() diff --git a/test/wal/suite.ini b/test/wal/suite.ini index 6e880db662105fb3eba2fcb356ece8991f9a8536..f40147ac6b3d6cce36a92fd739d9535073391962 100644 --- a/test/wal/suite.ini +++ b/test/wal/suite.ini @@ -2,10 +2,3 @@ core = tarantool script = wal.lua description = tarantool/box, wal_mode = none -config = tarantool.cfg -# put disabled tests here -#disabled = xlog.test -# disabled = lua.test -# put disabled in valgrind test here -#valgrind_disabled = admin_coredump.test -#release_disabled = errinj.test diff --git a/test/wal/wal.lua b/test/wal/wal.lua index 6151ffcb34e85b4c5db8bde2cdbac49f002dc56f..14ba9c3b91cd23b7fb07590125dcaf572d6fcf55 100644 --- a/test/wal/wal.lua +++ b/test/wal/wal.lua @@ -1 +1,8 @@ #!/usr/bin/env tarantool_box +box.cfg{ + primary_port = os.getenv("PRIMARY_PORT"), + admin_port = os.getenv("ADMIN_PORT"), + slab_alloc_arena = 0.1, + pid_file = "tarantool.pid", + wal_mode = "none" +} diff --git a/third_party/gopt/gopt.h b/third_party/gopt/gopt.h index 2bc98b44fd4e97e5ffe0e54efe8635d4253243b8..6c7e36af594011bfcf51fd1ee6c8e59a858f0c5e 100644 --- a/third_party/gopt/gopt.h +++ b/third_party/gopt/gopt.h @@ -19,6 +19,9 @@ Before modifying or distributing this software I ask that you would please read http://www.purposeful.co.uk/tfl/ */ +#ifdef __cplusplus +extern "C" { +#endif #define GOPT_ONCE 0 #define GOPT_REPEAT 1 @@ -69,4 +72,8 @@ void gopt_free( void *opts ); /** Prints descriptions for all options. */ void gopt_help(const void *opt_def); +#ifdef __cplusplus +} +#endif + #endif /* GOPT_H_INCLUDED */