All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3] iotests: fix three spurious local failures
@ 2026-07-15 10:34 Denis V. Lunev
  2026-07-15 10:34 ` [PATCH v2 1/3] iotests: run the test pool with the 'fork' start method Denis V. Lunev
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Denis V. Lunev @ 2026-07-15 10:34 UTC (permalink / raw)
  To: qemu-block, qemu-devel
  Cc: den, Kevin Wolf, Hanna Reitz, Vladimir Sementsov-Ogievskiy

Three independent fixes found while chasing a clean './check -qcow2'
run on a Python 3.14 host. Unrelated to each other, sent as one
series since they came out of the same session.

v2:
- patch 1: drop the now-unused 'Pool' import (Kevin)
- patch 2: rename _notrun_on_no_fuse to _notrun_on_fuse_error (Kevin)
- patch 3: replace the dropped assertion with a check that bitmap0's
  content on the destination has not reached its final value right
  after RESUME, throttling migration bandwidth

Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Hanna Reitz <hreitz@redhat.com>
CC: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>

Denis V. Lunev (3):
  iotests: run the test pool with the 'fork' start method
  iotests: skip FUSE tests when FUSE is not usable
  iotests/migrate-bitmaps-postcopy-test: replace the timing assertion
    with a content check

 tests/qemu-iotests/common.rc                      | 14 ++++++++++++++
 tests/qemu-iotests/testrunner.py                  |  4 ++--
 tests/qemu-iotests/tests/file-io-error            |  4 +---
 tests/qemu-iotests/tests/fuse-allow-other         |  2 ++
 tests/qemu-iotests/tests/fuse-mmap-shared         |  9 ++++++---
 .../tests/migrate-bitmaps-postcopy-test           | 15 ++++++++++++++-
 6 files changed, 39 insertions(+), 9 deletions(-)

-- 
2.53.0



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/3] iotests: run the test pool with the 'fork' start method
  2026-07-15 10:34 [PATCH v2 0/3] iotests: fix three spurious local failures Denis V. Lunev
@ 2026-07-15 10:34 ` Denis V. Lunev
  2026-07-22  8:45   ` Daniel P. Berrangé
  2026-07-15 10:34 ` [PATCH v2 2/3] iotests: skip FUSE tests when FUSE is not usable Denis V. Lunev
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Denis V. Lunev @ 2026-07-15 10:34 UTC (permalink / raw)
  To: qemu-block, qemu-devel; +Cc: den, Kevin Wolf, Hanna Reitz

run_tests_pool() shares the runner via the class attribute
TestRunner.shared_self, relying on worker processes to inherit it.
That only works with the 'fork' start method. Python 3.14 switched
the Linux default to 'forkserver', so workers see shared_self as
None and parallel runs abort with:

  assert runner is not None
  AssertionError

Only reproduces with Python 3.14+ and 'check -jN' (N > 1); meson
runs one test per process and never calls run_tests_pool(), so CI
is unaffected.

Request get_context('fork') explicitly; it is available on all
supported Python versions and a no-op before 3.14.

Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Hanna Reitz <hreitz@redhat.com>
---
 tests/qemu-iotests/testrunner.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py
index dbe2dddc32..cc36867719 100644
--- a/tests/qemu-iotests/testrunner.py
+++ b/tests/qemu-iotests/testrunner.py
@@ -26,7 +26,7 @@
 import json
 import shutil
 import sys
-from multiprocessing import Pool
+from multiprocessing import get_context
 from typing import List, Optional, Any, Sequence, Dict
 from testenv import TestEnv
 
@@ -125,7 +125,7 @@ def run_tests_pool(self, tests: List[str],
         assert TestRunner.shared_self is None
         TestRunner.shared_self = self
 
-        with Pool(jobs) as p:
+        with get_context('fork').Pool(jobs) as p:
             results = p.starmap(self.proc_run_test,
                                 zip(tests, [test_field_width] * len(tests)))
 
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/3] iotests: skip FUSE tests when FUSE is not usable
  2026-07-15 10:34 [PATCH v2 0/3] iotests: fix three spurious local failures Denis V. Lunev
  2026-07-15 10:34 ` [PATCH v2 1/3] iotests: run the test pool with the 'fork' start method Denis V. Lunev
@ 2026-07-15 10:34 ` Denis V. Lunev
  2026-07-22  8:46   ` Daniel P. Berrangé
  2026-07-15 10:34 ` [PATCH v2 3/3] iotests/migrate-bitmaps-postcopy-test: replace the timing assertion with a content check Denis V. Lunev
  2026-07-22  8:39 ` [PATCH v2 0/3] iotests: fix three spurious local failures Denis V. Lunev
  3 siblings, 1 reply; 8+ messages in thread
From: Denis V. Lunev @ 2026-07-15 10:34 UTC (permalink / raw)
  To: qemu-block, qemu-devel; +Cc: den, Kevin Wolf, Hanna Reitz

file-io-error, fuse-allow-other and fuse-mmap-shared skip only when
FUSE is not compiled in. When FUSE is built in but unusable at run
time (no /dev/fuse access, fusermount lacking permissions), the
export fails to mount with "Failed to mount FUSE session to export"
and the tests report a spurious failure instead of skipping, like
NBD tests already do for missing NBD support.

Add _notrun_on_fuse_error() to common.rc and use it in the shell
tests. fuse-mmap-shared is Python, so it gets an equivalent inline
check.

Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Hanna Reitz <hreitz@redhat.com>
---
 tests/qemu-iotests/common.rc              | 14 ++++++++++++++
 tests/qemu-iotests/tests/file-io-error    |  4 +---
 tests/qemu-iotests/tests/fuse-allow-other |  2 ++
 tests/qemu-iotests/tests/fuse-mmap-shared |  9 ++++++---
 4 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 298bc483e0..bcb1ec50a9 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -981,6 +981,20 @@ _require_drivers()
     done
 }
 
+# Skip if FUSE is unusable: not compiled in, or the export failed to
+# mount. $1 is the failing 'block-export-add' reply.
+_notrun_on_fuse_error()
+{
+    case "$1" in
+        *"Parameter 'type' does not accept value 'fuse'"*)
+            _notrun "No FUSE support"
+            ;;
+        *"Failed to mount FUSE session"*)
+            _notrun "FUSE not usable in this environment"
+            ;;
+    esac
+}
+
 # Check that we have a file system that allows huge (but very sparse) files
 #
 _require_large_file()
diff --git a/tests/qemu-iotests/tests/file-io-error b/tests/qemu-iotests/tests/file-io-error
index fb8db73b31..0d970c102f 100755
--- a/tests/qemu-iotests/tests/file-io-error
+++ b/tests/qemu-iotests/tests/file-io-error
@@ -89,9 +89,7 @@ output=$(_send_qemu_cmd $QEMU_HANDLE \
     'return' \
     | grep -v 'option allow_other only allowed if')
 
-if echo "$output" | grep -q "Parameter 'type' does not accept value 'fuse'"; then
-    _notrun 'No FUSE support'
-fi
+_notrun_on_fuse_error "$output"
 echo "$output"
 
 echo
diff --git a/tests/qemu-iotests/tests/fuse-allow-other b/tests/qemu-iotests/tests/fuse-allow-other
index eaa39f8f23..50a36601d7 100755
--- a/tests/qemu-iotests/tests/fuse-allow-other
+++ b/tests/qemu-iotests/tests/fuse-allow-other
@@ -77,6 +77,8 @@ fuse_export_add()
         _notrun "allow_other not supported"
     fi
 
+    _notrun_on_fuse_error "$output"
+
     echo "$output"
 }
 
diff --git a/tests/qemu-iotests/tests/fuse-mmap-shared b/tests/qemu-iotests/tests/fuse-mmap-shared
index 52941a3bb6..b190105894 100755
--- a/tests/qemu-iotests/tests/fuse-mmap-shared
+++ b/tests/qemu-iotests/tests/fuse-mmap-shared
@@ -28,9 +28,12 @@ def test_fuse_support(mount_point):
     })
     test_qsd.stop()
     if 'error' in res:
-        assert (res['error']['desc'] ==
-                "Parameter 'type' does not accept value 'fuse'")
-        iotests.notrun('No FUSE support')
+        desc = res['error']['desc']
+        if desc == "Parameter 'type' does not accept value 'fuse'":
+            iotests.notrun('No FUSE support')
+        if 'Failed to mount FUSE session' in desc:
+            iotests.notrun('FUSE not usable in this environment')
+        assert False, desc
 
 # Shared mmap when using direct IO is only supported for Linux kernels >= 6.6
 # with commit e78662e818f94 ("fuse: add a new fuse init flag to relax
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 3/3] iotests/migrate-bitmaps-postcopy-test: replace the timing assertion with a content check
  2026-07-15 10:34 [PATCH v2 0/3] iotests: fix three spurious local failures Denis V. Lunev
  2026-07-15 10:34 ` [PATCH v2 1/3] iotests: run the test pool with the 'fork' start method Denis V. Lunev
  2026-07-15 10:34 ` [PATCH v2 2/3] iotests: skip FUSE tests when FUSE is not usable Denis V. Lunev
@ 2026-07-15 10:34 ` Denis V. Lunev
  2026-07-15 10:55   ` Vladimir Sementsov-Ogievskiy
  2026-07-22  8:39 ` [PATCH v2 0/3] iotests: fix three spurious local failures Denis V. Lunev
  3 siblings, 1 reply; 8+ messages in thread
From: Denis V. Lunev @ 2026-07-15 10:34 UTC (permalink / raw)
  To: qemu-block, qemu-devel
  Cc: den, Kevin Wolf, Hanna Reitz, Vladimir Sementsov-Ogievskiy

`downtime * 10 < postcopy_time` was an unnormalized wall-clock
heuristic (commit e80a4150a5) that fails on fast hosts, where the
bitmap payload now transfers in under a second.

Check the actual invariant instead: right after RESUME, bitmap0's
content hash on the destination must not yet match the fully
migrated value. Throttle max-bandwidth first, since all-zero chunks
skip the payload write and would otherwise let a fast host finish
the transfer before the check runs.

Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Hanna Reitz <hreitz@redhat.com>
CC: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
---
 .../tests/migrate-bitmaps-postcopy-test           | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test
index c519e6db8c..33ff2b861f 100755
--- a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test
+++ b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test
@@ -160,12 +160,26 @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase):
 
         self.vm_b.cmd('migrate-set-capabilities', capabilities=caps)
 
+        # Throttle so the chunks covering our discards (the only ones
+        # not skipped by the all-zero fast path) can't outrun the check
+        # below.
+        self.vm_a.cmd('migrate-set-parameters', max_bandwidth=16536)
+
         self.vm_a.cmd('migrate', uri='exec:cat>' + fifo)
 
         self.vm_a.cmd('migrate-start-postcopy')
 
         event_resume = self.vm_b.event_wait('RESUME')
         self.vm_b_events.append(event_resume)
+
+        # bitmap0 can't already have its final content: that requires
+        # the bit data to have actually arrived.
+        result = self.vm_b.qmp('x-debug-block-dirty-bitmap-sha256',
+                               node='drive0', name='bitmap0')
+        assert result['return']['sha256'] != all_discards_sha256
+
+        self.vm_a.cmd('migrate-set-parameters', max_bandwidth=0)
+
         return (event_resume, discards1_sha256, all_discards_sha256)
 
     def test_postcopy_success(self):
@@ -186,7 +200,6 @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase):
         downtime = event_dist(event_stop, event_resume)
         postcopy_time = event_dist(event_resume, event_complete)
 
-        assert downtime * 10 < postcopy_time
         if debug:
             print('downtime:', downtime)
             print('postcopy_time:', postcopy_time)
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 3/3] iotests/migrate-bitmaps-postcopy-test: replace the timing assertion with a content check
  2026-07-15 10:34 ` [PATCH v2 3/3] iotests/migrate-bitmaps-postcopy-test: replace the timing assertion with a content check Denis V. Lunev
@ 2026-07-15 10:55   ` Vladimir Sementsov-Ogievskiy
  0 siblings, 0 replies; 8+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2026-07-15 10:55 UTC (permalink / raw)
  To: Denis V. Lunev, qemu-block, qemu-devel; +Cc: Kevin Wolf, Hanna Reitz

On 15.07.26 13:34, Denis V. Lunev wrote:
> `downtime * 10 < postcopy_time` was an unnormalized wall-clock
> heuristic (commit e80a4150a5) that fails on fast hosts, where the
> bitmap payload now transfers in under a second.
> 
> Check the actual invariant instead: right after RESUME, bitmap0's
> content hash on the destination must not yet match the fully
> migrated value. Throttle max-bandwidth first, since all-zero chunks
> skip the payload write and would otherwise let a fast host finish
> the transfer before the check runs.
> 
> Signed-off-by: Denis V. Lunev<den@openvz.org>
> CC: Kevin Wolf<kwolf@redhat.com>
> CC: Hanna Reitz<hreitz@redhat.com>
> CC: Vladimir Sementsov-Ogievskiy<vsementsov@yandex-team.ru>

Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>

-- 
Best regards,
Vladimir


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 0/3] iotests: fix three spurious local failures
  2026-07-15 10:34 [PATCH v2 0/3] iotests: fix three spurious local failures Denis V. Lunev
                   ` (2 preceding siblings ...)
  2026-07-15 10:34 ` [PATCH v2 3/3] iotests/migrate-bitmaps-postcopy-test: replace the timing assertion with a content check Denis V. Lunev
@ 2026-07-22  8:39 ` Denis V. Lunev
  3 siblings, 0 replies; 8+ messages in thread
From: Denis V. Lunev @ 2026-07-22  8:39 UTC (permalink / raw)
  To: Denis V. Lunev, qemu-block, qemu-devel
  Cc: Kevin Wolf, Hanna Reitz, Vladimir Sementsov-Ogievskiy

On 7/15/26 12:34, Denis V. Lunev wrote:
> This email originated from an IP that might not be authorized by the domain it was sent from.
> Do not click links or open attachments unless it is an email you expected to receive.
> Three independent fixes found while chasing a clean './check -qcow2'
> run on a Python 3.14 host. Unrelated to each other, sent as one
> series since they came out of the same session.
>
> v2:
> - patch 1: drop the now-unused 'Pool' import (Kevin)
> - patch 2: rename _notrun_on_no_fuse to _notrun_on_fuse_error (Kevin)
> - patch 3: replace the dropped assertion with a check that bitmap0's
>   content on the destination has not reached its final value right
>   after RESUME, throttling migration bandwidth
>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Kevin Wolf <kwolf@redhat.com>
> CC: Hanna Reitz <hreitz@redhat.com>
> CC: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
>
> Denis V. Lunev (3):
>   iotests: run the test pool with the 'fork' start method
>   iotests: skip FUSE tests when FUSE is not usable
>   iotests/migrate-bitmaps-postcopy-test: replace the timing assertion
>     with a content check
>
>  tests/qemu-iotests/common.rc                      | 14 ++++++++++++++
>  tests/qemu-iotests/testrunner.py                  |  4 ++--
>  tests/qemu-iotests/tests/file-io-error            |  4 +---
>  tests/qemu-iotests/tests/fuse-allow-other         |  2 ++
>  tests/qemu-iotests/tests/fuse-mmap-shared         |  9 ++++++---
>  .../tests/migrate-bitmaps-postcopy-test           | 15 ++++++++++++++-
>  6 files changed, 39 insertions(+), 9 deletions(-)
>
ping


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/3] iotests: run the test pool with the 'fork' start method
  2026-07-15 10:34 ` [PATCH v2 1/3] iotests: run the test pool with the 'fork' start method Denis V. Lunev
@ 2026-07-22  8:45   ` Daniel P. Berrangé
  0 siblings, 0 replies; 8+ messages in thread
From: Daniel P. Berrangé @ 2026-07-22  8:45 UTC (permalink / raw)
  To: Denis V. Lunev; +Cc: qemu-block, qemu-devel, Kevin Wolf, Hanna Reitz

On Wed, Jul 15, 2026 at 12:34:49PM +0200, Denis V. Lunev wrote:
> run_tests_pool() shares the runner via the class attribute
> TestRunner.shared_self, relying on worker processes to inherit it.
> That only works with the 'fork' start method. Python 3.14 switched
> the Linux default to 'forkserver', so workers see shared_self as
> None and parallel runs abort with:
> 
>   assert runner is not None
>   AssertionError
> 
> Only reproduces with Python 3.14+ and 'check -jN' (N > 1); meson
> runs one test per process and never calls run_tests_pool(), so CI
> is unaffected.
> 
> Request get_context('fork') explicitly; it is available on all
> supported Python versions and a no-op before 3.14.
> 
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Kevin Wolf <kwolf@redhat.com>
> CC: Hanna Reitz <hreitz@redhat.com>
> ---
>  tests/qemu-iotests/testrunner.py | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>


With regards,
Daniel
-- 
|: https://berrange.com       ~~        https://hachyderm.io/@berrange :|
|: https://libvirt.org          ~~          https://entangle-photo.org :|
|: https://pixelfed.art/berrange   ~~    https://fstop138.berrange.com :|



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 2/3] iotests: skip FUSE tests when FUSE is not usable
  2026-07-15 10:34 ` [PATCH v2 2/3] iotests: skip FUSE tests when FUSE is not usable Denis V. Lunev
@ 2026-07-22  8:46   ` Daniel P. Berrangé
  0 siblings, 0 replies; 8+ messages in thread
From: Daniel P. Berrangé @ 2026-07-22  8:46 UTC (permalink / raw)
  To: Denis V. Lunev; +Cc: qemu-block, qemu-devel, Kevin Wolf, Hanna Reitz

On Wed, Jul 15, 2026 at 12:34:50PM +0200, Denis V. Lunev wrote:
> file-io-error, fuse-allow-other and fuse-mmap-shared skip only when
> FUSE is not compiled in. When FUSE is built in but unusable at run
> time (no /dev/fuse access, fusermount lacking permissions), the
> export fails to mount with "Failed to mount FUSE session to export"
> and the tests report a spurious failure instead of skipping, like
> NBD tests already do for missing NBD support.
> 
> Add _notrun_on_fuse_error() to common.rc and use it in the shell
> tests. fuse-mmap-shared is Python, so it gets an equivalent inline
> check.
> 
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Kevin Wolf <kwolf@redhat.com>
> CC: Hanna Reitz <hreitz@redhat.com>
> ---
>  tests/qemu-iotests/common.rc              | 14 ++++++++++++++
>  tests/qemu-iotests/tests/file-io-error    |  4 +---
>  tests/qemu-iotests/tests/fuse-allow-other |  2 ++
>  tests/qemu-iotests/tests/fuse-mmap-shared |  9 ++++++---
>  4 files changed, 23 insertions(+), 6 deletions(-)

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>


With regards,
Daniel
-- 
|: https://berrange.com       ~~        https://hachyderm.io/@berrange :|
|: https://libvirt.org          ~~          https://entangle-photo.org :|
|: https://pixelfed.art/berrange   ~~    https://fstop138.berrange.com :|



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-07-22  8:47 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-15 10:34 [PATCH v2 0/3] iotests: fix three spurious local failures Denis V. Lunev
2026-07-15 10:34 ` [PATCH v2 1/3] iotests: run the test pool with the 'fork' start method Denis V. Lunev
2026-07-22  8:45   ` Daniel P. Berrangé
2026-07-15 10:34 ` [PATCH v2 2/3] iotests: skip FUSE tests when FUSE is not usable Denis V. Lunev
2026-07-22  8:46   ` Daniel P. Berrangé
2026-07-15 10:34 ` [PATCH v2 3/3] iotests/migrate-bitmaps-postcopy-test: replace the timing assertion with a content check Denis V. Lunev
2026-07-15 10:55   ` Vladimir Sementsov-Ogievskiy
2026-07-22  8:39 ` [PATCH v2 0/3] iotests: fix three spurious local failures Denis V. Lunev

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.