dssync: pass uptodateness vector into and out of DsGetNCChanges request.
authorMichael Adam <obnox@samba.org>
Wed, 16 Jul 2008 23:05:06 +0000 (01:05 +0200)
committerMichael Adam <obnox@samba.org>
Fri, 1 Aug 2008 14:04:41 +0000 (16:04 +0200)
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)

source3/libnet/libnet_dssync.c

index 1bec9034275b08ffa7b78db4b20e68956c614418..54bdbb7b22bff8e803609ce361fe6a1483dff47b 100644 (file)
@@ -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",