[SCM] Samba Shared Repository - branch master updated

Kamen Mazdrashki kamenim at samba.org
Tue Sep 7 11:46:53 MDT 2010


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 <kamenim at samba.org>
Date:   Tue Sep 7 17:00:20 2010 +0300

    s4-dreplsrv: Run NC replication synchronously if requested

commit 3f109f8fd7bdd2cc691beb78463fba7a469e2a3d
Author: Kamen Mazdrashki <kamenim at 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


More information about the samba-cvs mailing list