diff options
author | Michael Adam <obnox@samba.org> | 2008-07-17 01:05:06 +0200 |
---|---|---|
committer | Michael Adam <obnox@samba.org> | 2008-08-01 16:04:41 +0200 |
commit | 4d946b5932faa89cc1f48b1d13c4c8357e47d83e (patch) | |
tree | 4064e9da6165ae529d8bb35eecfb0417824b7a80 /source3/libnet | |
parent | 55791799b54e947c6ef825a05a0d141fc1436b9e (diff) | |
download | samba-4d946b5932faa89cc1f48b1d13c4c8357e47d83e.tar.gz samba-4d946b5932faa89cc1f48b1d13c4c8357e47d83e.tar.bz2 samba-4d946b5932faa89cc1f48b1d13c4c8357e47d83e.zip |
dssync: pass uptodateness vector into and out of DsGetNCChanges request.
Also store the new uptodateness vector in the backend after completion
and retrieve the old vector before sending the DsGetNCChanges request.
This effectively accomplishes differential replication.
Michael
(This used to be commit a2a88808df16d153f45337b740391d419d87e87a)
Diffstat (limited to 'source3/libnet')
-rw-r--r-- | source3/libnet/libnet_dssync.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/source3/libnet/libnet_dssync.c b/source3/libnet/libnet_dssync.c index 1bec903427..54bdbb7b22 100644 --- a/source3/libnet/libnet_dssync.c +++ b/source3/libnet/libnet_dssync.c @@ -374,6 +374,10 @@ static NTSTATUS libnet_dssync_process(TALLOC_CTX *mem_ctx, struct drsuapi_DsGetNCChangesCtr1 *ctr1 = NULL; struct drsuapi_DsGetNCChangesCtr6 *ctr6 = NULL; + struct replUpToDateVectorBlob *old_utdv = NULL; + struct drsuapi_DsReplicaCursorCtrEx cursors; + struct drsuapi_DsReplicaCursorCtrEx *pcursors = NULL; + struct replUpToDateVectorBlob new_utdv; int32_t out_level = 0; int y; uint32_t replica_flags = DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE | @@ -389,7 +393,7 @@ static NTSTATUS libnet_dssync_process(TALLOC_CTX *mem_ctx, nc.guid = GUID_zero(); nc.sid = null_sid; - status = ctx->ops->startup(ctx, mem_ctx, NULL); + status = ctx->ops->startup(ctx, mem_ctx, &old_utdv); if (!NT_STATUS_IS_OK(status)) { ctx->error_message = talloc_asprintf(mem_ctx, "Failed to call startup operation: %s", @@ -397,6 +401,30 @@ static NTSTATUS libnet_dssync_process(TALLOC_CTX *mem_ctx, goto out; } + if (old_utdv) { + pcursors = &cursors; + ZERO_STRUCTP(pcursors); + + switch (old_utdv->version) { + case 1: + pcursors->count = old_utdv->ctr.ctr1.count; + pcursors->cursors = old_utdv->ctr.ctr1.cursors; + break; + case 2: + pcursors->count = old_utdv->ctr.ctr2.count; + pcursors->cursors = talloc_array(mem_ctx, + struct drsuapi_DsReplicaCursor, + pcursors->count); + for (y = 0; y < pcursors->count; y++) { + pcursors->cursors[y].source_dsa_invocation_id = + old_utdv->ctr.ctr2.cursors[y].source_dsa_invocation_id; + pcursors->cursors[y].highest_usn = + old_utdv->ctr.ctr2.cursors[y].highest_usn; + } + break; + } + } + if (ctx->remote_info28.supported_extensions & DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8) { @@ -405,12 +433,14 @@ static NTSTATUS libnet_dssync_process(TALLOC_CTX *mem_ctx, req.req8.replica_flags = replica_flags; req.req8.max_object_count = 402; req.req8.max_ndr_size = 402116; + req.req8.uptodateness_vector = pcursors; } else { level = 5; req.req5.naming_context = &nc; req.req5.replica_flags = replica_flags; req.req5.max_object_count = 402; req.req5.max_ndr_size = 402116; + req.req5.uptodateness_vector = pcursors; } for (y=0; ;y++) { @@ -491,6 +521,11 @@ static NTSTATUS libnet_dssync_process(TALLOC_CTX *mem_ctx, if (!last_query) { continue; } + + ZERO_STRUCT(new_utdv); + new_utdv.version = 1; + new_utdv.ctr.ctr1.count = ctr1->uptodateness_vector->count; + new_utdv.ctr.ctr1.cursors = ctr1->uptodateness_vector->cursors; } if (level_out == 6) { @@ -532,9 +567,14 @@ static NTSTATUS libnet_dssync_process(TALLOC_CTX *mem_ctx, if (!last_query) { continue; } + + ZERO_STRUCT(new_utdv); + new_utdv.version = 2; + new_utdv.ctr.ctr2.count = ctr6->uptodateness_vector->count; + new_utdv.ctr.ctr2.cursors = ctr6->uptodateness_vector->cursors; } - status = ctx->ops->finish(ctx, mem_ctx, NULL); + status = ctx->ops->finish(ctx, mem_ctx, &new_utdv); if (!NT_STATUS_IS_OK(status)) { ctx->error_message = talloc_asprintf(mem_ctx, "Failed to call finishing operation: %s", |