kcc: Wait until the samba_kcc script runs to declare success to the caller
authorAndrew Bartlett <abartlet@samba.org>
Wed, 18 Feb 2015 03:42:09 +0000 (16:42 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 28 May 2015 05:25:07 +0000 (07:25 +0200)
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>
source4/dsdb/kcc/kcc_periodic.c
source4/dsdb/kcc/kcc_service.c

index 0e84e422d5fe4b6ec3782002898e963cfa264e4f..7fdbea74e66349dd399342fa238ee0e998c7f68a 100644 (file)
@@ -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 =
index 8b35d6f01a52a470de289da743101d26573a1c93..2c1a92261aacf26488d96410f30c197ec69f55b2 100644 (file)
@@ -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)