diff --git a/include/fiber.h b/include/fiber.h index 0d31a830de9bb9313d1e3426c2e75a73341b7c28..49dda87f2f3fd0d6a075271ca481c6b3978b2b30 100644 --- a/include/fiber.h +++ b/include/fiber.h @@ -95,7 +95,8 @@ extern __thread struct fiber *fiber; void fiber_init(void); void fiber_free(void); -struct fiber *fiber_new(const char *name, void (*f) (va_list)); +typedef void(*fiber_func)(va_list); +struct fiber *fiber_new(const char *name, fiber_func f); void fiber_set_name(struct fiber *fiber, const char *name); int wait_for_child(pid_t pid); diff --git a/include/tarantool.h b/include/tarantool.h index 6da91c9b2e49e213c40e2e1acc62fd65af5ff368..b9eda2655216e50cdf2ad03e6ac529439826f155 100644 --- a/include/tarantool.h +++ b/include/tarantool.h @@ -43,7 +43,7 @@ extern char *binary_filename; extern char *custom_proc_title; i32 reload_cfg(struct tbuf *out); void show_cfg(struct tbuf *out); -int snapshot(void * /* ev */, int /* events */); +int snapshot(void); const char *tarantool_version(void); double tarantool_uptime(void); void tarantool_free(void); diff --git a/src/admin.m b/src/admin.m index 8b50cdf28a3e8413283a0e82ffabab54d17bf704..361eebaa919932ce01c442cfc7c20889c4c7fadc 100644 --- a/src/admin.m +++ b/src/admin.m @@ -328,7 +328,7 @@ tr67: tr76: #line 244 "src/admin.rl" { - int ret = snapshot(NULL, 0); + int ret = snapshot(); if (ret == 0) ok(out); @@ -453,7 +453,7 @@ tr68: tr77: #line 244 "src/admin.rl" { - int ret = snapshot(NULL, 0); + int ret = snapshot(); if (ret == 0) ok(out); diff --git a/src/admin.rl b/src/admin.rl index 9ad64f03a3c68d4af83dfc728c7989c6f4d70ca4..5172efcfb6a69dc8a05ac6256c5441add27e9a23 100644 --- a/src/admin.rl +++ b/src/admin.rl @@ -242,7 +242,7 @@ admin_dispatch(struct ev_io *coio, struct iobuf *iobuf, lua_State *L) } action save_snapshot { - int ret = snapshot(NULL, 0); + int ret = snapshot(); if (ret == 0) ok(out); diff --git a/src/tarantool.m b/src/tarantool.m index 2601f873e5aa2fbb891e2583520055cf90461f8b..75b76036b90a079188e5c5a452d7300ce84f86db 100644 --- a/src/tarantool.m +++ b/src/tarantool.m @@ -316,7 +316,7 @@ tarantool_uptime(void) } int -snapshot(void *ev, int events __attribute__((unused))) +snapshot(void) { if (snapshot_pid) return EINPROGRESS; @@ -327,22 +327,6 @@ snapshot(void *ev, int events __attribute__((unused))) return -1; } if (p > 0) { - /* - * If called from a signal handler, we can't - * access any fiber state, and no one is expecting - * to get an execution status. Just return 0 to - * indicate a successful fork. - */ - if (ev != NULL) - return 0; - /* - * This is 'save snapshot' call received from the - * administrative console. Check for the child - * exit status and report it back. This is done to - * make 'save snapshot' synchronous, and propagate - * any possible error up to the user. - */ - snapshot_pid = p; int status = wait_for_child(p); snapshot_pid = 0; @@ -363,6 +347,22 @@ snapshot(void *ev, int events __attribute__((unused))) return 0; } + +/** +* Create snapshot from signal handler (SIGUSR1) +* +*/ +static void +sig_snapshot(void) +{ + if (snapshot_pid) { + say_warn("Snapshot process is already running," + " the signal is ignored"); + return; + } + fiber_call(fiber_new("snapshot", (fiber_func)snapshot)); +} + static void signal_cb(void) { @@ -489,7 +489,7 @@ signal_init(void) sigs = palloc(eter_pool, sizeof(ev_signal) * 4); memset(sigs, 0, sizeof(ev_signal) * 4); - ev_signal_init(&sigs[0], (void*)snapshot, SIGUSR1); + ev_signal_init(&sigs[0], (void*)sig_snapshot, SIGUSR1); ev_signal_start(&sigs[0]); ev_signal_init(&sigs[1], (void*)signal_cb, SIGINT); ev_signal_start(&sigs[1]);