[SCM] Samba Shared Repository - branch master updated
Martin Schwenke
martins at samba.org
Tue Nov 21 07:59:03 UTC 2017
The branch, master has been updated
via c1b4a74 ctdb-common: Add async version of shutdown in sock_daemon
via 41d888a ctdb-common: Add async version of reconfigure in sock_daemon
via 7558592 ctdb-common: Add async version of startup in sock_daemon
via ba3e9e6 ctdb-tests: Create sock_daemon_funcs per test
via 3b8f0cc ctdb-common: Handle errors on unexpected socket close in sock_daemon
via 984c3f4 ctdb-common: Start listening to sockets only on successful startup
via 001ae55 ctdb-common: Start wait computation only after successful startup
via fbb5ac8 ctdb-common: Return status from sock_daemon startup()/reconfigure()
via a6296ba ctdb-common: Do not use sock->req outside sock_socket functions
via 49308f7 ctdb-common: Call missing tevent_wakeup_recv() in sock_daemon
via 848f242 ctdb-daemon: Allocate deferred calls off calling context
via 757a120 s3: utils: net. Fix return paths that don't free talloc stackframe.
from 6e7d037 Fix formating of sources to be less than 80 lines
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit c1b4a74f272977ebdc735c040e976853c7ca800f
Author: Amitay Isaacs <amitay at gmail.com>
Date: Fri Nov 17 12:38:47 2017 +1100
ctdb-common: Add async version of shutdown in sock_daemon
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Martin Schwenke <martin at meltin.net>
Autobuild-User(master): Martin Schwenke <martins at samba.org>
Autobuild-Date(master): Tue Nov 21 08:58:45 CET 2017 on sn-devel-144
commit 41d888afbecfca6e4ea3c6c86c05101bd5e5b5c4
Author: Amitay Isaacs <amitay at gmail.com>
Date: Fri Nov 17 12:38:18 2017 +1100
ctdb-common: Add async version of reconfigure in sock_daemon
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Martin Schwenke <martin at meltin.net>
commit 7558592d15fa4911fa8d2061aa56e2b151f516a2
Author: Amitay Isaacs <amitay at gmail.com>
Date: Fri Nov 17 12:36:29 2017 +1100
ctdb-common: Add async version of startup in sock_daemon
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Martin Schwenke <martin at meltin.net>
commit ba3e9e6eae62af0ee991945206e0ef2b3dba8acf
Author: Amitay Isaacs <amitay at gmail.com>
Date: Fri Nov 17 13:11:12 2017 +1100
ctdb-tests: Create sock_daemon_funcs per test
This avoids defining sock_daemon functions that are not needed in the test.
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Martin Schwenke <martin at meltin.net>
commit 3b8f0cc21dd18e84ee78d0450d6f89435abf8dc1
Author: Amitay Isaacs <amitay at gmail.com>
Date: Fri Nov 17 12:31:16 2017 +1100
ctdb-common: Handle errors on unexpected socket close in sock_daemon
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Martin Schwenke <martin at meltin.net>
commit 984c3f4f66846fb05fbbbc0cb4d2a3d2cacb6444
Author: Amitay Isaacs <amitay at gmail.com>
Date: Fri Nov 10 12:15:45 2017 +1100
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 <amitay at gmail.com>
Reviewed-by: Martin Schwenke <martin at meltin.net>
commit 001ae55011d9c0596f398dc374efc84637f1590c
Author: Amitay Isaacs <amitay at gmail.com>
Date: Fri Nov 17 10:52:57 2017 +1100
ctdb-common: Start wait computation only after successful startup
This orders the startup events in sock_daemon code.
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Martin Schwenke <martin at meltin.net>
commit fbb5ac8404525a0828504cd744992dfcb7c8e216
Author: Amitay Isaacs <amitay at gmail.com>
Date: Fri Nov 10 12:10:05 2017 +1100
ctdb-common: Return status from sock_daemon startup()/reconfigure()
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Martin Schwenke <martin at meltin.net>
commit a6296bad87ac16cb0a39d35aa8cf0db2f85ec0d3
Author: Amitay Isaacs <amitay at gmail.com>
Date: Mon Nov 20 11:52:55 2017 +1100
ctdb-common: Do not use sock->req outside sock_socket functions
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Martin Schwenke <martin at meltin.net>
commit 49308f7f22f3d6fa05cc81fdef3db020e503fa9f
Author: Amitay Isaacs <amitay at gmail.com>
Date: Fri Nov 10 12:18:01 2017 +1100
ctdb-common: Call missing tevent_wakeup_recv() in sock_daemon
https://bugzilla.samba.org/show_bug.cgi?id=13153
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Martin Schwenke <martin at meltin.net>
commit 848f2425984667c243ccac847b8f48a66ce10178
Author: Amitay Isaacs <amitay at gmail.com>
Date: Thu Oct 19 14:58:18 2017 +1100
ctdb-daemon: Allocate deferred calls off calling context
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13152
This makes sure that if a client disconnects, all the deferred calls
from the client are correctly freed.
Signed-off-by: Amitay Isaacs <amitay at gmail.com>
Reviewed-by: Martin Schwenke <martin at meltin.net>
commit 757a120fc4c659047bd6a1175b24f0673630ce2d
Author: Jeremy Allison <jra at samba.org>
Date: Tue Nov 21 00:09:39 2017 +0000
s3: utils: net. Fix return paths that don't free talloc stackframe.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13151
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Martin Schwenke <martin at meltin.net>
-----------------------------------------------------------------------
Summary of changes:
ctdb/common/sock_daemon.c | 271 ++++++++++++++++---
ctdb/common/sock_daemon.h | 41 ++-
ctdb/server/ctdb_call.c | 14 +-
ctdb/tests/cunit/sock_daemon_test_001.sh | 33 ++-
ctdb/tests/src/sock_daemon_test.c | 449 +++++++++++++++++++++++++++----
source3/utils/net_usershare.c | 5 +-
6 files changed, 707 insertions(+), 106 deletions(-)
Changeset truncated at 500 lines:
diff --git a/ctdb/common/sock_daemon.c b/ctdb/common/sock_daemon.c
index ba171af..7554cd6 100644
--- a/ctdb/common/sock_daemon.c
+++ b/ctdb/common/sock_daemon.c
@@ -265,7 +265,11 @@ static int sock_socket_init(TALLOC_CTX *mem_ctx, const char *sockpath,
return ENOMEM;
}
- sock->sockpath = sockpath;
+ sock->sockpath = talloc_strdup(sock, sockpath);
+ if (sock->sockpath == NULL) {
+ talloc_free(sock);
+ return ENOMEM;
+ }
sock->funcs = funcs;
sock->private_data = private_data;
sock->fd = -1;
@@ -278,6 +282,8 @@ static int sock_socket_init(TALLOC_CTX *mem_ctx, const char *sockpath,
static int sock_socket_destructor(struct sock_socket *sock)
{
+ TALLOC_FREE(sock->req);
+
if (sock->fd != -1) {
close(sock->fd);
sock->fd = -1;
@@ -331,6 +337,8 @@ static struct tevent_req *sock_socket_start_send(TALLOC_CTX *mem_ctx,
}
tevent_req_set_callback(subreq, sock_socket_start_new_client, req);
+ sock->req = req;
+
return req;
}
@@ -401,7 +409,8 @@ static int sock_socket_start_client_destructor(struct sock_client *client)
return 0;
}
-static bool sock_socket_start_recv(struct tevent_req *req, int *perr)
+static bool sock_socket_start_recv(struct tevent_req *req, int *perr,
+ TALLOC_CTX *mem_ctx, const char **sockpath)
{
struct sock_socket_start_state *state = tevent_req_data(
req, struct sock_socket_start_state);
@@ -416,6 +425,10 @@ static bool sock_socket_start_recv(struct tevent_req *req, int *perr)
return false;
}
+ if (sockpath != NULL) {
+ *sockpath = talloc_steal(mem_ctx, state->sock->sockpath);
+ }
+
return true;
}
@@ -511,17 +524,24 @@ struct sock_daemon_run_state {
pid_t pid_watch;
int fd;
+ int exit_code;
};
static void sock_daemon_run_started(struct tevent_req *subreq);
+static void sock_daemon_run_startup_done(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_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);
+static void sock_daemon_run_wait(struct tevent_req *req);
static void sock_daemon_run_wait_done(struct tevent_req *subreq);
struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx,
@@ -534,8 +554,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);
@@ -552,7 +570,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;
@@ -591,18 +608,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);
-
- sock->req = subreq;
- }
-
if (pid_watch > 1) {
subreq = tevent_wakeup_send(state, ev,
tevent_timeval_current_ofs(1,0));
@@ -613,33 +618,84 @@ struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx,
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);
+ return req;
+}
+
+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_run_state *state = tevent_req_data(
+ req, struct sock_daemon_run_state);
+ struct sock_daemon_context *sockd = state->sockd;
+ bool status;
+
+ status = tevent_wakeup_recv(subreq);
+ TALLOC_FREE(subreq);
+ if (! status) {
+ tevent_req_error(req, EIO);
+ return;
+ }
+
+ D_NOTICE("daemon started, pid=%u\n", getpid());
+
+ if (sockd->funcs != NULL && sockd->funcs->startup_send != NULL &&
+ sockd->funcs->startup_recv != NULL) {
+ subreq = sockd->funcs->startup_send(state, state->ev,
+ sockd->private_data);
if (tevent_req_nomem(subreq, req)) {
- return tevent_req_post(req, ev);
+ return;
}
- tevent_req_set_callback(subreq, sock_daemon_run_wait_done,
+ tevent_req_set_callback(subreq, sock_daemon_run_startup_done,
req);
+ return;
}
- return req;
+ if (sockd->funcs != NULL && sockd->funcs->startup != NULL) {
+ int ret;
+
+ ret = sockd->funcs->startup(sockd->private_data);
+ if (ret != 0) {
+ D_ERR("startup failed, ret=%d\n", ret);
+ tevent_req_error(req, EIO);
+ return;
+ }
+
+ D_NOTICE("startup completed successfully\n");
+ }
+
+ status = sock_daemon_run_socket_listen(req);
+ if (! status) {
+ return;
+ }
+ sock_daemon_run_wait(req);
}
-static void sock_daemon_run_started(struct tevent_req *subreq)
+static void sock_daemon_run_startup_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;
- D_NOTICE("daemon started, pid=%u\n", getpid());
+ status = sockd->funcs->startup_recv(subreq, &ret);
+ TALLOC_FREE(subreq);
+ if (! status) {
+ D_ERR("startup failed, ret=%d\n", ret);
+ tevent_req_error(req, EIO);
+ return;
+ }
- if (sockd->funcs != NULL && sockd->funcs->startup != NULL) {
- sockd->funcs->startup(sockd->private_data);
+ D_NOTICE("startup completed succesfully\n");
+
+ status = sock_daemon_run_socket_listen(req);
+ if (! status) {
+ return;
}
+ sock_daemon_run_wait(req);
}
static void sock_daemon_run_signal_handler(struct tevent_context *ev,
@@ -649,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);
@@ -658,24 +716,66 @@ 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);
}
}
static void sock_daemon_run_reconfigure(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;
+ if (sockd->funcs != NULL && sockd->funcs->reconfigure_send != NULL &&
+ sockd->funcs->reconfigure_recv != NULL) {
+ subreq = sockd->funcs->reconfigure_send(state, state->ev,
+ sockd->private_data);
+ if (tevent_req_nomem(subreq, req)) {
+ return;
+ }
+ tevent_req_set_callback(subreq,
+ sock_daemon_run_reconfigure_done, req);
+ return;
+ }
+
if (sockd->funcs != NULL && sockd->funcs->reconfigure != NULL) {
- sockd->funcs->reconfigure(sockd->private_data);
+ int ret;
+
+ ret = sockd->funcs->reconfigure(sockd->private_data);
+ if (ret != 0) {
+ D_ERR("reconfigure failed, ret=%d\n", ret);
+ return;
+ }
+
+ D_NOTICE("reconfigure completed successfully\n");
+ }
+}
+
+static void sock_daemon_run_reconfigure_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->reconfigure_recv(subreq, &ret);
+ TALLOC_FREE(subreq);
+ if (! status) {
+ D_ERR("reconfigure failed, ret=%d\n", ret);
+ return;
}
+
+ D_NOTICE("reconfigure completed successfully\n");
}
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;
@@ -685,32 +785,103 @@ static void sock_daemon_run_shutdown(struct tevent_req *req)
while ((sock = sockd->socket_list) != NULL) {
DLIST_REMOVE(sockd->socket_list, sock);
- TALLOC_FREE(sock->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)
+{
+ 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(
subreq, struct tevent_req);
+ struct sock_daemon_run_state *state = tevent_req_data(
+ req, struct sock_daemon_run_state);
+ const char *sockpath = NULL;
int ret = 0;
bool status;
- status = sock_socket_start_recv(subreq, &ret);
+ status = sock_socket_start_recv(subreq, &ret, state, &sockpath);
TALLOC_FREE(subreq);
- sock_daemon_run_shutdown(req);
if (! status) {
- tevent_req_error(req, ret);
+ D_ERR("socket %s closed unexpectedly\n", sockpath);
+ 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)
@@ -733,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",
@@ -750,6 +921,25 @@ static void sock_daemon_run_watch_pid(struct tevent_req *subreq)
tevent_req_set_callback(subreq, sock_daemon_run_watch_pid, req);
}
+static void sock_daemon_run_wait(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;
+
+ if (sockd->funcs != NULL && sockd->funcs->wait_send != NULL &&
+ sockd->funcs->wait_recv != NULL) {
+ subreq = sockd->funcs->wait_send(state, state->ev,
+ sockd->private_data);
+ if (tevent_req_nomem(subreq, req)) {
+ return;
+ }
+ tevent_req_set_callback(subreq, sock_daemon_run_wait_done,
+ req);
+ }
+}
+
static void sock_daemon_run_wait_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
@@ -757,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)
diff --git a/ctdb/common/sock_daemon.h b/ctdb/common/sock_daemon.h
index 1821028..a071833 100644
--- a/ctdb/common/sock_daemon.h
+++ b/ctdb/common/sock_daemon.h
@@ -48,11 +48,27 @@ struct sock_client_context;
* @brief The callback routines called during daemon life cycle
*
* 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
+ * either via sock_daemon_run() or via sock_daemon_run_send()
+ * startup() should return 0 for success, non-zero value on failure
+ * On failure, sock_daemon_run() will return error.
+ *
+ * startup_send()/startup_recv() is the async version of startup()
+ *
+ * reconfigure() is called when the daemon receives SIGUSR1 or SIGHUP
+ * reconfigure() should return 0 for success, non-zero value on failure
+ * On failure, sock_daemon_run() will continue to run.
+ *
+ * reconfigure_send()/reconfigure_recv() is the async version of reconfigure()
+ *
* 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
*
@@ -60,10 +76,27 @@ struct sock_client_context;
* 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);
+ int (*startup)(void *private_data);
--
Samba Shared Repository
More information about the samba-cvs
mailing list