[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