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]/
.
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);
> }
>