[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Mon Jan 16 20:17:02 UTC 2017
The branch, master has been updated
via ed722c3 ctdb-common: Add wait_send/wait_recv to sock_daemon_funcs
via d09469e ctdb-common: Avoid any processing after finishing tevent_req
via d5be557 ctdb-common: Pass tevent_req to the computation sub-functions
via 31274cf ctdb-common: Use consistent naming for sock_daemon_run computation functions
via 9e09a25 ctdb-common: Correct name of sock_daemon_run_send/recv state structure
from ff0d45c ctdb-tests: Fix name of the variable representing init script
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit ed722c3aa9690873af495cb467dd440c1a714d82
Author: Amitay Isaacs <amitay at gmail.com>
Date: Wed Jan 11 20:37:00 2017 +1100
ctdb-common: Add wait_send/wait_recv to sock_daemon_funcs
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12510
To be able to terminate the daemon from within the implementation,
create a subreq using wait_send() provided by the implementation.
When the subreq is finished, it signals the sock_daemon code to terminate
the daemon.
This avoids the need to keep track of the top level tevent_req causing
layer violation and keeps the code flow straighforward.
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
Autobuild-Date(master): Mon Jan 16 21:16:51 CET 2017 on sn-devel-144
commit d09469e575233242eab2a8c1c0767f52e7cad1e5
Author: Amitay Isaacs <amitay at gmail.com>
Date: Wed Jan 11 19:54:36 2017 +1100
ctdb-common: Avoid any processing after finishing tevent_req
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12510
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit d5be55725000eb34611dc76a2e8e7188eea2503f
Author: Amitay Isaacs <amitay at gmail.com>
Date: Fri Jan 13 10:43:44 2017 +1100
ctdb-common: Pass tevent_req to the computation sub-functions
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12510
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 31274cf7aec1bb26e8dac0dbd1b9a3fa799b2b85
Author: Amitay Isaacs <amitay at gmail.com>
Date: Fri Jan 13 10:40:43 2017 +1100
ctdb-common: Use consistent naming for sock_daemon_run computation functions
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12510
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 9e09a253b4ca1b5f9aa432c986c1755a173a9566
Author: Amitay Isaacs <amitay at gmail.com>
Date: Wed Jan 11 19:50:34 2017 +1100
ctdb-common: Correct name of sock_daemon_run_send/recv state structure
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12510
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
-----------------------------------------------------------------------
Summary of changes:
ctdb/common/sock_daemon.c | 132 +++++++++++++----------
ctdb/common/sock_daemon.h | 14 ++-
ctdb/tests/cunit/sock_daemon_test_001.sh | 2 +
ctdb/tests/src/sock_daemon_test.c | 175 ++++++++++++++++++++++++-------
4 files changed, 226 insertions(+), 97 deletions(-)
Changeset truncated at 500 lines:
diff --git a/ctdb/common/sock_daemon.c b/ctdb/common/sock_daemon.c
index ca4086d..b53b4d8 100644
--- a/ctdb/common/sock_daemon.c
+++ b/ctdb/common/sock_daemon.c
@@ -70,7 +70,6 @@ struct sock_daemon_context {
struct pidfile_context *pid_ctx;
struct sock_socket *socket_list;
- struct tevent_req *req;
};
/*
@@ -451,8 +450,6 @@ bool sock_socket_write_recv(struct tevent_req *req, int *perr)
* Socket daemon
*/
-static int sock_daemon_context_destructor(struct sock_daemon_context *sockd);
-
int sock_daemon_setup(TALLOC_CTX *mem_ctx, const char *daemon_name,
const char *logging, const char *debug_level,
const char *pidfile,
@@ -487,21 +484,10 @@ int sock_daemon_setup(TALLOC_CTX *mem_ctx, const char *daemon_name,
}
}
- talloc_set_destructor(sockd, sock_daemon_context_destructor);
-
*out = sockd;
return 0;
}
-static int sock_daemon_context_destructor(struct sock_daemon_context *sockd)
-{
- if (sockd->req != NULL) {
- tevent_req_done(sockd->req);
- }
-
- return 0;
-}
-
int sock_daemon_add_unix(struct sock_daemon_context *sockd,
const char *sockpath,
struct sock_socket_funcs *funcs,
@@ -529,7 +515,7 @@ int sock_daemon_add_unix(struct sock_daemon_context *sockd,
* Run socket daemon
*/
-struct sock_daemon_start_state {
+struct sock_daemon_run_state {
struct tevent_context *ev;
struct sock_daemon_context *sockd;
pid_t pid_watch;
@@ -537,15 +523,16 @@ struct sock_daemon_start_state {
int fd;
};
-static void sock_daemon_started(struct tevent_req *subreq);
-static void sock_daemon_signal_handler(struct tevent_context *ev,
- struct tevent_signal *se,
- int signum, int count, void *siginfo,
- void *private_data);
-static void sock_daemon_socket_fail(struct tevent_req *subreq);
-static void sock_daemon_watch_pid(struct tevent_req *subreq);
-static void sock_daemon_reconfigure(struct sock_daemon_start_state *state);
-static void sock_daemon_shutdown(struct sock_daemon_start_state *state);
+static void sock_daemon_run_started(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,
+ void *private_data);
+static void sock_daemon_run_reconfigure(struct tevent_req *req);
+static void sock_daemon_run_shutdown(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_done(struct tevent_req *subreq);
struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@@ -553,12 +540,12 @@ struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx,
pid_t pid_watch)
{
struct tevent_req *req, *subreq;
- struct sock_daemon_start_state *state;
+ struct sock_daemon_run_state *state;
struct tevent_signal *se;
struct sock_socket *sock;
req = tevent_req_create(mem_ctx, &state,
- struct sock_daemon_start_state);
+ struct sock_daemon_run_state);
if (req == NULL) {
return NULL;
}
@@ -573,28 +560,28 @@ struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx,
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
- tevent_req_set_callback(subreq, sock_daemon_started, req);
+ tevent_req_set_callback(subreq, sock_daemon_run_started, req);
se = tevent_add_signal(ev, state, SIGHUP, 0,
- sock_daemon_signal_handler, req);
+ sock_daemon_run_signal_handler, req);
if (tevent_req_nomem(se, req)) {
return tevent_req_post(req, ev);
}
se = tevent_add_signal(ev, state, SIGUSR1, 0,
- sock_daemon_signal_handler, req);
+ sock_daemon_run_signal_handler, req);
if (tevent_req_nomem(se, req)) {
return tevent_req_post(req, ev);
}
se = tevent_add_signal(ev, state, SIGINT, 0,
- sock_daemon_signal_handler, req);
+ sock_daemon_run_signal_handler, req);
if (tevent_req_nomem(se, req)) {
return tevent_req_post(req, ev);
}
se = tevent_add_signal(ev, state, SIGTERM, 0,
- sock_daemon_signal_handler, req);
+ sock_daemon_run_signal_handler, req);
if (tevent_req_nomem(se, req)) {
return tevent_req_post(req, ev);
}
@@ -604,7 +591,8 @@ struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx,
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
- tevent_req_set_callback(subreq, sock_daemon_socket_fail, req);
+ tevent_req_set_callback(subreq, sock_daemon_run_socket_fail,
+ req);
sock->req = subreq;
}
@@ -615,20 +603,30 @@ struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx,
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
- tevent_req_set_callback(subreq, sock_daemon_watch_pid, req);
+ tevent_req_set_callback(subreq, sock_daemon_run_watch_pid,
+ req);
}
- sockd->req = req;
+ if (sockd->funcs != NULL && sockd->funcs->wait_send != NULL &&
+ sockd->funcs->wait_recv != NULL) {
+ subreq = sockd->funcs->wait_send(state, ev,
+ sockd->private_data);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, sock_daemon_run_wait_done,
+ req);
+ }
return req;
}
-static void sock_daemon_started(struct tevent_req *subreq)
+static void sock_daemon_run_started(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
- struct sock_daemon_start_state *state = tevent_req_data(
- req, struct sock_daemon_start_state);
+ struct sock_daemon_run_state *state = tevent_req_data(
+ req, struct sock_daemon_run_state);
struct sock_daemon_context *sockd = state->sockd;
D_NOTICE("daemon started, pid=%u\n", getpid());
@@ -638,31 +636,31 @@ static void sock_daemon_started(struct tevent_req *subreq)
}
}
-static void sock_daemon_signal_handler(struct tevent_context *ev,
- struct tevent_signal *se,
- int signum, int count, void *siginfo,
- void *private_data)
+static void sock_daemon_run_signal_handler(struct tevent_context *ev,
+ struct tevent_signal *se,
+ int signum, int count, void *siginfo,
+ void *private_data)
{
struct tevent_req *req = talloc_get_type_abort(
private_data, struct tevent_req);
- struct sock_daemon_start_state *state = tevent_req_data(
- req, struct sock_daemon_start_state);
D_NOTICE("Received signal %d\n", signum);
if (signum == SIGHUP || signum == SIGUSR1) {
- sock_daemon_reconfigure(state);
+ sock_daemon_run_reconfigure(req);
return;
}
if (signum == SIGINT || signum == SIGTERM) {
- sock_daemon_shutdown(state);
+ sock_daemon_run_shutdown(req);
tevent_req_error(req, EINTR);
}
}
-static void sock_daemon_reconfigure(struct sock_daemon_start_state *state)
+static void sock_daemon_run_reconfigure(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;
if (sockd->funcs != NULL && sockd->funcs->reconfigure != NULL) {
@@ -670,8 +668,10 @@ static void sock_daemon_reconfigure(struct sock_daemon_start_state *state)
}
}
-static void sock_daemon_shutdown(struct sock_daemon_start_state *state)
+static void sock_daemon_run_shutdown(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;
struct sock_socket *sock;
@@ -690,32 +690,29 @@ static void sock_daemon_shutdown(struct sock_daemon_start_state *state)
TALLOC_FREE(sockd->pid_ctx);
}
-static void sock_daemon_socket_fail(struct tevent_req *subreq)
+static void sock_daemon_run_socket_fail(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
- struct sock_daemon_start_state *state = tevent_req_data(
- req, struct sock_daemon_start_state);
int ret = 0;
bool status;
status = sock_socket_start_recv(subreq, &ret);
TALLOC_FREE(subreq);
+ sock_daemon_run_shutdown(req);
if (! status) {
tevent_req_error(req, ret);
} else {
tevent_req_done(req);
}
-
- sock_daemon_shutdown(state);
}
-static void sock_daemon_watch_pid(struct tevent_req *subreq)
+static void sock_daemon_run_watch_pid(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
- struct sock_daemon_start_state *state = tevent_req_data(
- req, struct sock_daemon_start_state);
+ struct sock_daemon_run_state *state = tevent_req_data(
+ req, struct sock_daemon_run_state);
int ret;
bool status;
@@ -730,7 +727,7 @@ static void sock_daemon_watch_pid(struct tevent_req *subreq)
if (ret == -1) {
if (errno == ESRCH) {
D_ERR("PID %d gone away, exiting\n", state->pid_watch);
- sock_daemon_shutdown(state);
+ sock_daemon_run_shutdown(req);
tevent_req_error(req, ESRCH);
return;
} else {
@@ -744,7 +741,27 @@ static void sock_daemon_watch_pid(struct tevent_req *subreq)
if (tevent_req_nomem(subreq, req)) {
return;
}
- tevent_req_set_callback(subreq, sock_daemon_watch_pid, req);
+ tevent_req_set_callback(subreq, sock_daemon_run_watch_pid, req);
+}
+
+static void sock_daemon_run_wait_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->wait_recv(subreq, &ret);
+ TALLOC_FREE(subreq);
+ sock_daemon_run_shutdown(req);
+ if (! status) {
+ tevent_req_error(req, ret);
+ } else {
+ tevent_req_done(req);
+ }
}
bool sock_daemon_run_recv(struct tevent_req *req, int *perr)
@@ -777,7 +794,6 @@ int sock_daemon_run(struct tevent_context *ev,
tevent_req_poll(req, ev);
status = sock_daemon_run_recv(req, &ret);
- sockd->req = NULL;
TALLOC_FREE(req);
if (! status) {
return ret;
diff --git a/ctdb/common/sock_daemon.h b/ctdb/common/sock_daemon.h
index 6c474ac..81853f6 100644
--- a/ctdb/common/sock_daemon.h
+++ b/ctdb/common/sock_daemon.h
@@ -50,12 +50,24 @@ struct sock_client_context;
* startup() is called when the daemon starts running
* either via sock_daemon_run() or via sock_daemon_run_send()
* reconfigure() is called when process receives SIGUSR1 or SIGHUP
- * shutdown() is called when process receives SIGINT or SIGTERM
+ * shutdown() is called when process receives SIGINT or SIGTERM or
+ * when wait computation has finished
+ *
+ * wait_send() starts the async computation to keep running the daemon
+ * wait_recv() ends the async computation to keep running the daemon
+ *
+ * If wait_send()/wait_recv() is NULL, then daemon will keep running forever.
+ * If wait_send() returns req, then when req is over, daemon will shutdown.
*/
struct sock_daemon_funcs {
void (*startup)(void *private_data);
void (*reconfigure)(void *private_data);
void (*shutdown)(void *private_data);
+
+ struct tevent_req * (*wait_send)(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ void *private_data);
+ bool (*wait_recv)(struct tevent_req *req, int *perr);
};
/**
diff --git a/ctdb/tests/cunit/sock_daemon_test_001.sh b/ctdb/tests/cunit/sock_daemon_test_001.sh
index 036b6ac..72e5532 100755
--- a/ctdb/tests/cunit/sock_daemon_test_001.sh
+++ b/ctdb/tests/cunit/sock_daemon_test_001.sh
@@ -47,6 +47,7 @@ unit_test sock_daemon_test "$pidfile" "$sockpath" 3
ok <<EOF
test4[PID]: daemon started, pid=PID
+test4[PID]: Shutting down
EOF
unit_test sock_daemon_test "$pidfile" "$sockpath" 4
@@ -61,5 +62,6 @@ unit_test sock_daemon_test "$pidfile" "$sockpath" 5
ok <<EOF
test6[PID]: listening on $sockpath
test6[PID]: daemon started, pid=PID
+test6[PID]: Shutting down
EOF
unit_test sock_daemon_test "$pidfile" "$sockpath" 6
diff --git a/ctdb/tests/src/sock_daemon_test.c b/ctdb/tests/src/sock_daemon_test.c
index 4a085c0..278dcab 100644
--- a/ctdb/tests/src/sock_daemon_test.c
+++ b/ctdb/tests/src/sock_daemon_test.c
@@ -254,17 +254,68 @@ static void test3(TALLOC_CTX *mem_ctx, const char *pidfile,
assert(ret == -1);
}
-static void test4_handler(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval curtime,
- void *private_data)
+struct test4_wait_state {
+};
+
+static void test4_wait_done(struct tevent_req *subreq);
+
+static struct tevent_req *test4_wait_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ void *private_data)
{
- struct sock_daemon_context *sockd = talloc_get_type_abort(
- private_data, struct sock_daemon_context);
+ struct tevent_req *req, *subreq;
+ struct test4_wait_state *state;
- talloc_free(sockd);
+ req = tevent_req_create(mem_ctx, &state, struct test4_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, test4_wait_done, req);
+
+ return req;
}
+static void test4_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);
+ TALLOC_FREE(subreq);
+
+ if (! status) {
+ tevent_req_error(req, EIO);
+ } else {
+ tevent_req_done(req);
+ }
+}
+
+static bool test4_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 test4_funcs = {
+ .wait_send = test4_wait_send,
+ .wait_recv = test4_wait_recv,
+};
+
static void test4(TALLOC_CTX *mem_ctx, const char *pidfile,
const char *sockpath)
{
@@ -278,19 +329,14 @@ static void test4(TALLOC_CTX *mem_ctx, const char *pidfile,
if (pid == 0) {
struct tevent_context *ev;
struct sock_daemon_context *sockd;
- struct tevent_timer *te;
ev = tevent_context_init(mem_ctx);
assert(ev != NULL);
ret = sock_daemon_setup(mem_ctx, "test4", "file:", "NOTICE",
- NULL, NULL, NULL, &sockd);
+ pidfile, &test4_funcs, NULL, &sockd);
assert(ret == 0);
- te = tevent_add_timer(ev, ev, tevent_timeval_current_ofs(10,0),
- test4_handler, sockd);
- assert(te != NULL);
-
ret = sock_daemon_run(ev, sockd, -1);
assert(ret == 0);
@@ -666,7 +712,7 @@ static void test6_client(const char *sockpath)
struct test6_server_state {
struct sock_daemon_context *sockd;
- int done;
+ int fd, done;
};
struct test6_read_state {
@@ -752,35 +798,90 @@ static struct sock_socket_funcs test6_client_funcs = {
static void test6_startup(void *private_data)
{
- int fd = *(int *)private_data;
+ struct test6_server_state *server_state =
+ (struct test6_server_state *)private_data;
int ret = 1;
ssize_t nwritten;
- nwritten = write(fd, &ret, sizeof(ret));
+ nwritten = write(server_state->fd, &ret, sizeof(ret));
assert(nwritten == sizeof(ret));
- close(fd);
+ close(server_state->fd);
+ server_state->fd = -1;
}
-static struct sock_daemon_funcs test6_funcs = {
- .startup = test6_startup,
+struct test6_wait_state {
+ struct test6_server_state *server_state;
};
-static void test6_handler(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval curtime,
- void *private_data)
+static void test6_wait_done(struct tevent_req *subreq);
+
+static struct tevent_req *test6_wait_send(TALLOC_CTX *mem_ctx,
--
Samba Shared Repository
More information about the samba-cvs
mailing list