On 10/7/26 4:02 PM, Bernhard Beschow wrote:


Am 30. September 2026 15:24:13 UTC schrieb Eric Farman <[email protected]>:
From: Zhuoying Cai <[email protected]>

The pxe test for a net device does not fail gracefully when the
s390-ccw.img in use was built without support for booting that device.

Add a boot_dev_support check that searches for a known string in the
bios image to confirm boot support. If absent, the test is skipped
gracefully instead of failing.

Also re-enable pxe-test in qtests_s390x, which was accidentally
removed by commit 973d97feca93.

Signed-off-by: Zhuoying Cai <[email protected]>
Tested-by: Joshua Daley <[email protected]>
Reviewed-by: Matthew Rosato <[email protected]>
Link: 
https://lore.kernel.org/qemu-devel/[email protected]
Signed-off-by: Eric Farman <[email protected]>
---
tests/qtest/meson.build |  1 +
tests/qtest/pxe-test.c  | 85 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 33f58b0e95..341f6ad1ba 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -292,6 +292,7 @@ qtests_aarch64 = \
    'migration-test']

qtests_s390x = \
+  (slirp.found() ? ['pxe-test'] : []) + \
   qtests_filter + \
   ['boot-serial-test',
    'drive_del-test',
diff --git a/tests/qtest/pxe-test.c b/tests/qtest/pxe-test.c
index e85dec5a4e..5c6415b936 100644
--- a/tests/qtest/pxe-test.c
+++ b/tests/qtest/pxe-test.c
@@ -26,6 +26,7 @@ typedef struct testdef {
     const char *machine;    /* Machine type */
     const char *model;      /* NIC device model */
     const char *extra;      /* Any additional parameters */
+    bool (*boot_dev_support)(void); /* optional: boot device support check */
} testdef_t;

static testdef_t x86_tests[] = {
@@ -58,8 +59,80 @@ static testdef_t ppc64_tests_slow[] = {
     { NULL },
};

+static const char *s390_bios_load(gsize *len)
+{
+    static char *cached_contents;
+    static gsize cached_len;
+    const char *qemu_bin;
+    g_autofree char *cmd = NULL;
+    char dir[PATH_MAX];
+    char *found = NULL;
+    char *path = NULL;
+    FILE *fp;
+
+    if (cached_contents) {
+        g_test_message("Using cached bios contents");
+        goto out;
+    }
+
+    /* search the qemu binary's data directories for s390-ccw.img */
+    qemu_bin = qtest_qemu_binary(NULL);
+    cmd = g_strdup_printf("%s -L help", qemu_bin);
+    fp = popen(cmd, "r");
+
+    if (!fp) {
+        g_error("Failed to run '%s'", cmd);
+    }
+
+    while (fgets(dir, sizeof(dir), fp) && !found) {
+        dir[strcspn(dir, "\n")] = '\0';
+        path = g_build_filename(dir, "s390-ccw.img", NULL);
+        if (g_file_get_contents(path, &cached_contents, &cached_len, NULL)) {
+            found = path;
+        } else {
+            g_free(path);
+        }
+    }
+    pclose(fp);
+
+    if (!found) {
+        g_error("s390-ccw.img not found");
+    }
+
+    g_test_message("Loaded %s", found);
+    g_free(found);
+
+out:
+    *len = cached_len;
+    return cached_contents;
+}
+
+static bool s390_bios_has_string(const char *needle)
+{
+    const char *contents;
+    gsize len;
+    bool found;
+
+    contents = s390_bios_load(&len);
+    found = memmem(contents, len, needle, strlen(needle)) != NULL;

MinGW-w64 has no `memmem`, so this patch unfortunately breaks the MSYS2 build 
with GCC. We might need to provide our own implementation like we do with other 
functions: 
https://lore.kernel.org/qemu-devel/[email protected]/ 
.

Oof, sorry about that! Thanks for the report; will work with Joy and Matt to get this repaired. (And I'll figure out why I didn't stumble on this in my build tests.)

Thanks,
Eric


Best regards,
Bernhard

+
+    g_test_message("\"%s\" %s in bios", needle, found ? "found" : "not found");
+    return found;
+}
+
+static bool s390_bios_has_net_ccw(void)
+{
+    /*
+     * Assume that netboot support always includes virtio-net-ccw support.
+     * Check only that netboot code exists, rather than probing virtio-net-ccw
+     * support directly.
+     */
+    return s390_bios_has_string("Network boot starting...");
+}
+
static testdef_t s390x_tests[] = {
-    { "s390-ccw-virtio", "virtio-net-ccw" },
+    { "s390-ccw-virtio", "virtio-net-ccw",
+      .boot_dev_support = s390_bios_has_net_ccw },
     { NULL },
};

@@ -90,6 +163,11 @@ static void test_pxe_ipv4(gconstpointer data)
{
     const testdef_t *test = data;

+    if (test->boot_dev_support && !test->boot_dev_support()) {
+        g_test_skip("The bios does not support booting this device");
+        return;
+    }
+
     test_pxe_one(test, false);
}

@@ -97,6 +175,11 @@ static void test_pxe_ipv6(gconstpointer data)
{
     const testdef_t *test = data;

+    if (test->boot_dev_support && !test->boot_dev_support()) {
+        g_test_skip("The bios does not support booting this device");
+        return;
+    }
+
     test_pxe_one(test, true);
}



Reply via email to