From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 6D35522607 for ; Sun, 1 Jul 2018 17:41:10 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id yGwZLF_9ugyR for ; Sun, 1 Jul 2018 17:41:10 -0400 (EDT) Received: from smtp63.i.mail.ru (smtp63.i.mail.ru [217.69.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id A6E87201C6 for ; Sun, 1 Jul 2018 17:41:09 -0400 (EDT) From: Serge Petrenko Subject: [tarantool-patches] [PATCH] Add a way to know instance is being run or restarted by tarantoolctl. Date: Mon, 2 Jul 2018 00:40:48 +0300 Message-Id: <20180701214048.71474-1-sergepetrenko@tarantool.org> Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-subscribe: List-owner: List-post: List-archive: To: tarantool-patches@freelists.org Cc: Serge Petrenko There are some hacks to know the instance was run by tarantoolctl, none of them are too reliable, thoug. This patch adds a convenient way to know whether instance is being run or restarted by tarantoolctl. For this purpose, we intoduce 2 new fields to box.info table: box.info.tarantoolctl and box.info.is_restart, set to true, respectively, if the instance is being run by tarantoolctl, and if it is being restarted. Closes: #3215 --- https://github.com/tarantool/tarantool/tree/sergepetrenko/gh-3215-tarantoolctl-detection https://github.com/tarantool/tarantool/issues/3215 extra/dist/tarantoolctl.in | 9 +++++++++ src/box/lua/info.c | 15 +++++++++++++++ src/main.cc | 37 +++++++++++++++++++++++++++++++++++++ src/main.h | 12 ++++++++++++ test/box/info.result | 10 ++++++++++ test/box/info.test.lua | 2 ++ 6 files changed, 85 insertions(+) diff --git a/extra/dist/tarantoolctl.in b/extra/dist/tarantoolctl.in index b6b8e09c9..e3212c14a 100755 --- a/extra/dist/tarantoolctl.in +++ b/extra/dist/tarantoolctl.in @@ -22,6 +22,7 @@ int kill(int pid, int sig); int isatty(int fd); int getppid(void); int chdir(const char *path); +int setenv(const char *name, const char *value, int overwrite); ]] local TIMEOUT_INFINITY = 100 * 365 * 86400 @@ -509,6 +510,11 @@ local function start() log.error("The daemon is already running: PID %s", pid) os.exit(1) end + + -- Set an environment variable for tarantool + -- to know it's being run under tarantoolctl. + ffi.C.setenv('TARANTOOLCTL', 'true', 0) + box.cfg = wrapper_cfg require('title').update{ script_name = instance_path, @@ -593,6 +599,9 @@ local function restart() end stop() fiber.sleep(1) + -- Set an environment variable for tarantool to + -- know it's being restarted by tarantoolctl. + ffi.C.setenv('TARANTOOL_RESTART', 'true', 0) start() return 0 end diff --git a/src/box/lua/info.c b/src/box/lua/info.c index d6697df9c..9b29d1320 100644 --- a/src/box/lua/info.c +++ b/src/box/lua/info.c @@ -246,6 +246,19 @@ lbox_info_ro(struct lua_State *L) return 1; } +static int +lbox_info_tarantoolctl(struct lua_State *L) +{ + lua_pushboolean(L, tarantool_under_tarantoolctl()); + return 1; +} + +static int +lbox_info_is_restart(struct lua_State *L) +{ + lua_pushboolean(L, tarantool_is_restart()); + return 1; +} /* * Tarantool 1.6.x compat */ @@ -530,6 +543,8 @@ static const struct luaL_Reg lbox_info_dynamic_meta[] = { {"signature", lbox_info_signature}, {"vclock", lbox_info_vclock}, {"ro", lbox_info_ro}, + {"tarantoolctl", lbox_info_tarantoolctl}, + {"is_restart", lbox_info_is_restart}, {"replication", lbox_info_replication}, {"status", lbox_info_status}, {"uptime", lbox_info_uptime}, diff --git a/src/main.cc b/src/main.cc index a36a2b0d0..888926ec3 100644 --- a/src/main.cc +++ b/src/main.cc @@ -87,14 +87,41 @@ static int main_argc; static ev_signal ev_sigs[6]; static const int ev_sig_count = sizeof(ev_sigs)/sizeof(*ev_sigs); +static bool under_tarantoolctl; +static bool is_restart; + static double start_time; +bool +tarantool_under_tarantoolctl() +{ + return under_tarantoolctl; +} + +bool +tarantool_is_restart() +{ + return is_restart; +} + double tarantool_uptime(void) { return ev_monotonic_now(loop()) - start_time; } +/** + * Check if the instance is being run or restarted + * by tarantoolctl. In case it is, there will be + * TARANTOOLCTL (and maybe TARANTOOL_RESTART) environment + * variable set for us by tarantoolctl. + */ +void detect_tarantoolctl() +{ + under_tarantoolctl = getenv("TARANTOOLCTL") != NULL; + is_restart = getenv("TARANTOOL_RESTART") != NULL; +} + /** * Create a checkpoint from signal handler (SIGUSR1) */ @@ -523,6 +550,16 @@ load_cfg() title_set_custom(cfg_gets("custom_proc_title")); title_update(); box_cfg(); + + /* + * tarantoolctl is a lua script executed by tarantool, + * so the only valid place in tarantool to detect + * tarantoolctl's presence is after the call to + * tarantool_lua_run_script(), but before user code + * execution. Doing it right after user calls + * box.cfg{} seems to be the only way out. + */ + detect_tarantoolctl(); } void diff --git a/src/main.h b/src/main.h index 221374144..c69b6a912 100644 --- a/src/main.h +++ b/src/main.h @@ -37,6 +37,18 @@ extern "C" { #endif /* defined(__cplusplus) */ +/** + * Returns whether instance was run by tarantoolctl. + */ +bool +tarantool_under_tarantoolctl(); + +/** + * Returns whether the instance was restarted by tarantoolctl. + */ +bool +tarantool_is_restart(); + double tarantool_uptime(void); void diff --git a/test/box/info.result b/test/box/info.result index 338463155..5b7a827bf 100644 --- a/test/box/info.result +++ b/test/box/info.result @@ -51,6 +51,14 @@ box.info.status --- - running ... +box.info.tarantoolctl == true or box.info +--- +- true +... +box.info.is_restart == false or box.info +--- +- true +... string.len(box.info.uptime) > 0 --- - true @@ -77,6 +85,7 @@ t - - cluster - gc - id + - is_restart - lsn - memory - pid @@ -84,6 +93,7 @@ t - ro - signature - status + - tarantoolctl - uptime - uuid - vclock diff --git a/test/box/info.test.lua b/test/box/info.test.lua index 60ee3216d..828e21c56 100644 --- a/test/box/info.test.lua +++ b/test/box/info.test.lua @@ -14,6 +14,8 @@ box.info.signature >= 0 box.info.ro == false box.info.replication[1].id box.info.status +box.info.tarantoolctl == true or box.info +box.info.is_restart == false or box.info string.len(box.info.uptime) > 0 string.match(box.info.uptime, '^[1-9][0-9]*$') ~= nil box.info.cluster.uuid == box.space._schema:get{'cluster'}[2] -- 2.15.2 (Apple Git-101.1)