diff options
author | Amitay Isaacs <amitay@gmail.com> | 2017-11-17 12:36:29 +1100 |
---|---|---|
committer | Martin Schwenke <martins@samba.org> | 2017-11-21 05:03:17 +0100 |
commit | 7558592d15fa4911fa8d2061aa56e2b151f516a2 (patch) | |
tree | cf5a10cfdd3c538a68fad70d577fe510f9fbbdd9 /ctdb | |
parent | ba3e9e6eae62af0ee991945206e0ef2b3dba8acf (diff) | |
download | samba-7558592d15fa4911fa8d2061aa56e2b151f516a2.tar.gz |
ctdb-common: Add async version of startup in sock_daemon
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
Diffstat (limited to 'ctdb')
-rw-r--r-- | ctdb/common/sock_daemon.c | 40 | ||||
-rw-r--r-- | ctdb/common/sock_daemon.h | 8 | ||||
-rwxr-xr-x | ctdb/tests/cunit/sock_daemon_test_001.sh | 2 | ||||
-rw-r--r-- | ctdb/tests/src/sock_daemon_test.c | 45 |
4 files changed, 95 insertions, 0 deletions
diff --git a/ctdb/common/sock_daemon.c b/ctdb/common/sock_daemon.c index 0ef01666883..6b05e2462f9 100644 --- a/ctdb/common/sock_daemon.c +++ b/ctdb/common/sock_daemon.c @@ -527,6 +527,7 @@ struct sock_daemon_run_state { }; static void sock_daemon_run_started(struct tevent_req *subreq); +static void sock_daemon_run_startup_done(struct tevent_req *subreq); static void sock_daemon_run_signal_handler(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, @@ -634,6 +635,18 @@ static void sock_daemon_run_started(struct tevent_req *subreq) D_NOTICE("daemon started, pid=%u\n", getpid()); + if (sockd->funcs != NULL && sockd->funcs->startup_send != NULL && + sockd->funcs->startup_recv != NULL) { + subreq = sockd->funcs->startup_send(state, state->ev, + sockd->private_data); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, sock_daemon_run_startup_done, + req); + return; + } + if (sockd->funcs != NULL && sockd->funcs->startup != NULL) { int ret; @@ -654,6 +667,33 @@ static void sock_daemon_run_started(struct tevent_req *subreq) sock_daemon_run_wait(req); } +static void sock_daemon_run_startup_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct sock_daemon_run_state *state = tevent_req_data( + req, struct sock_daemon_run_state); + struct sock_daemon_context *sockd = state->sockd; + int ret; + bool status; + + status = sockd->funcs->startup_recv(subreq, &ret); + TALLOC_FREE(subreq); + if (! status) { + D_ERR("startup failed, ret=%d\n", ret); + tevent_req_error(req, EIO); + return; + } + + D_NOTICE("startup completed succesfully\n"); + + status = sock_daemon_run_socket_listen(req); + if (! status) { + return; + } + sock_daemon_run_wait(req); +} + static void sock_daemon_run_signal_handler(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, diff --git a/ctdb/common/sock_daemon.h b/ctdb/common/sock_daemon.h index 190a4ef172f..7f19b32dcd4 100644 --- a/ctdb/common/sock_daemon.h +++ b/ctdb/common/sock_daemon.h @@ -52,6 +52,8 @@ struct sock_client_context; * startup() should return 0 for success, non-zero value on failure * On failure, sock_daemon_run() will return error. * + * startup_send()/startup_recv() is the async version of startup() + * * reconfigure() is called when the daemon receives SIGUSR1 or SIGHUP * reconfigure() should return 0 for success, non-zero value on failure * On failure, sock_daemon_run() will continue to run. @@ -67,6 +69,12 @@ struct sock_client_context; */ struct sock_daemon_funcs { int (*startup)(void *private_data); + + struct tevent_req * (*startup_send)(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + void *private_data); + bool (*startup_recv)(struct tevent_req *req, int *perr); + int (*reconfigure)(void *private_data); void (*shutdown)(void *private_data); diff --git a/ctdb/tests/cunit/sock_daemon_test_001.sh b/ctdb/tests/cunit/sock_daemon_test_001.sh index bf925fbe2ab..aa1d6b471db 100755 --- a/ctdb/tests/cunit/sock_daemon_test_001.sh +++ b/ctdb/tests/cunit/sock_daemon_test_001.sh @@ -26,6 +26,8 @@ ok <<EOF test1[PID]: daemon started, pid=PID test1[PID]: startup failed, ret=1 test1[PID]: daemon started, pid=PID +test1[PID]: startup failed, ret=2 +test1[PID]: daemon started, pid=PID test1[PID]: startup completed successfully test1[PID]: listening on $sockpath test1[PID]: Shutting down diff --git a/ctdb/tests/src/sock_daemon_test.c b/ctdb/tests/src/sock_daemon_test.c index d224ce85dc3..72f265f0b78 100644 --- a/ctdb/tests/src/sock_daemon_test.c +++ b/ctdb/tests/src/sock_daemon_test.c @@ -80,6 +80,34 @@ static int test1_startup(void *private_data) return 0; } +struct test1_startup_state { +}; + +static struct tevent_req *test1_startup_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + void *private_data) +{ + struct tevent_req *req; + struct test1_startup_state *state; + + req = tevent_req_create(mem_ctx, &state, struct test1_startup_state); + if (req == NULL) { + return NULL; + } + + tevent_req_error(req, 2); + return tevent_req_post(req, ev); +} + +static bool test1_startup_recv(struct tevent_req *req, int *perr) +{ + if (tevent_req_is_unix_error(req, perr)) { + return false; + } + + return true; +} + static struct tevent_req *dummy_read_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sock_client_context *client, @@ -137,6 +165,23 @@ static void test1(TALLOC_CTX *mem_ctx, const char *pidfile, talloc_free(sockd); test1_funcs = (struct sock_daemon_funcs){ + .startup_send = test1_startup_send, + .startup_recv = test1_startup_recv, + }; + + ret = sock_daemon_setup(mem_ctx, "test1", "file:", "NOTICE", + &test1_funcs, NULL, &sockd); + assert(ret == 0); + assert(sockd != NULL); + + ret = stat(pidfile, &st); + assert(ret == -1); + + ret = sock_daemon_run(ev, sockd, NULL, false, false, -1); + assert(ret == EIO); + talloc_free(sockd); + + test1_funcs = (struct sock_daemon_funcs){ .startup = test1_startup, .wait_send = dummy_wait_send, .wait_recv = dummy_wait_recv, |