From 7e2b3ab14f84fb369a8fc00839feebd70b85426b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 Apr 2010 12:17:08 +1000 Subject: s4-repl: added a workaround for WERR_DS_DRA_NO_REPLICA DsReplicaSync errors The 0xc0002104/WERR_DS_DRA_NO_REPLICA seems to be spurious, and can be avoided by setting DRSUAPI_DRS_SYNC_ALL in the DsReplicaSync request. We need to investigate this further, and find out from MS why this is sometimes being sent, even when the target DC has the right repsFrom entries --- source4/dsdb/repl/drepl_notify.c | 19 +++++++++++++++++-- source4/dsdb/repl/drepl_service.h | 2 ++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/source4/dsdb/repl/drepl_notify.c b/source4/dsdb/repl/drepl_notify.c index 00075e8ca8..0145b2767a 100644 --- a/source4/dsdb/repl/drepl_notify.c +++ b/source4/dsdb/repl/drepl_notify.c @@ -120,6 +120,10 @@ static void dreplsrv_op_notify_replica_sync_trigger(struct tevent_req *req) DRSUAPI_DRS_ASYNC_OP | DRSUAPI_DRS_UPDATE_NOTIFICATION | DRSUAPI_DRS_WRIT_REP; + if (state->op->service->syncall_workaround) { + DEBUG(3,("sending DsReplicaSync with SYNC_ALL workaround\n")); + r->in.req->req1.options |= DRSUAPI_DRS_SYNC_ALL; + } if (state->op->is_urgent) { r->in.req->req1.options |= DRSUAPI_DRS_SYNC_URGENT; @@ -127,6 +131,10 @@ static void dreplsrv_op_notify_replica_sync_trigger(struct tevent_req *req) state->ndr_struct_ptr = r; + if (DEBUGLVL(10)) { + NDR_PRINT_IN_DEBUG(drsuapi_DsReplicaSync, r); + } + subreq = dcerpc_drsuapi_DsReplicaSync_r_send(state, state->ev, drsuapi->drsuapi_handle, @@ -185,10 +193,17 @@ static void dreplsrv_notify_op_callback(struct tevent_req *subreq) status = dreplsrv_op_notify_recv(subreq); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("dreplsrv_notify: Failed to send DsReplicaSync to %s for %s - %s\n", + WERROR werr; + werr = ntstatus_to_werror(status); + + DEBUG(0,("dreplsrv_notify: Failed to send DsReplicaSync to %s for %s - %s : %s\n", op->source_dsa->repsFrom1->other_info->dns_name, ldb_dn_get_linearized(op->source_dsa->partition->dn), - nt_errstr(status))); + nt_errstr(status), win_errstr(werr))); + if (W_ERROR_EQUAL(werr, WERR_DS_DRA_NO_REPLICA)) { + DEBUG(0,("Enabling SYNC_ALL workaround\n")); + op->service->syncall_workaround = true; + } } else { DEBUG(2,("dreplsrv_notify: DsReplicaSync OK for %s\n", op->source_dsa->repsFrom1->other_info->dns_name)); diff --git a/source4/dsdb/repl/drepl_service.h b/source4/dsdb/repl/drepl_service.h index 7813f92cbe..88be769128 100644 --- a/source4/dsdb/repl/drepl_service.h +++ b/source4/dsdb/repl/drepl_service.h @@ -213,6 +213,8 @@ struct dreplsrv_service { bool in_progress; struct dreplsrv_partition_source_dsa *rid_manager_source_dsa; } ridalloc; + + bool syncall_workaround; }; #include "dsdb/repl/drepl_out_helpers.h" -- cgit