diff --git a/include/fiber.h b/include/fiber.h index 1ef42904dfd7aeb726091f391b431b8ced81bb2b..7ced635808eb83da5282bd1891a25208747a7cfa 100644 --- a/include/fiber.h +++ b/include/fiber.h @@ -97,7 +97,8 @@ extern __thread struct fiber *fiber; void fiber_init(void); void fiber_free(void); -struct fiber *fiber_create(const char *name, void (*f) (va_list)); +typedef void(*fiber_func)(va_list); +struct fiber *fiber_create(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 10f4e8ce4b9e96cfae7fbac486acf2b446dbae13..10a5ac7b13f4e17b331c4bbe7526fe37b4e6a35a 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 3b1f3619094df0d8d680128836ca3879768f74ea..85621c110c050440c526494de60f244f9210a44e 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 158934eed6fa711c0615ac123b5fdb6d3229be6c..d12db6a2c5da68cde7a2bf7a8c4e9fed6c56839b 100644 --- a/src/tarantool.m +++ b/src/tarantool.m @@ -315,7 +315,7 @@ tarantool_uptime(void) } int -snapshot(void *ev, int events __attribute__((unused))) +snapshot(void) { if (snapshot_pid) return EINPROGRESS; @@ -326,23 +326,9 @@ 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; + say_warn("Snapshot process was started, pid=%d, fid=%d", + snapshot_pid, fiber->fid); int status = wait_for_child(p); snapshot_pid = 0; return (WIFSIGNALED(status) ? EINTR : WEXITSTATUS(status)); @@ -362,6 +348,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 has already been started, " + "signal will be ignored"); + return; + } + fiber_call(fiber_create("snapshot", (fiber_func)snapshot)); +} + static void signal_cb(void) { @@ -488,7 +490,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]);