mirror of
https://github.com/samba-team/samba.git
synced 2025-02-26 21:57:41 +03:00
ctdb-common: Add async version of shutdown in sock_daemon
Signed-off-by: Amitay Isaacs <amitay@gmail.com> Reviewed-by: Martin Schwenke <martin@meltin.net> Autobuild-User(master): Martin Schwenke <martins@samba.org> Autobuild-Date(master): Tue Nov 21 08:58:45 CET 2017 on sn-devel-144
This commit is contained in:
parent
41d888afbe
commit
c1b4a74f27
@ -524,6 +524,7 @@ struct sock_daemon_run_state {
|
||||
pid_t pid_watch;
|
||||
|
||||
int fd;
|
||||
int exit_code;
|
||||
};
|
||||
|
||||
static void sock_daemon_run_started(struct tevent_req *subreq);
|
||||
@ -535,6 +536,8 @@ static void sock_daemon_run_signal_handler(struct tevent_context *ev,
|
||||
static void sock_daemon_run_reconfigure(struct tevent_req *req);
|
||||
static void sock_daemon_run_reconfigure_done(struct tevent_req *subreq);
|
||||
static void sock_daemon_run_shutdown(struct tevent_req *req);
|
||||
static void sock_daemon_run_shutdown_done(struct tevent_req *subreq);
|
||||
static void sock_daemon_run_exit(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);
|
||||
@ -702,6 +705,8 @@ static void sock_daemon_run_signal_handler(struct tevent_context *ev,
|
||||
{
|
||||
struct tevent_req *req = talloc_get_type_abort(
|
||||
private_data, struct tevent_req);
|
||||
struct sock_daemon_run_state *state = tevent_req_data(
|
||||
req, struct sock_daemon_run_state);
|
||||
|
||||
D_NOTICE("Received signal %d\n", signum);
|
||||
|
||||
@ -711,8 +716,8 @@ static void sock_daemon_run_signal_handler(struct tevent_context *ev,
|
||||
}
|
||||
|
||||
if (signum == SIGINT || signum == SIGTERM) {
|
||||
state->exit_code = EINTR;
|
||||
sock_daemon_run_shutdown(req);
|
||||
tevent_req_error(req, EINTR);
|
||||
}
|
||||
}
|
||||
|
||||
@ -770,6 +775,7 @@ static void sock_daemon_run_reconfigure_done(struct tevent_req *subreq)
|
||||
|
||||
static void sock_daemon_run_shutdown(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;
|
||||
@ -782,11 +788,53 @@ static void sock_daemon_run_shutdown(struct tevent_req *req)
|
||||
TALLOC_FREE(sock);
|
||||
}
|
||||
|
||||
if (sockd->funcs != NULL && sockd->funcs->shutdown_send != NULL &&
|
||||
sockd->funcs->shutdown_recv != NULL) {
|
||||
subreq = sockd->funcs->shutdown_send(state, state->ev,
|
||||
sockd->private_data);
|
||||
if (subreq == NULL) {
|
||||
sock_daemon_run_exit(req);
|
||||
return;
|
||||
}
|
||||
tevent_req_set_callback(subreq, sock_daemon_run_shutdown_done,
|
||||
req);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sockd->funcs != NULL && sockd->funcs->shutdown != NULL) {
|
||||
sockd->funcs->shutdown(sockd->private_data);
|
||||
}
|
||||
|
||||
sock_daemon_run_exit(req);
|
||||
}
|
||||
|
||||
static void sock_daemon_run_shutdown_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;
|
||||
|
||||
sockd->funcs->shutdown_recv(subreq);
|
||||
TALLOC_FREE(subreq);
|
||||
|
||||
sock_daemon_run_exit(req);
|
||||
}
|
||||
|
||||
static void sock_daemon_run_exit(struct tevent_req *req)
|
||||
{
|
||||
struct sock_daemon_run_state *state = tevent_req_data(
|
||||
req, struct sock_daemon_run_state);
|
||||
struct sock_daemon_context *sockd = state->sockd;
|
||||
|
||||
TALLOC_FREE(sockd->pid_ctx);
|
||||
|
||||
if (state->exit_code == 0) {
|
||||
tevent_req_done(req);
|
||||
} else {
|
||||
tevent_req_error(req, state->exit_code);
|
||||
}
|
||||
}
|
||||
|
||||
static bool sock_daemon_run_socket_listen(struct tevent_req *req)
|
||||
@ -826,13 +874,14 @@ static void sock_daemon_run_socket_fail(struct tevent_req *subreq)
|
||||
|
||||
status = sock_socket_start_recv(subreq, &ret, state, &sockpath);
|
||||
TALLOC_FREE(subreq);
|
||||
sock_daemon_run_shutdown(req);
|
||||
if (! status) {
|
||||
D_ERR("socket %s closed unexpectedly\n", sockpath);
|
||||
tevent_req_error(req, ret);
|
||||
state->exit_code = ret;
|
||||
} else {
|
||||
tevent_req_done(req);
|
||||
state->exit_code = 0;
|
||||
}
|
||||
|
||||
sock_daemon_run_shutdown(req);
|
||||
}
|
||||
|
||||
static void sock_daemon_run_watch_pid(struct tevent_req *subreq)
|
||||
@ -855,8 +904,8 @@ static void sock_daemon_run_watch_pid(struct tevent_req *subreq)
|
||||
if (ret == -1) {
|
||||
if (errno == ESRCH) {
|
||||
D_ERR("PID %d gone away, exiting\n", state->pid_watch);
|
||||
state->exit_code = ESRCH;
|
||||
sock_daemon_run_shutdown(req);
|
||||
tevent_req_error(req, ESRCH);
|
||||
return;
|
||||
} else {
|
||||
D_ERR("Failed to check PID status %d, ret=%d\n",
|
||||
@ -898,17 +947,18 @@ static void sock_daemon_run_wait_done(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;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
bool status;
|
||||
|
||||
status = sockd->funcs->wait_recv(subreq, &ret);
|
||||
TALLOC_FREE(subreq);
|
||||
sock_daemon_run_shutdown(req);
|
||||
if (! status) {
|
||||
tevent_req_error(req, ret);
|
||||
state->exit_code = ret;
|
||||
} else {
|
||||
tevent_req_done(req);
|
||||
state->exit_code = 0;
|
||||
}
|
||||
|
||||
sock_daemon_run_shutdown(req);
|
||||
}
|
||||
|
||||
bool sock_daemon_run_recv(struct tevent_req *req, int *perr)
|
||||
|
@ -63,6 +63,12 @@ struct sock_client_context;
|
||||
* shutdown() is called when process receives SIGINT or SIGTERM or
|
||||
* when wait computation has finished
|
||||
*
|
||||
* shutdown_send()/shutdown_recv() is the async version of shutdown()
|
||||
*
|
||||
* Please note that only one (sync or async) version of these functions
|
||||
* will be called. If both versions are defined, then only async function
|
||||
* will be called.
|
||||
*
|
||||
* wait_send() starts the async computation to keep running the daemon
|
||||
* wait_recv() ends the async computation to keep running the daemon
|
||||
*
|
||||
@ -86,6 +92,11 @@ struct sock_daemon_funcs {
|
||||
|
||||
void (*shutdown)(void *private_data);
|
||||
|
||||
struct tevent_req * (*shutdown_send)(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
void *private_data);
|
||||
void (*shutdown_recv)(struct tevent_req *req);
|
||||
|
||||
struct tevent_req * (*wait_send)(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
void *private_data);
|
||||
|
@ -297,6 +297,40 @@ static void test2_shutdown(void *private_data)
|
||||
assert(nwritten == sizeof(ret));
|
||||
}
|
||||
|
||||
struct test2_shutdown_state {
|
||||
int fd;
|
||||
};
|
||||
|
||||
static struct tevent_req *test2_shutdown_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
void *private_data)
|
||||
{
|
||||
struct tevent_req *req;
|
||||
struct test2_shutdown_state *state;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
struct test2_shutdown_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
state->fd = *(int *)private_data;
|
||||
|
||||
tevent_req_done(req);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
static void test2_shutdown_recv(struct tevent_req *req)
|
||||
{
|
||||
struct test2_shutdown_state *state = tevent_req_data(
|
||||
req, struct test2_shutdown_state);
|
||||
int ret = 3;
|
||||
ssize_t nwritten;
|
||||
|
||||
nwritten = write(state->fd, &ret, sizeof(ret));
|
||||
assert(nwritten == sizeof(ret));
|
||||
}
|
||||
|
||||
static void test2(TALLOC_CTX *mem_ctx, const char *pidfile,
|
||||
const char *sockpath)
|
||||
{
|
||||
@ -405,6 +439,8 @@ static void test2(TALLOC_CTX *mem_ctx, const char *pidfile,
|
||||
.startup = test2_startup,
|
||||
.reconfigure_send = test2_reconfigure_send,
|
||||
.reconfigure_recv = test2_reconfigure_recv,
|
||||
.shutdown_send = test2_shutdown_send,
|
||||
.shutdown_recv = test2_shutdown_recv,
|
||||
};
|
||||
|
||||
close(fd[0]);
|
||||
@ -449,6 +485,10 @@ static void test2(TALLOC_CTX *mem_ctx, const char *pidfile,
|
||||
ret = kill(pid, SIGTERM);
|
||||
assert(ret == 0);
|
||||
|
||||
n = read(fd[0], &ret, sizeof(ret));
|
||||
assert(n == sizeof(ret));
|
||||
assert(ret == 3);
|
||||
|
||||
pid2 = waitpid(pid, &ret, 0);
|
||||
assert(pid2 == pid);
|
||||
assert(WEXITSTATUS(ret) == 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user