[PATCH] do a partial replication with drs replicate --local
Stefan Metzmacher
metze at samba.org
Thu Feb 9 05:41:31 UTC 2017
Hi Bob,
> Attached are patches after my team's had a look at them; with some minor
> changes.
Thanks! Please change some minor things in py_dsdb_load_udv_v2():
- Please initialize all pointer variables with NULL
- cursor_ctr is unused
- if (!py_cursor) should be if (py_cursor == NULL)
Then it's Reviewed-by: me
Thanks!
metze
> On 09/02/17 15:10, Bob Campbell wrote:
>> Hi Metze -
>>
>> I've changed the attached patches by adding python bindings for
>> dsdb_load_udv_v2, and using that in replicate --local.
>>
>> Thanks,
>> Bob
>>
>> On 08/02/17 23:41, Stefan Metzmacher wrote:
>>> 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/20170209/08abf48b/signature.sig>
More information about the samba-technical
mailing list