]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s4:torture: Retry DsExecuteKCC on NT_STATUS_DS_BUSY
authorAndreas Schneider <asn@samba.org>
Wed, 25 Mar 2026 14:52:02 +0000 (15:52 +0100)
committerAndreas Schneider <asn@cryptomilk.org>
Thu, 23 Apr 2026 07:55:04 +0000 (07:55 +0000)
The KCC service runs a periodic samba_kcc child process (every 300s,
first at 15s after startup) with a 40 second timeout. If a test calls
DsExecuteKCC while the periodic child is running, kccsrv returns
NT_STATUS_DS_BUSY which propagates as EPT_NT_CANT_PERFORM_OP to the
client, causing flaky test failures.

UNEXPECTED(error): samba4.drs.samba_tool_drs_showrepl.python(schema_pair_dc).samba_tool_drs_showrepl.SambaToolDrsShowReplTests.test_samba_tool_showrepl(schema_pair_dc:local)
REASON: Exception: Exception: Traceback (most recent call last):
  File "/builds/samba-testbase/samba-def-build/source4/torture/drs/python/samba_tool_drs_showrepl.py", line 57, in test_samba_tool_showrepl
    kcc_out = self.check_output("samba-tool drs kcc %s %s" % (self.dc1,
  File "/builds/samba-testbase/samba-def-build/bin/python/samba/tests/__init__.py", line 593, in check_output
    raise BlackboxProcessError(retcode, line, stdoutdata, stderrdata)
samba.tests.BlackboxProcessError: Command 'python3 bin/samba-tool drs kcc liveupgrade1dc -USCHEMADOMAIN/Administrator%locDCpass1'; shell True; exit status 255;
stdout: ''; stderr: 'ERROR(runtime): DsExecuteKCC failed - (3221356597, 'The operation cannot be performed.')

3221356597 => 0xc0020035 (EPT_NT_CANT_PERFORM_OP)

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date(master): Thu Apr 23 07:55:04 UTC 2026 on atb-devel-224

source4/torture/drs/python/drs_base.py
source4/torture/drs/python/samba_tool_drs.py
source4/torture/drs/python/samba_tool_drs_showrepl.py

index 0f8b5ba928a40aac3e8802defb047c028b0ffa25..f6dff0ee1f5179a67b56a7ca6fada57bcc841ce5 100644 (file)
@@ -126,6 +126,25 @@ class DrsBaseTestCase(SambaToolCmdTest):
         # bin/samba-tool drs <drs_command> <cmdline_auth>
         return ["drs", drs_command, cmdline_auth]
 
+    def _run_drs_kcc(self, DC, cmdline_creds=None):
+        """Run 'samba-tool drs kcc' with retries.
+
+        The KCC periodic task may already be running when we call
+        DsExecuteKCC, causing it to return NT_STATUS_DS_BUSY.  Retry
+        a few times until we are out of the periodic window (up to 40s).
+        """
+        if cmdline_creds is None:
+            cmdline_creds = self.cmdline_creds
+        for i in range(5):
+            try:
+                out = self.check_output(
+                    "samba-tool drs kcc %s %s" % (DC, cmdline_creds))
+                return out
+            except samba.tests.BlackboxProcessError:
+                if i == 4:
+                    raise
+                time.sleep(10)
+
     def _net_drs_replicate(self, DC, fromDC, nc_dn=None, forced=True,
                            local=False, full_sync=False, single=False):
         if nc_dn is None:
index e622fe4f5987a1ea4ce226534e252a007aa04ecd..5ff09aac983abd778671bc1f1ca701de6dcce749 100644 (file)
@@ -70,8 +70,7 @@ class SambaToolDrsTests(drs_base.DrsBaseTestCase):
         """Tests 'samba-tool drs kcc' command."""
 
         # Output should be like 'Consistency check on <DC> successful.'
-        out = self.check_output("samba-tool drs kcc %s %s" % (self.dc1,
-                                                              self.cmdline_creds))
+        out = self._run_drs_kcc(self.dc1)
         self.assertTrue(b"Consistency check on" in out)
         self.assertTrue(b"successful" in out)
 
index 0f0ed86f321330816344fd09f91c3638f994f01b..0588a34dfa6954606d9ac07006a1eb931b49599b 100644 (file)
@@ -54,8 +54,7 @@ class SambaToolDrsShowReplTests(drs_base.DrsBaseTestCase):
 
         # Manually run kcc to create a "Connection" object, so we can find
         # this for the expected output below.
-        kcc_out = self.check_output("samba-tool drs kcc %s %s" % (self.dc1,
-                                                                  self.cmdline_creds))
+        kcc_out = self._run_drs_kcc(self.dc1)
         self.assertIn(b"successful", kcc_out)
 
         # Run replicate to ensure there are incoming and outgoing partners