summaryrefslogtreecommitdiff
path: root/source4/dsdb/repl
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2010-11-17 23:13:32 +1100
committerAndrew Tridgell <tridge@samba.org>2010-11-17 23:55:39 +1100
commit6c8b0d7f2784faf68d08d42227765bdc0ce28b35 (patch)
tree3668a2afb8d1c651022ec98343c8d52f0269b4df /source4/dsdb/repl
parent73016ad40523d4d41114c7b4d6bb2a46815bb597 (diff)
downloadsamba-6c8b0d7f2784faf68d08d42227765bdc0ce28b35.tar.gz
samba-6c8b0d7f2784faf68d08d42227765bdc0ce28b35.tar.bz2
samba-6c8b0d7f2784faf68d08d42227765bdc0ce28b35.zip
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
Diffstat (limited to 'source4/dsdb/repl')
-rw-r--r--source4/dsdb/repl/drepl_notify.c31
-rw-r--r--source4/dsdb/repl/drepl_out_pull.c97
2 files changed, 75 insertions, 53 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; i<count; i++) {
+ if (GUID_compare(source_dsa_obj_guid,
+ &reps[i].ctr.ctr1.source_dsa_obj_guid) == 0) {
+ break;
+ }
+ }
+
+ if (i == count) {
+ /* no record to update */
+ talloc_free(tmp_ctx);
+ return;
+ }
+
+ /* only update the status fields */
+ reps[i].ctr.ctr1.last_attempt = now;
+ reps[i].ctr.ctr1.result_last_attempt = status;
+ if (W_ERROR_IS_OK(status)) {
+ reps[i].ctr.ctr1.last_success = now;
+ reps[i].ctr.ctr1.consecutive_sync_failures = 0;
+ } else {
+ reps[i].ctr.ctr1.consecutive_sync_failures++;
+ }
+
+ werr = dsdb_savereps(s->samdb, 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);