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);
}