summaryrefslogtreecommitdiff
path: root/source4/dsdb/kcc
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2015-02-18 16:42:09 +1300
committerAndrew Bartlett <abartlet@samba.org>2015-05-28 07:25:07 +0200
commit86943313f22627b8e35f04e7d29bd22acfd587af (patch)
treea4fc147611555b073f663bc74bfdeb7dc7fff18b /source4/dsdb/kcc
parentce4830e00a62b16adc344107e2d5dc5e85588be3 (diff)
downloadsamba-86943313f22627b8e35f04e7d29bd22acfd587af.tar.gz
kcc: Wait until the samba_kcc script runs to declare success to the caller
This allows us to tell if this script even executes, without looking in the logs. Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Garming Sam <garming@catalyst.net.nz>
Diffstat (limited to 'source4/dsdb/kcc')
-rw-r--r--source4/dsdb/kcc/kcc_periodic.c5
-rw-r--r--source4/dsdb/kcc/kcc_service.c105
2 files changed, 100 insertions, 10 deletions
diff --git a/source4/dsdb/kcc/kcc_periodic.c b/source4/dsdb/kcc/kcc_periodic.c
index 0e84e422d5f..7fdbea74e66 100644
--- a/source4/dsdb/kcc/kcc_periodic.c
+++ b/source4/dsdb/kcc/kcc_periodic.c
@@ -606,7 +606,7 @@ static void kccsrv_periodic_run(struct kccsrv_service *service)
mem_ctx = talloc_new(service);
if (service->samba_kcc_code)
- status = kccsrv_samba_kcc(service, mem_ctx);
+ status = kccsrv_samba_kcc(service);
else {
status = kccsrv_simple_update(service, mem_ctx);
if (!NT_STATUS_IS_OK(status))
@@ -651,8 +651,7 @@ static void samba_kcc_done(struct tevent_req *subreq)
/* Invocation of the samba_kcc python script for replication
* topology generation.
*/
-NTSTATUS kccsrv_samba_kcc(struct kccsrv_service *service,
- TALLOC_CTX *ctxp)
+NTSTATUS kccsrv_samba_kcc(struct kccsrv_service *service)
{
NTSTATUS status = NT_STATUS_OK;
const char * const *samba_kcc_command =
diff --git a/source4/dsdb/kcc/kcc_service.c b/source4/dsdb/kcc/kcc_service.c
index 8b35d6f01a5..2c1a92261aa 100644
--- a/source4/dsdb/kcc/kcc_service.c
+++ b/source4/dsdb/kcc/kcc_service.c
@@ -141,25 +141,116 @@ static WERROR kccsrv_load_partitions(struct kccsrv_service *s)
return WERR_OK;
}
+
+struct kcc_manual_runcmd_state {
+ struct irpc_message *msg;
+ struct drsuapi_DsExecuteKCC *r;
+ struct kccsrv_service *service;
+};
+
+
+/*
+ * Called when samba_kcc script has finished
+ */
+static void manual_samba_kcc_done(struct tevent_req *subreq)
+{
+ struct kcc_manual_runcmd_state *st =
+ tevent_req_callback_data(subreq,
+ struct kcc_manual_runcmd_state);
+ int rc;
+ int sys_errno;
+ NTSTATUS status;
+
+ st->service->periodic.subreq = NULL;
+
+ rc = samba_runcmd_recv(subreq, &sys_errno);
+ TALLOC_FREE(subreq);
+
+ if (rc != 0) {
+ status = map_nt_error_from_unix_common(sys_errno);
+ } else {
+ status = NT_STATUS_OK;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,(__location__ ": Failed manual run of samba_kcc - %s\n",
+ nt_errstr(status)));
+ } else {
+ DEBUG(3,("Completed manual run of samba_kcc OK\n"));
+ }
+
+ if (!(st->r->in.req->ctr1.flags & DRSUAPI_DS_EXECUTE_KCC_ASYNCHRONOUS_OPERATION)) {
+ irpc_send_reply(st->msg, status);
+ }
+}
+
static NTSTATUS kccsrv_execute_kcc(struct irpc_message *msg, struct drsuapi_DsExecuteKCC *r)
{
TALLOC_CTX *mem_ctx;
NTSTATUS status = NT_STATUS_OK;
struct kccsrv_service *service = talloc_get_type(msg->private_data, struct kccsrv_service);
- mem_ctx = talloc_new(service);
+ const char * const *samba_kcc_command;
+ struct kcc_manual_runcmd_state *st;
+
+ if (!service->samba_kcc_code) {
+ mem_ctx = talloc_new(service);
- if (service->samba_kcc_code)
- status = kccsrv_samba_kcc(service, mem_ctx);
- else {
status = kccsrv_simple_update(service, mem_ctx);
- if (!NT_STATUS_IS_OK(status))
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("kccsrv_execute_kcc failed - %s\n",
nt_errstr(status)));
+ }
+ talloc_free(mem_ctx);
+
+ return NT_STATUS_OK;
+ }
+
+ /* Invocation of the samba_kcc python script for replication
+ * topology generation.
+ */
+
+ samba_kcc_command =
+ lpcfg_samba_kcc_command(service->task->lp_ctx);
+
+ st = talloc(msg, struct kcc_manual_runcmd_state);
+ if (st == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ st->msg = msg;
+ st->r = r;
+ st->service = service;
+
+ /* don't run at the same time as an existing child */
+ if (service->periodic.subreq) {
+ status = NT_STATUS_DS_BUSY;
+ return status;
+ }
+
+ DEBUG(2, ("Calling samba_kcc script\n"));
+ service->periodic.subreq = samba_runcmd_send(service,
+ service->task->event_ctx,
+ timeval_current_ofs(40, 0),
+ 2, 0, samba_kcc_command, NULL);
+
+ if (service->periodic.subreq == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ DEBUG(0,(__location__ ": failed - %s\n", nt_errstr(status)));
+ return status;
+ } else {
+ tevent_req_set_callback(service->periodic.subreq,
+ manual_samba_kcc_done, st);
+ }
+
+ if (r->in.req->ctr1.flags & DRSUAPI_DS_EXECUTE_KCC_ASYNCHRONOUS_OPERATION) {
+ /* This actually means reply right away, let it run in the background */
+ } else {
+ /* mark the request as replied async, the caller wants to know when this is finished */
+ msg->defer_reply = true;
}
+ return status;
- talloc_free(mem_ctx);
- return NT_STATUS_OK;
}
static NTSTATUS kccsrv_replica_get_info(struct irpc_message *msg, struct drsuapi_DsReplicaGetInfo *r)