From 6c8b0d7f2784faf68d08d42227765bdc0ce28b35 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Nov 2010 23:13:32 +1100 Subject: s4-repl: save the result of the last replication in repsFrom/repsTo when a replication fails, we should add the failure to repsFrom when a notify fails, we need to save it to repsTo this ensures showrepl always shows the latest status --- source4/dsdb/repl/drepl_notify.c | 31 ++------ source4/dsdb/repl/drepl_out_pull.c | 97 +++++++++++++++++-------- source4/dsdb/samdb/ldb_modules/repl_meta_data.c | 5 -- 3 files changed, 75 insertions(+), 58 deletions(-) diff --git a/source4/dsdb/repl/drepl_notify.c b/source4/dsdb/repl/drepl_notify.c index 25378129da..4629357711 100644 --- a/source4/dsdb/repl/drepl_notify.c +++ b/source4/dsdb/repl/drepl_notify.c @@ -120,10 +120,6 @@ 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; @@ -189,30 +185,13 @@ static void dreplsrv_notify_op_callback(struct tevent_req *subreq) struct dreplsrv_notify_operation); NTSTATUS status; struct dreplsrv_service *s = op->service; + WERROR werr; status = dreplsrv_op_notify_recv(subreq); + werr = ntstatus_to_werror(status); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - WERROR werr; - unsigned int msg_debug_level = 0; - werr = ntstatus_to_werror(status); - if (W_ERROR_EQUAL(werr, WERR_BADFILE)) { - /* - * TODO: - * - * we should better fix the bug regarding - * non-linked attribute handling, instead - * of just hiding the failures. - * - * we should also remove the dc from our repsTo - * if it failed to often, instead of retrying - * every few seconds - */ - msg_debug_level = 2; - } - - DEBUG(msg_debug_level, - ("dreplsrv_notify: Failed to send DsReplicaSync to %s for %s - %s : %s\n", + DEBUG(4,("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), win_errstr(werr))); @@ -226,6 +205,10 @@ static void dreplsrv_notify_op_callback(struct tevent_req *subreq) op->source_dsa->notify_uSN = op->uSN; } + drepl_reps_update(s, "repsTo", op->source_dsa->partition->dn, + &op->source_dsa->repsFrom1->source_dsa_obj_guid, + werr); + talloc_free(op); s->ops.n_current = NULL; dreplsrv_run_pending_ops(s); diff --git a/source4/dsdb/repl/drepl_out_pull.c b/source4/dsdb/repl/drepl_out_pull.c index 0af232c67f..874d44ef55 100644 --- a/source4/dsdb/repl/drepl_out_pull.c +++ b/source4/dsdb/repl/drepl_out_pull.c @@ -34,6 +34,60 @@ #include "libcli/composite/composite.h" #include "libcli/security/security.h" +/* + update repsFrom/repsTo error information + */ +void drepl_reps_update(struct dreplsrv_service *s, const char *reps_attr, + struct ldb_dn *dn, + struct GUID *source_dsa_obj_guid, WERROR status) +{ + struct repsFromToBlob *reps; + uint32_t count, i; + WERROR werr; + TALLOC_CTX *tmp_ctx = talloc_new(s); + time_t t; + NTTIME now; + + t = time(NULL); + unix_to_nt_time(&now, t); + + werr = dsdb_loadreps(s->samdb, tmp_ctx, dn, reps_attr, &reps, &count); + if (!W_ERROR_IS_OK(werr)) { + talloc_free(tmp_ctx); + return; + } + + for (i=0; isamdb, tmp_ctx, dn, reps_attr, reps, count); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(2,("drepl_reps_update: Failed to save %s for %s: %s\n", + reps_attr, ldb_dn_get_linearized(dn), win_errstr(werr))); + } + talloc_free(tmp_ctx); +} + WERROR dreplsrv_schedule_partition_pull_source(struct dreplsrv_service *s, struct dreplsrv_partition_source_dsa *source, enum drsuapi_DsExtendedOperation extended_op, @@ -96,33 +150,21 @@ static void dreplsrv_pending_op_callback(struct tevent_req *subreq) struct dreplsrv_out_operation); struct repsFromTo1 *rf = op->source_dsa->repsFrom1; struct dreplsrv_service *s = op->service; - time_t t; - NTTIME now; + WERROR werr; - t = time(NULL); - unix_to_nt_time(&now, t); - - rf->result_last_attempt = dreplsrv_op_pull_source_recv(subreq); + werr = dreplsrv_op_pull_source_recv(subreq); TALLOC_FREE(subreq); - if (W_ERROR_IS_OK(rf->result_last_attempt)) { - rf->consecutive_sync_failures = 0; - rf->last_success = now; - DEBUG(3,("dreplsrv_op_pull_source(%s)\n", - win_errstr(rf->result_last_attempt))); - goto done; - } - rf->consecutive_sync_failures++; + DEBUG(4,("dreplsrv_op_pull_source(%s) for %s\n", win_errstr(werr), + ldb_dn_get_linearized(op->source_dsa->partition->dn))); - DEBUG(1,("dreplsrv_op_pull_source(%s/%s) for %s failures[%u]\n", - win_errstr(rf->result_last_attempt), - nt_errstr(werror_to_ntstatus(rf->result_last_attempt)), - ldb_dn_get_linearized(op->source_dsa->partition->dn), - rf->consecutive_sync_failures)); + if (op->extended_op == DRSUAPI_EXOP_NONE) { + drepl_reps_update(s, "repsFrom", op->source_dsa->partition->dn, + &rf->source_dsa_obj_guid, werr); + } -done: if (op->callback) { - op->callback(s, rf->result_last_attempt, op->extended_ret, op->cb_data); + op->callback(s, werr, op->extended_ret, op->cb_data); } talloc_free(op); s->ops.current = NULL; @@ -159,8 +201,10 @@ void dreplsrv_run_pull_ops(struct dreplsrv_service *s) if (!subreq) { struct repsFromTo1 *rf = op->source_dsa->repsFrom1; - rf->result_last_attempt = WERR_NOMEM; - rf->consecutive_sync_failures++; + if (op->extended_op == DRSUAPI_EXOP_NONE) { + drepl_reps_update(s, "repsFrom", op->source_dsa->partition->dn, + &rf->source_dsa_obj_guid, WERR_NOMEM); + } s->ops.current = NULL; /* @@ -168,13 +212,8 @@ void dreplsrv_run_pull_ops(struct dreplsrv_service *s) * to do its job just like in any other failure situation */ if (op->callback) { - op->callback(s, rf->result_last_attempt, op->extended_ret, op->cb_data); + op->callback(s, WERR_NOMEM, op->extended_ret, op->cb_data); } - - DEBUG(1,("dreplsrv_op_pull_source(%s/%s) failures[%u]\n", - win_errstr(rf->result_last_attempt), - nt_errstr(werror_to_ntstatus(rf->result_last_attempt)), - rf->consecutive_sync_failures)); return; } tevent_req_set_callback(subreq, dreplsrv_pending_op_callback, op); diff --git a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c index 957ca3ccc5..3db1fe9590 100644 --- a/source4/dsdb/samdb/ldb_modules/repl_meta_data.c +++ b/source4/dsdb/samdb/ldb_modules/repl_meta_data.c @@ -3547,11 +3547,6 @@ static int replmd_replicated_uptodate_modify(struct replmd_replicated_request *a ZERO_STRUCT(nrf); nrf.version = 1; nrf.ctr.ctr1 = *ar->objs->source_dsa; - /* and fix some values... */ - nrf.ctr.ctr1.consecutive_sync_failures = 0; - nrf.ctr.ctr1.last_success = now; - nrf.ctr.ctr1.last_attempt = now; - nrf.ctr.ctr1.result_last_attempt = WERR_OK; nrf.ctr.ctr1.highwatermark.highest_usn = nrf.ctr.ctr1.highwatermark.tmp_highest_usn; /* -- cgit