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 <ami...@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 <ami...@gmail.com>
    Reviewed-by: Stefan Metzmacher <me...@samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <me...@samba.org>
    Autobuild-Date(master): Mon Jan 16 21:16:51 CET 2017 on sn-devel-144

commit d09469e575233242eab2a8c1c0767f52e7cad1e5
Author: Amitay Isaacs <ami...@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 <ami...@gmail.com>
    Reviewed-by: Stefan Metzmacher <me...@samba.org>

commit d5be55725000eb34611dc76a2e8e7188eea2503f
Author: Amitay Isaacs <ami...@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 <ami...@gmail.com>
    Reviewed-by: Stefan Metzmacher <me...@samba.org>

commit 31274cf7aec1bb26e8dac0dbd1b9a3fa799b2b85
Author: Amitay Isaacs <ami...@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 <ami...@gmail.com>
    Reviewed-by: Stefan Metzmacher <me...@samba.org>

commit 9e09a253b4ca1b5f9aa432c986c1755a173a9566
Author: Amitay Isaacs <ami...@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 <ami...@gmail.com>
    Reviewed-by: Stefan Metzmacher <me...@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

Reply via email to