diff options
author | Andrew Bartlett <abartlet@samba.org> | 2015-02-18 16:42:09 +1300 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2015-05-28 07:25:07 +0200 |
commit | 86943313f22627b8e35f04e7d29bd22acfd587af (patch) | |
tree | a4fc147611555b073f663bc74bfdeb7dc7fff18b /source4/dsdb/kcc | |
parent | ce4830e00a62b16adc344107e2d5dc5e85588be3 (diff) | |
download | samba-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.c | 5 | ||||
-rw-r--r-- | source4/dsdb/kcc/kcc_service.c | 105 |
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) |