The branch, master has been updated
       via  e64e398 s4-dreplsrv: Run NC replication synchronously if requested
       via  3f109f8 s4-drs: Dump exact error when failure occurs during 
DsReplicaUpdateRefs call
      from  7612760 s3: Prune the printername cache when a printer is deleted

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit e64e3985688e57a882e0e128b256ec5f84c6f67a
Author: Kamen Mazdrashki <kame...@samba.org>
Date:   Tue Sep 7 17:00:20 2010 +0300

    s4-dreplsrv: Run NC replication synchronously if requested

commit 3f109f8fd7bdd2cc691beb78463fba7a469e2a3d
Author: Kamen Mazdrashki <kame...@samba.org>
Date:   Mon Sep 6 14:33:14 2010 +0300

    s4-drs: Dump exact error when failure occurs during DsReplicaUpdateRefs call

-----------------------------------------------------------------------

Summary of changes:
 source4/dsdb/repl/drepl_service.c       |  149 ++++++++++++++++++++++++------
 source4/rpc_server/drsuapi/updaterefs.c |   16 ++--
 2 files changed, 129 insertions(+), 36 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/repl/drepl_service.c 
b/source4/dsdb/repl/drepl_service.c
index 5babbcb..7d4a88c 100644
--- a/source4/dsdb/repl/drepl_service.c
+++ b/source4/dsdb/repl/drepl_service.c
@@ -34,6 +34,21 @@
 #include "librpc/gen_ndr/ndr_irpc.h"
 #include "param/param.h"
 
+/**
+ * Call-back data for _drepl_replica_sync_done_cb()
+ */
+struct drepl_replica_sync_cb_data {
+       struct irpc_message *msg;
+       struct drsuapi_DsReplicaSync *r;
+
+       /* number of ops left to be completed */
+       int ops_count;
+
+       /* last failure error code */
+       WERROR werr_last_failure;
+};
+
+
 static WERROR dreplsrv_init_creds(struct dreplsrv_service *service)
 {
        service->system_session_info = system_session(service->task->lp_ctx);
@@ -104,6 +119,92 @@ static WERROR dreplsrv_connect_samdb(struct 
dreplsrv_service *service, struct lo
 }
 
 
+/**
+ * Callback for dreplsrv_out_operation operation completion.
+ *
+ * We just need to complete a waiting IRPC message here.
+ * In case pull operation has failed,
+ * caller of this callback will dump
+ * failure information.
+ *
+ * NOTE: cb_data is allocated in IRPC msg's context
+ * and will be freed during irpc_send_reply() call.
+ */
+static void _drepl_replica_sync_done_cb(struct dreplsrv_service *service,
+                                       WERROR werr,
+                                       enum drsuapi_DsExtendedError ext_err,
+                                       void *cb_data)
+{
+       struct drepl_replica_sync_cb_data *data = talloc_get_type(cb_data,
+                                                                 struct 
drepl_replica_sync_cb_data);
+       struct irpc_message *msg = data->msg;
+       struct drsuapi_DsReplicaSync *r = data->r;
+
+       /* store last bad result */
+       if (W_ERROR_IS_OK(werr)) {
+               data->werr_last_failure = werr;
+       }
+
+       /* decrement pending ops count */
+       data->ops_count--;
+
+       if (data->ops_count == 0) {
+               /* Return result to client */
+               r->out.result = data->werr_last_failure;
+
+               /* complete IRPC message */
+               irpc_send_reply(msg, NT_STATUS_OK);
+       }
+}
+
+/**
+ * Helper to schedule a replication operation with a source DSA.
+ * If 'data' is valid pointer, then a callback
+ * for the operation is passed and 'data->msg' is
+ * marked as 'deferred' - defer_reply = true
+ */
+static WERROR _drepl_schedule_replication(struct dreplsrv_service *service,
+                                         struct dreplsrv_partition_source_dsa 
*dsa,
+                                         struct 
drsuapi_DsReplicaObjectIdentifier *nc,
+                                         struct drepl_replica_sync_cb_data 
*data,
+                                         TALLOC_CTX *mem_ctx)
+{
+       WERROR werr;
+       dreplsrv_fsmo_callback_t fn_callback = NULL;
+
+       if (data) {
+               fn_callback = _drepl_replica_sync_done_cb;
+       }
+
+       /* schedule replication item */
+       werr = dreplsrv_schedule_partition_pull_source(service, dsa,
+                                                      DRSUAPI_EXOP_NONE, 0,
+                                                      fn_callback, data);
+       if (!W_ERROR_IS_OK(werr)) {
+               DEBUG(0,("%s: failed setup of sync of partition (%s, %s, %s) - 
%s\n",
+                        __FUNCTION__,
+                        GUID_string(mem_ctx, &nc->guid),
+                        nc->dn,
+                        dsa->repsFrom1->other_info->dns_name,
+                        win_errstr(werr)));
+               return werr;
+       }
+       /* log we've scheduled a replication item */
+       DEBUG(3,("%s: forcing sync of partition (%s, %s, %s)\n",
+                __FUNCTION__,
+                GUID_string(mem_ctx, &nc->guid),
+                nc->dn,
+                dsa->repsFrom1->other_info->dns_name));
+
+       /* mark IRPC message as deferred if necessary */
+       if (data) {
+               data->ops_count++;
+               data->msg->defer_reply = true;
+       }
+
+       return WERR_OK;
+}
+
 /*
   DsReplicaSync messages from the DRSUAPI server are forwarded here
  */
@@ -112,6 +213,7 @@ static NTSTATUS drepl_replica_sync(struct irpc_message *msg,
 {
        WERROR werr;
        struct dreplsrv_partition *p;
+       struct drepl_replica_sync_cb_data *cb_data;
        struct dreplsrv_partition_source_dsa *dsa;
        struct drsuapi_DsReplicaSyncRequest1 *req1;
        struct drsuapi_DsReplicaObjectIdentifier *nc;
@@ -147,28 +249,29 @@ static NTSTATUS drepl_replica_sync(struct irpc_message 
*msg,
                REPLICA_SYNC_FAIL(werr);
        }
 
+       /* should we process it asynchronously? */
+       if (req1->options & DRSUAPI_DRS_ASYNC_OP) {
+               cb_data = NULL;
+       } else {
+               cb_data = talloc_zero(msg, struct drepl_replica_sync_cb_data);
+               if (!cb_data) {
+                       DEBUG(0,(__location__ ": Not enought memory!"));
+                       REPLICA_SYNC_FAIL(WERR_DS_DRA_INTERNAL_ERROR);
+               }
+
+               cb_data->msg = msg;
+               cb_data->r   = r;
+               cb_data->werr_last_failure = WERR_OK;
+       }
+
        /* collect source DSAs to sync with */
        if (req1->options & DRSUAPI_DRS_SYNC_ALL) {
                for (dsa = p->sources; dsa; dsa = dsa->next) {
                        /* schedule replication item */
-                       werr = dreplsrv_schedule_partition_pull_source(service, 
dsa,
-                                                                      
DRSUAPI_EXOP_NONE, 0,
-                                                                      NULL, 
NULL);
+                       werr = _drepl_schedule_replication(service, dsa, nc, 
cb_data, msg);
                        if (!W_ERROR_IS_OK(werr)) {
-                               DEBUG(0,("%s: failed setup of sync of partition 
(%s, %s, %s) - %s\n",
-                                        __FUNCTION__,
-                                        GUID_string(msg, &nc->guid),
-                                        nc->dn,
-                                        dsa->repsFrom1->other_info->dns_name,
-                                        win_errstr(werr)));
                                REPLICA_SYNC_FAIL(werr);
                        }
-                       /* log we've scheduled replication item */
-                       DEBUG(3,("%s: forcing sync of partition (%s, %s, %s)\n",
-                                __FUNCTION__,
-                                GUID_string(msg, &nc->guid),
-                                nc->dn,
-                                dsa->repsFrom1->other_info->dns_name));
                }
        } else {
                if (req1->options & DRSUAPI_DRS_SYNC_BYNAME) {
@@ -201,24 +304,10 @@ static NTSTATUS drepl_replica_sync(struct irpc_message 
*msg,
                }
 
                /* schedule replication item */
-               werr = dreplsrv_schedule_partition_pull_source(service, dsa,
-                                                              
DRSUAPI_EXOP_NONE, 0,
-                                                              NULL, NULL);
+               werr = _drepl_schedule_replication(service, dsa, nc, cb_data, 
msg);
                if (!W_ERROR_IS_OK(werr)) {
-                       DEBUG(0,("%s: failed setup of sync of partition (%s, 
%s, %s) - %s\n",
-                                __FUNCTION__,
-                                GUID_string(msg, &nc->guid),
-                                nc->dn,
-                                dsa->repsFrom1->other_info->dns_name,
-                                win_errstr(werr)));
                        REPLICA_SYNC_FAIL(werr);
                }
-               /* log we've scheduled replication item */
-               DEBUG(3,("%s: forcing sync of partition (%s, %s, %s)\n",
-                        __FUNCTION__,
-                        GUID_string(msg, &nc->guid),
-                        nc->dn,
-                        dsa->repsFrom1->other_info->dns_name));
        }
 
        /* if we got here, everything is OK */
diff --git a/source4/rpc_server/drsuapi/updaterefs.c 
b/source4/rpc_server/drsuapi/updaterefs.c
index e911838..8efdfbb 100644
--- a/source4/rpc_server/drsuapi/updaterefs.c
+++ b/source4/rpc_server/drsuapi/updaterefs.c
@@ -136,15 +136,17 @@ WERROR drsuapi_UpdateRefs(struct drsuapi_bind_state 
*b_state, TALLOC_CTX *mem_ct
        }
 
        if (ldb_transaction_start(b_state->sam_ctx) != LDB_SUCCESS) {
-               DEBUG(0,(__location__ ": Failed to start transaction on 
samdb\n"));
+               DEBUG(0,(__location__ ": Failed to start transaction on samdb: 
%s\n",
+                        ldb_errstring(b_state->sam_ctx)));
                return WERR_DS_DRA_INTERNAL_ERROR;              
        }
 
        if (req->options & DRSUAPI_DRS_DEL_REF) {
                werr = uref_del_dest(b_state->sam_ctx, mem_ctx, dn, 
&req->dest_dsa_guid, req->options);
                if (!W_ERROR_IS_OK(werr)) {
-                       DEBUG(0,("Failed to delete repsTo for %s\n",
-                                GUID_string(mem_ctx, &req->dest_dsa_guid)));
+                       DEBUG(0,("Failed to delete repsTo for %s: %s\n",
+                                GUID_string(mem_ctx, &req->dest_dsa_guid),
+                                win_errstr(werr)));
                        goto failed;
                }
        }
@@ -163,14 +165,16 @@ WERROR drsuapi_UpdateRefs(struct drsuapi_bind_state 
*b_state, TALLOC_CTX *mem_ct
 
                werr = uref_add_dest(b_state->sam_ctx, mem_ctx, dn, &dest, 
req->options);
                if (!W_ERROR_IS_OK(werr)) {
-                       DEBUG(0,("Failed to add repsTo for %s\n",
-                                GUID_string(mem_ctx, 
&dest.source_dsa_obj_guid)));
+                       DEBUG(0,("Failed to add repsTo for %s: %s\n",
+                                GUID_string(mem_ctx, 
&dest.source_dsa_obj_guid),
+                                win_errstr(werr)));
                        goto failed;
                }
        }
 
        if (ldb_transaction_commit(b_state->sam_ctx) != LDB_SUCCESS) {
-               DEBUG(0,(__location__ ": Failed to commit transaction on 
samdb\n"));
+               DEBUG(0,(__location__ ": Failed to commit transaction on samdb: 
%s\n",
+                        ldb_errstring(b_state->sam_ctx)));
                return WERR_DS_DRA_INTERNAL_ERROR;              
        }
 


-- 
Samba Shared Repository

Reply via email to