[PATCH] do a partial replication with drs replicate --local
Stefan Metzmacher
metze at samba.org
Wed Feb 8 10:41:12 UTC 2017
Hi Bob,
no the logic is not ok yet.
Am 08.02.2017 um 02:01 schrieb Bob Campbell:
>
> -
> source_dsa_invocation_id = misc.GUID(self.samdb.get_invocation_id())
> dest_dsa_invocation_id = misc.GUID(self.local_samdb.get_invocation_id())
> destination_dsa_guid = self.ntds_guid
>
> + # If we can't find an upToDateVector, replicate fully
> + hwm = drsuapi.DsReplicaHighWaterMark()
> + hwm.tmp_highest_usn = 0
> + hwm.reserved_usn = 0
> + hwm.highest_usn = 0
> +
> + udv = None
> + if not full_sync:
> + res = self.local_samdb.search(base=NC, scope=ldb.SCOPE_BASE,
> + attrs=["replUpToDateVector", "repsFrom"])
> + if "repsFrom" in res[0]:
> + for reps_from_packed in res[0]["repsFrom"]:
> + reps_from_obj = ndr_unpack(drsblobs.repsFromToBlob, reps_from_packed)
> + if reps_from_obj.ctr.source_dsa_invocation_id == source_dsa_invocation_id:
> + hwm = reps_from_obj.ctr.highwatermark
> +
> + if "replUpToDateVector" in res[0]:
> + udv_packed = res[0]["replUpToDateVector"][0]
> + udv_obj = ndr_unpack(drsblobs.replUpToDateVectorBlob, udv_packed)
> + udv_ctr = udv_obj.ctr
> +
> + udv = drsuapi.DsReplicaCursorCtrEx()
> + udv.version = 2
> + udv.reserved1 = 0
> + udv.reserved2 = 0
> + cursors = []
> +
> + highest_usn = self.local_samdb.sequence_number(ldb.SEQ_NEXT)
> + found = False
> + for cursor in udv_ctr.cursors:
> + udv_ex_cursor = drsuapi.DsReplicaCursor()
> + udv_ex_cursor.source_dsa_invocation_id = cursor.source_dsa_invocation_id
> + udv_ex_cursor.highest_usn = cursor.highest_usn
> + # Update the cursor if it's ours
> + if cursor.source_dsa_invocation_id == source_dsa_invocation_id:
> + udv_ex_cursor.highest_usn = highest_usn
> + found = True
> + cursors.append(udv_ex_cursor)
> +
> + # If we didn't find our cursor, add a new one for us
> + if not found:
> + our_udv_cursor = drsuapi.DsReplicaCursor()
> + our_udv_cursor.source_dsa_invocation_id = source_dsa_invocation_id
> + our_udv_cursor.highest_usn = highest_usn
> + cursors.append(our_udv_cursor)
> +
> + udv.cursors = cursors
> + udv.count = len(cursors)
> +
It needs to be something like this:
highest_usn = self.local_samdb.sequence_number(ldb.SEQ_NEXT)
# If we can't find an upToDateVector, replicate fully
hwm = drsuapi.DsReplicaHighWaterMark()
hwm.tmp_highest_usn = 0
hwm.reserved_usn = 0
hwm.highest_usn = 0
udv = None
if not full_sync:
res = self.local_samdb.search(base=NC, scope=ldb.SCOPE_BASE,
attrs=["replUpToDateVector",
"repsFrom"])
if "repsFrom" in res[0]:
for reps_from_packed in res[0]["repsFrom"]:
reps_from_obj = ndr_unpack(drsblobs.repsFromToBlob,
reps_from_packed)
if reps_from_obj.ctr.source_dsa_invocation_id ==
source_dsa_invocation_id:
hwm = reps_from_obj.ctr.highwatermark
# The following logic should match dsdb_load_udv_v2()!
cursors = []
found = False
if "replUpToDateVector" in res[0]:
udv_packed = res[0]["replUpToDateVector"][0]
udv_obj = ndr_unpack(drsblobs.replUpToDateVectorBlob,
udv_packed)
udv_ctr = udv_obj.ctr
for cursor in udv_ctr.cursors:
udv_ex_cursor = drsuapi.DsReplicaCursor()
udv_ex_cursor.source_dsa_invocation_id =
cursor.source_dsa_invocation_id
# Update the cursor if it's ours
if cursor.source_dsa_invocation_id ==
destinatoin_dsa_invocation_id:
udv_ex_cursor.highest_usn = highest_usn
found = True
else:
udv_ex_cursor.highest_usn = cursor.highest_usn
cursors.append(udv_ex_cursor)
# If we didn't find our cursor, add a new one for us
if not found:
our_udv_cursor = drsuapi.DsReplicaCursor()
our_udv_cursor.source_dsa_invocation_id =
destination_dsa_invocation_id
our_udv_cursor.highest_usn = highest_usn
cursors.append(our_udv_cursor)
todo_sort_by_guid(cursors)
udv = drsuapi.DsReplicaCursorCtrEx()
udv.version = 2
udv.reserved1 = 0
udv.reserved2 = 0
udv.cursors = cursors
udv.count = len(cursors)
The main points are that our highest_usn belongs to our
destination_dsa_invocation_id not to the source_dsa_invocation_id variable.
and we need to create the udv even without "replUpToDateVector" in that
case we just send our own cursor.
And you should to sort the cursors at the end see:
TYPESAFE_QSORT(*cursors, *count, drsuapi_DsReplicaCursor2_compare);
Another approach would be to add python bindings for dsdb_load_udv_v2().
metze
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20170208/4357ea1e/signature.sig>
More information about the samba-technical
mailing list