From: Amitay Isaacs Date: Fri, 10 Nov 2017 01:15:45 +0000 (+1100) Subject: ctdb-common: Start listening to sockets only on successful startup X-Git-Tag: talloc-2.1.11~430 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=984c3f4f66846fb05fbbbc0cb4d2a3d2cacb6444;p=thirdparty%2Fsamba.git ctdb-common: Start listening to sockets only on successful startup Fix tests to use wait_send() instead of startup() as a synchronization point to ensure that the socket is listening. Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke --- diff --git a/ctdb/common/sock_daemon.c b/ctdb/common/sock_daemon.c index 8ceb7c96bda..ae291d773c3 100644 --- a/ctdb/common/sock_daemon.c +++ b/ctdb/common/sock_daemon.c @@ -524,6 +524,7 @@ static void sock_daemon_run_signal_handler(struct tevent_context *ev, void *private_data); static void sock_daemon_run_reconfigure(struct tevent_req *req); static void sock_daemon_run_shutdown(struct tevent_req *req); +static bool sock_daemon_run_socket_listen(struct tevent_req *req); static void sock_daemon_run_socket_fail(struct tevent_req *subreq); static void sock_daemon_run_watch_pid(struct tevent_req *subreq); static void sock_daemon_run_wait(struct tevent_req *req); @@ -539,8 +540,6 @@ struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx, struct tevent_req *req, *subreq; struct sock_daemon_run_state *state; struct tevent_signal *se; - struct sock_socket *sock; - bool remove_before_use = false; req = tevent_req_create(mem_ctx, &state, struct sock_daemon_run_state); @@ -557,7 +556,6 @@ struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx, tevent_req_error(req, EEXIST); return tevent_req_post(req, ev); } - remove_before_use = true; } state->ev = ev; @@ -596,16 +594,6 @@ struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - for (sock = sockd->socket_list; sock != NULL; sock = sock->next) { - subreq = sock_socket_start_send(state, ev, sock, - remove_before_use); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - tevent_req_set_callback(subreq, sock_daemon_run_socket_fail, - req); - } - if (pid_watch > 1) { subreq = tevent_wakeup_send(state, ev, tevent_timeval_current_ofs(1,0)); @@ -650,6 +638,10 @@ static void sock_daemon_run_started(struct tevent_req *subreq) D_NOTICE("startup completed successfully\n"); } + status = sock_daemon_run_socket_listen(req); + if (! status) { + return; + } sock_daemon_run_wait(req); } @@ -714,6 +706,31 @@ static void sock_daemon_run_shutdown(struct tevent_req *req) TALLOC_FREE(sockd->pid_ctx); } +static bool sock_daemon_run_socket_listen(struct tevent_req *req) +{ + struct tevent_req *subreq; + struct sock_daemon_run_state *state = tevent_req_data( + req, struct sock_daemon_run_state); + struct sock_daemon_context *sockd = state->sockd; + struct sock_socket *sock; + bool remove_before_use = false; + + if (sockd->pid_ctx != NULL) { + remove_before_use = true; + } + for (sock = sockd->socket_list; sock != NULL; sock = sock->next) { + subreq = sock_socket_start_send(state, state->ev, sock, + remove_before_use); + if (tevent_req_nomem(subreq, req)) { + return false; + } + tevent_req_set_callback(subreq, sock_daemon_run_socket_fail, + req); + } + + return true; +} + static void sock_daemon_run_socket_fail(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( diff --git a/ctdb/tests/cunit/sock_daemon_test_001.sh b/ctdb/tests/cunit/sock_daemon_test_001.sh index 0561863e256..bf925fbe2ab 100755 --- a/ctdb/tests/cunit/sock_daemon_test_001.sh +++ b/ctdb/tests/cunit/sock_daemon_test_001.sh @@ -25,16 +25,17 @@ result_filter () ok <fd, &ret, sizeof(ret)); - assert(nwritten == sizeof(ret)); - close(server_state->fd); - server_state->fd = -1; - return 0; -} - struct test6_wait_state { struct test6_server_state *server_state; }; @@ -934,8 +952,17 @@ static struct tevent_req *test6_wait_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, void *private_data) { + struct test6_server_state *server_state = + (struct test6_server_state *)private_data; struct tevent_req *req, *subreq; struct test6_wait_state *state; + ssize_t nwritten; + int ret = 1; + + nwritten = write(server_state->fd, &ret, sizeof(ret)); + assert(nwritten == sizeof(ret)); + close(server_state->fd); + server_state->fd = -1; req = tevent_req_create(mem_ctx, &state, struct test6_wait_state); if (req == NULL) { @@ -992,7 +1019,6 @@ static bool test6_wait_recv(struct tevent_req *req, int *perr) } static struct sock_daemon_funcs test6_funcs = { - .startup = test6_startup, .wait_send = test6_wait_send, .wait_recv = test6_wait_recv, }; @@ -1366,6 +1392,84 @@ static void test9(TALLOC_CTX *mem_ctx, const char *pidfile, close(fd[0]); } +static void test10_shutdown(void *private_data) +{ + int fd = *(int *)private_data; + int ret = 3; + ssize_t nwritten; + + nwritten = write(fd, &ret, sizeof(ret)); + assert(nwritten == sizeof(ret)); +} + +struct test10_wait_state { +}; + +static void test10_wait_done(struct tevent_req *subreq); + +static struct tevent_req *test10_wait_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + void *private_data) +{ + int fd = *(int *)private_data; + struct tevent_req *req, *subreq; + struct test10_wait_state *state; + size_t nwritten; + int ret = 1; + + req = tevent_req_create(mem_ctx, &state, struct test10_wait_state); + if (req == NULL) { + return NULL; + } + + subreq = tevent_wakeup_send(state, ev, + tevent_timeval_current_ofs(10, 0)); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, test10_wait_done, req); + + nwritten = write(fd, &ret, sizeof(ret)); + assert(nwritten == sizeof(ret)); + + return req; +} + +static void test10_wait_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + bool status; + + status = tevent_wakeup_recv(subreq); + if (! status) { + tevent_req_error(req, EIO); + return; + } + + tevent_req_done(req); +} + +static bool test10_wait_recv(struct tevent_req *req, int *perr) +{ + int ret; + + if (tevent_req_is_unix_error(req, &ret)) { + if (perr != NULL) { + *perr = ret; + } + return false; + } + + return true; +} + +static struct sock_daemon_funcs test10_funcs = { + .shutdown = test10_shutdown, + .wait_send = test10_wait_send, + .wait_recv = test10_wait_recv, +}; + /* * test10 * @@ -1399,7 +1503,7 @@ static void test10(TALLOC_CTX *mem_ctx, const char *pidfile, assert(ev != NULL); ret = sock_daemon_setup(mem_ctx, "test10", "file:", "NOTICE", - &test2_funcs, &fd[1], &sockd); + &test10_funcs, &fd[1], &sockd); assert(ret == 0); ret = sock_daemon_add_unix(sockd, sockpath, @@ -1443,7 +1547,7 @@ static void test10(TALLOC_CTX *mem_ctx, const char *pidfile, assert(ev != NULL); ret = sock_daemon_setup(mem_ctx, "test10", "file:", "NOTICE", - &test2_funcs, &fd[1], &sockd); + &test10_funcs, &fd[1], &sockd); assert(ret == 0); ret = sock_daemon_add_unix(sockd, sockpath,