qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/18] tests/qtest: Enable running qtest on Windows
@ 2022-10-06 15:11 Bin Meng
  2022-10-06 15:11 ` [PATCH 01/18] semihosting/arm-compat-semi: Avoid using hardcoded /tmp Bin Meng
                   ` (18 more replies)
  0 siblings, 19 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Alex Bennée, Beraldo Leal,
	Christian Schoenebeck, Daniel P. Berrangé,
	Dr. David Alan Gilbert, Eduardo Habkost, Gerd Hoffmann, Greg Kurz,
	Hanna Reitz, Juan Quintela, Kevin Wolf, Laurent Vivier,
	Marcel Apfelbaum, Paolo Bonzini, Philippe Mathieu-Daudé,
	Richard Henderson, Thomas Huth, Wainer dos Santos Moschetta,
	Yanan Wang, qemu-block

In preparation to adding virtio-9p support on Windows, this series
enables running qtest on Windows, so that we can run the virtio-9p
tests on Windows to make sure it does not break accidently.

Changes in v5:
- Rebase on qemu/master
- Drop patches that are already merged
- Use g_autoptr(GError)
- Restore to v1 version which does not touch the posix implementation
- Replace sighandler_t with its actual definition, since it is not
  available on BSD hosts

Changes in v4:
- Update the error reporting by using the GError "error" argument
  of g_dir_make_tmp()
- Remove the const from tmpfs declaration

Changes in v3:
- Split to a separate patch
- Add a usleep(1) in the busy wait loop
- Drop the host test

Changes in v2:
- Use g_autofree to declare the variable
- Change to use g_mkdir()
- Change to use g_mkdir()
- Change to use g_mkdir()
- Introduce qemu_send_full() and use it
- Move the enabling of building qtests on Windows to a separate
  patch to keep bisectablity
- Call socket_init() unconditionally
- Add a missing CloseHandle() call
- Change to a busy wait after migration is canceled
- new patch: "io/channel-watch: Drop the unnecessary cast"
- Change the timeout limit to 90 minutes
- new patch: "tests/qtest: Enable qtest build on Windows"

Bin Meng (15):
  semihosting/arm-compat-semi: Avoid using hardcoded /tmp
  tcg: Avoid using hardcoded /tmp
  util/qemu-sockets: Use g_get_tmp_dir() to get the directory for
    temporary files
  tests/qtest: migration-test: Avoid using hardcoded /tmp
  block/vvfat: Unify the mkdir() call
  fsdev/virtfs-proxy-helper: Use g_mkdir()
  hw/usb: dev-mtp: Use g_mkdir()
  tests/qtest: libqtest: Install signal handler via signal()
  tests/qtest: Support libqtest to build and run on Windows
  tests/qtest: libqtest: Correct the timeout unit of blocking receive
    calls for win32
  io/channel-watch: Drop a superfluous '#ifdef WIN32'
  io/channel-watch: Drop the unnecessary cast
  io/channel-watch: Fix socket watch on Windows
  .gitlab-ci.d/windows.yml: Increase the timeout to 90 minutes
  tests/qtest: Enable qtest build on Windows

Xuzhou Cheng (3):
  accel/qtest: Support qtest accelerator for Windows
  tests/qtest: Use send/recv for socket communication
  tests/qtest: migration-test: Make sure QEMU process "to" exited after
    migration is canceled

 include/hw/core/cpu.h         |   1 +
 include/qemu/sockets.h        |   2 +
 accel/dummy-cpus.c            |  14 +++-
 block/vvfat.c                 |   9 +--
 fsdev/virtfs-proxy-helper.c   |   3 +-
 hw/usb/dev-mtp.c              |   4 +-
 io/channel-watch.c            |  12 +---
 semihosting/arm-compat-semi.c |   3 +-
 softmmu/cpus.c                |   9 +--
 tcg/tcg.c                     |   3 +-
 tests/qtest/libqmp.c          |   5 +-
 tests/qtest/libqtest.c        | 124 +++++++++++++++++++++++++++++-----
 tests/qtest/migration-test.c  |  14 ++--
 util/osdep.c                  |  33 +++++++++
 util/qemu-sockets.c           |   5 +-
 .gitlab-ci.d/windows.yml      |   4 +-
 accel/meson.build             |   1 +
 accel/qtest/meson.build       |   1 +
 tests/qtest/meson.build       |   6 --
 19 files changed, 194 insertions(+), 59 deletions(-)

-- 
2.34.1



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

* [PATCH 01/18] semihosting/arm-compat-semi: Avoid using hardcoded /tmp
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 02/18] tcg: " Bin Meng
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Bin Meng, Alex Bennée

From: Bin Meng <bin.meng@windriver.com>

Use g_get_tmp_dir() to get the directory to use for temporary files.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
---

(no changes since v1)

 semihosting/arm-compat-semi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index bfea9e9337..62d8bae97f 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -503,7 +503,8 @@ void do_common_semihosting(CPUState *cs)
         GET_ARG(0);
         GET_ARG(1);
         GET_ARG(2);
-        len = asprintf(&s, "/tmp/qemu-%x%02x", getpid(), (int)arg1 & 0xff);
+        len = asprintf(&s, "%s/qemu-%x%02x", g_get_tmp_dir(),
+                       getpid(), (int)arg1 & 0xff);
         if (len < 0) {
             common_semi_set_ret(cs, -1);
             break;
-- 
2.34.1



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

* [PATCH 02/18] tcg: Avoid using hardcoded /tmp
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
  2022-10-06 15:11 ` [PATCH 01/18] semihosting/arm-compat-semi: Avoid using hardcoded /tmp Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 03/18] util/qemu-sockets: Use g_get_tmp_dir() to get the directory for temporary files Bin Meng
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Bin Meng, Alex Bennée,
	Richard Henderson

From: Bin Meng <bin.meng@windriver.com>

Use g_get_tmp_dir() to get the directory to use for temporary files.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
---

(no changes since v2)

Changes in v2:
- Use g_autofree to declare the variable

 tcg/tcg.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 612a12f58f..84921b64f7 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -4729,7 +4729,8 @@ static void tcg_register_jit_int(const void *buf_ptr, size_t buf_size,
     /* Enable this block to be able to debug the ELF image file creation.
        One can use readelf, objdump, or other inspection utilities.  */
     {
-        FILE *f = fopen("/tmp/qemu.jit", "w+b");
+        g_autofree char *jit = g_strdup_printf("%s/qemu.jit", g_get_tmp_dir());
+        FILE *f = fopen(jit, "w+b");
         if (f) {
             if (fwrite(img, img_size, 1, f) != img_size) {
                 /* Avoid stupid unused return value warning for fwrite.  */
-- 
2.34.1



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

* [PATCH 03/18] util/qemu-sockets: Use g_get_tmp_dir() to get the directory for temporary files
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
  2022-10-06 15:11 ` [PATCH 01/18] semihosting/arm-compat-semi: Avoid using hardcoded /tmp Bin Meng
  2022-10-06 15:11 ` [PATCH 02/18] tcg: " Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 04/18] tests/qtest: migration-test: Avoid using hardcoded /tmp Bin Meng
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Bin Meng, Daniel P. Berrangé

From: Bin Meng <bin.meng@windriver.com>

Replace the existing logic to get the directory for temporary files
with g_get_tmp_dir(), which works for win32 too.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---

(no changes since v1)

 util/qemu-sockets.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 83f4bd6fd2..0c41ca9e42 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -919,9 +919,8 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
     if (saddr->path[0] || abstract) {
         path = saddr->path;
     } else {
-        const char *tmpdir = getenv("TMPDIR");
-        tmpdir = tmpdir ? tmpdir : "/tmp";
-        path = pathbuf = g_strdup_printf("%s/qemu-socket-XXXXXX", tmpdir);
+        path = pathbuf = g_strdup_printf("%s/qemu-socket-XXXXXX",
+                                         g_get_tmp_dir());
     }
 
     pathlen = strlen(path);
-- 
2.34.1



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

* [PATCH 04/18] tests/qtest: migration-test: Avoid using hardcoded /tmp
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
                   ` (2 preceding siblings ...)
  2022-10-06 15:11 ` [PATCH 03/18] util/qemu-sockets: Use g_get_tmp_dir() to get the directory for temporary files Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 05/18] block/vvfat: Unify the mkdir() call Bin Meng
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Bin Meng, Dr. David Alan Gilbert,
	Juan Quintela, Laurent Vivier, Paolo Bonzini, Thomas Huth

From: Bin Meng <bin.meng@windriver.com>

This case was written to use hardcoded /tmp directory for temporary
files. Update to use g_dir_make_tmp() for a portable implementation.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---

Changes in v5:
- Use g_autoptr(GError)

Changes in v4:
- Update the error reporting by using the GError "error" argument
  of g_dir_make_tmp()
- Remove the const from tmpfs declaration

Changes in v3:
- Split to a separate patch

 tests/qtest/migration-test.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
index 0d153d6b5e..ef4427ff4d 100644
--- a/tests/qtest/migration-test.c
+++ b/tests/qtest/migration-test.c
@@ -102,7 +102,7 @@ static bool ufd_version_check(void)
 
 #endif
 
-static const char *tmpfs;
+static char *tmpfs;
 
 /* The boot file modifies memory area in [start_address, end_address)
  * repeatedly. It outputs a 'B' at a fixed rate while it's still running.
@@ -2451,10 +2451,10 @@ static bool kvm_dirty_ring_supported(void)
 
 int main(int argc, char **argv)
 {
-    char template[] = "/tmp/migration-test-XXXXXX";
     const bool has_kvm = qtest_has_accel("kvm");
     const bool has_uffd = ufd_version_check();
     const char *arch = qtest_get_arch();
+    g_autoptr(GError) err = NULL;
     int ret;
 
     g_test_init(&argc, &argv, NULL);
@@ -2479,9 +2479,10 @@ int main(int argc, char **argv)
         return g_test_run();
     }
 
-    tmpfs = g_mkdtemp(template);
+    tmpfs = g_dir_make_tmp("migration-test-XXXXXX", &err);
     if (!tmpfs) {
-        g_test_message("g_mkdtemp on path (%s): %s", template, strerror(errno));
+        g_test_message("g_dir_make_tmp on path (%s): %s", tmpfs,
+                       err->message);
     }
     g_assert(tmpfs);
 
@@ -2612,6 +2613,7 @@ int main(int argc, char **argv)
         g_test_message("unable to rmdir: path (%s): %s",
                        tmpfs, strerror(errno));
     }
+    g_free(tmpfs);
 
     return ret;
 }
-- 
2.34.1



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

* [PATCH 05/18] block/vvfat: Unify the mkdir() call
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
                   ` (3 preceding siblings ...)
  2022-10-06 15:11 ` [PATCH 04/18] tests/qtest: migration-test: Avoid using hardcoded /tmp Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 06/18] fsdev/virtfs-proxy-helper: Use g_mkdir() Bin Meng
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Bin Meng, Hanna Reitz, Kevin Wolf,
	qemu-block

From: Bin Meng <bin.meng@windriver.com>

There is a difference in the mkdir() call for win32 and non-win32
platforms, and currently is handled in the codes with #ifdefs.

glib provides a portable g_mkdir() API and we can use it to unify
the codes without #ifdefs.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---

(no changes since v2)

Changes in v2:
- Change to use g_mkdir()

 block/vvfat.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index d6dd919683..723beef025 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -25,6 +25,7 @@
 
 #include "qemu/osdep.h"
 #include <dirent.h>
+#include <glib/gstdio.h>
 #include "qapi/error.h"
 #include "block/block_int.h"
 #include "block/qdict.h"
@@ -2726,13 +2727,9 @@ static int handle_renames_and_mkdirs(BDRVVVFATState* s)
             mapping_t* mapping;
             int j, parent_path_len;
 
-#ifdef __MINGW32__
-            if (mkdir(commit->path))
+            if (g_mkdir(commit->path, 0755)) {
                 return -5;
-#else
-            if (mkdir(commit->path, 0755))
-                return -5;
-#endif
+            }
 
             mapping = insert_mapping(s, commit->param.mkdir.cluster,
                     commit->param.mkdir.cluster + 1);
-- 
2.34.1



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

* [PATCH 06/18] fsdev/virtfs-proxy-helper: Use g_mkdir()
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
                   ` (4 preceding siblings ...)
  2022-10-06 15:11 ` [PATCH 05/18] block/vvfat: Unify the mkdir() call Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 07/18] hw/usb: dev-mtp: " Bin Meng
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Bin Meng, Christian Schoenebeck,
	Greg Kurz

From: Bin Meng <bin.meng@windriver.com>

Use g_mkdir() to create a directory on all platforms.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
---

(no changes since v2)

Changes in v2:
- Change to use g_mkdir()

 fsdev/virtfs-proxy-helper.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c
index 2dde27922f..5cafcd7703 100644
--- a/fsdev/virtfs-proxy-helper.c
+++ b/fsdev/virtfs-proxy-helper.c
@@ -10,6 +10,7 @@
  */
 
 #include "qemu/osdep.h"
+#include <glib/gstdio.h>
 #include <sys/resource.h>
 #include <getopt.h>
 #include <syslog.h>
@@ -639,7 +640,7 @@ static int do_create_others(int type, struct iovec *iovec)
         if (retval < 0) {
             goto err_out;
         }
-        retval = mkdir(path.data, mode);
+        retval = g_mkdir(path.data, mode);
         break;
     case T_SYMLINK:
         retval = proxy_unmarshal(iovec, offset, "ss", &oldpath, &path);
-- 
2.34.1



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

* [PATCH 07/18] hw/usb: dev-mtp: Use g_mkdir()
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
                   ` (5 preceding siblings ...)
  2022-10-06 15:11 ` [PATCH 06/18] fsdev/virtfs-proxy-helper: Use g_mkdir() Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 08/18] accel/qtest: Support qtest accelerator for Windows Bin Meng
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Bin Meng, Gerd Hoffmann

From: Bin Meng <bin.meng@windriver.com>

Use g_mkdir() to create a directory on all platforms.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
---

(no changes since v2)

Changes in v2:
- Change to use g_mkdir()

 hw/usb/dev-mtp.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 5831395cef..1cac1cd435 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -14,7 +14,7 @@
 #include "qemu/error-report.h"
 #include <wchar.h>
 #include <dirent.h>
-
+#include <glib/gstdio.h>
 #include <sys/statvfs.h>
 
 
@@ -1622,7 +1622,7 @@ static void usb_mtp_write_data(MTPState *s, uint32_t handle)
         if (s->dataset.filename) {
             path = g_strdup_printf("%s/%s", parent->path, s->dataset.filename);
             if (s->dataset.format == FMT_ASSOCIATION) {
-                ret = mkdir(path, mask);
+                ret = g_mkdir(path, mask);
                 if (!ret) {
                     usb_mtp_queue_result(s, RES_OK, d->trans, 3,
                                          QEMU_STORAGE_ID,
-- 
2.34.1



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

* [PATCH 08/18] accel/qtest: Support qtest accelerator for Windows
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
                   ` (6 preceding siblings ...)
  2022-10-06 15:11 ` [PATCH 07/18] hw/usb: dev-mtp: " Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 09/18] tests/qtest: Use send/recv for socket communication Bin Meng
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Xuzhou Cheng, Bin Meng, Eduardo Habkost,
	Laurent Vivier, Marcel Apfelbaum, Paolo Bonzini,
	Philippe Mathieu-Daudé, Richard Henderson, Thomas Huth,
	Yanan Wang

From: Xuzhou Cheng <xuzhou.cheng@windriver.com>

Currently signal SIGIPI [=SIGUSR1] is used to kick the dummy CPU
when qtest accelerator is used. However SIGUSR1 is unsupported on
Windows. To support Windows, we add a QemuSemaphore CPUState::sem
to kick the dummy CPU instead for Windows.

Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---

Changes in v5:
- restore to v1 version which does not touch the posix implementation

 include/hw/core/cpu.h   |  1 +
 accel/dummy-cpus.c      | 14 ++++++++++++--
 softmmu/cpus.c          |  9 +++++----
 accel/meson.build       |  1 +
 accel/qtest/meson.build |  1 +
 5 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index f9b58773f7..8830546121 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -333,6 +333,7 @@ struct CPUState {
     struct QemuThread *thread;
 #ifdef _WIN32
     HANDLE hThread;
+    QemuSemaphore sem;
 #endif
     int thread_id;
     bool running, has_waiter;
diff --git a/accel/dummy-cpus.c b/accel/dummy-cpus.c
index 10429fdfb2..d6a1b8d0a2 100644
--- a/accel/dummy-cpus.c
+++ b/accel/dummy-cpus.c
@@ -21,8 +21,6 @@
 static void *dummy_cpu_thread_fn(void *arg)
 {
     CPUState *cpu = arg;
-    sigset_t waitset;
-    int r;
 
     rcu_register_thread();
 
@@ -32,8 +30,13 @@ static void *dummy_cpu_thread_fn(void *arg)
     cpu->can_do_io = 1;
     current_cpu = cpu;
 
+#ifndef _WIN32
+    sigset_t waitset;
+    int r;
+
     sigemptyset(&waitset);
     sigaddset(&waitset, SIG_IPI);
+#endif
 
     /* signal CPU creation */
     cpu_thread_signal_created(cpu);
@@ -41,6 +44,7 @@ static void *dummy_cpu_thread_fn(void *arg)
 
     do {
         qemu_mutex_unlock_iothread();
+#ifndef _WIN32
         do {
             int sig;
             r = sigwait(&waitset, &sig);
@@ -49,6 +53,9 @@ static void *dummy_cpu_thread_fn(void *arg)
             perror("sigwait");
             exit(1);
         }
+#else
+        qemu_sem_wait(&cpu->sem);
+#endif
         qemu_mutex_lock_iothread();
         qemu_wait_io_event(cpu);
     } while (!cpu->unplug);
@@ -69,4 +76,7 @@ void dummy_start_vcpu_thread(CPUState *cpu)
              cpu->cpu_index);
     qemu_thread_create(cpu->thread, thread_name, dummy_cpu_thread_fn, cpu,
                        QEMU_THREAD_JOINABLE);
+#ifdef _WIN32
+    qemu_sem_init(&cpu->sem, 0);
+#endif
 }
diff --git a/softmmu/cpus.c b/softmmu/cpus.c
index 61b27ff59d..9dd1a4dc17 100644
--- a/softmmu/cpus.c
+++ b/softmmu/cpus.c
@@ -437,18 +437,19 @@ void qemu_wait_io_event(CPUState *cpu)
 
 void cpus_kick_thread(CPUState *cpu)
 {
-#ifndef _WIN32
-    int err;
-
     if (cpu->thread_kicked) {
         return;
     }
     cpu->thread_kicked = true;
-    err = pthread_kill(cpu->thread->thread, SIG_IPI);
+
+#ifndef _WIN32
+    int err = pthread_kill(cpu->thread->thread, SIG_IPI);
     if (err && err != ESRCH) {
         fprintf(stderr, "qemu:%s: %s", __func__, strerror(err));
         exit(1);
     }
+#else
+    qemu_sem_post(&cpu->sem);
 #endif
 }
 
diff --git a/accel/meson.build b/accel/meson.build
index b9a963cf80..b21c85dc0a 100644
--- a/accel/meson.build
+++ b/accel/meson.build
@@ -17,4 +17,5 @@ dummy_ss.add(files(
 ))
 
 specific_ss.add_all(when: ['CONFIG_SOFTMMU', 'CONFIG_POSIX'], if_true: dummy_ss)
+specific_ss.add_all(when: ['CONFIG_WIN32'], if_true: dummy_ss)
 specific_ss.add_all(when: ['CONFIG_XEN'], if_true: dummy_ss)
diff --git a/accel/qtest/meson.build b/accel/qtest/meson.build
index 4c65600293..a4876fc0f2 100644
--- a/accel/qtest/meson.build
+++ b/accel/qtest/meson.build
@@ -1,2 +1,3 @@
 qtest_module_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_POSIX'],
                     if_true: files('qtest.c'))
+qtest_module_ss.add(when: ['CONFIG_WIN32'], if_true: files('qtest.c'))
-- 
2.34.1



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

* [PATCH 09/18] tests/qtest: Use send/recv for socket communication
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
                   ` (7 preceding siblings ...)
  2022-10-06 15:11 ` [PATCH 08/18] accel/qtest: Support qtest accelerator for Windows Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 10/18] tests/qtest: libqtest: Install signal handler via signal() Bin Meng
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Xuzhou Cheng, Bin Meng,
	Daniel P. Berrangé, Laurent Vivier, Paolo Bonzini,
	Thomas Huth

From: Xuzhou Cheng <xuzhou.cheng@windriver.com>

Socket communication in the libqtest and libqmp codes uses read()
and write() which work on any file descriptor on *nix, and sockets
in *nix are an example of a file descriptor.

However sockets on Windows do not use *nix-style file descriptors,
so read() and write() cannot be used on sockets on Windows.
Switch over to use send() and recv() instead which work on both
Windows and *nix.

Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---

(no changes since v2)

Changes in v2:
- Introduce qemu_send_full() and use it

 include/qemu/sockets.h |  2 ++
 tests/qtest/libqmp.c   |  5 +++--
 tests/qtest/libqtest.c |  4 ++--
 util/osdep.c           | 33 +++++++++++++++++++++++++++++++++
 4 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index 036745e586..adf2b21bd9 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -33,6 +33,8 @@ int qemu_socketpair(int domain, int type, int protocol, int sv[2]);
 #endif
 
 int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
+ssize_t qemu_send_full(int s, const void *buf, size_t count)
+    G_GNUC_WARN_UNUSED_RESULT;
 int socket_set_cork(int fd, int v);
 int socket_set_nodelay(int fd);
 void qemu_socket_set_block(int fd);
diff --git a/tests/qtest/libqmp.c b/tests/qtest/libqmp.c
index ade26c15f0..2b08382e5d 100644
--- a/tests/qtest/libqmp.c
+++ b/tests/qtest/libqmp.c
@@ -23,6 +23,7 @@
 #endif
 
 #include "qemu/cutils.h"
+#include "qemu/sockets.h"
 #include "qapi/error.h"
 #include "qapi/qmp/json-parser.h"
 #include "qapi/qmp/qjson.h"
@@ -36,7 +37,7 @@ typedef struct {
 
 static void socket_send(int fd, const char *buf, size_t size)
 {
-    size_t res = qemu_write_full(fd, buf, size);
+    ssize_t res = qemu_send_full(fd, buf, size);
 
     assert(res == size);
 }
@@ -69,7 +70,7 @@ QDict *qmp_fd_receive(int fd)
         ssize_t len;
         char c;
 
-        len = read(fd, &c, 1);
+        len = recv(fd, &c, 1, 0);
         if (len == -1 && errno == EINTR) {
             continue;
         }
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index 4f4b2d6477..8228262938 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -436,7 +436,7 @@ void qtest_quit(QTestState *s)
 
 static void socket_send(int fd, const char *buf, size_t size)
 {
-    size_t res = qemu_write_full(fd, buf, size);
+    ssize_t res = qemu_send_full(fd, buf, size);
 
     assert(res == size);
 }
@@ -468,7 +468,7 @@ static GString *qtest_client_socket_recv_line(QTestState *s)
         ssize_t len;
         char buffer[1024];
 
-        len = read(s->fd, buffer, sizeof(buffer));
+        len = recv(s->fd, buffer, sizeof(buffer), 0);
         if (len == -1 && errno == EINTR) {
             continue;
         }
diff --git a/util/osdep.c b/util/osdep.c
index 60fcbbaebe..0342e754e1 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -502,6 +502,39 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
     return ret;
 }
 
+/*
+ * A variant of send(2) which handles partial send.
+ *
+ * Return the number of bytes transferred over the socket.
+ * Set errno if fewer than `count' bytes are sent.
+ *
+ * This function don't work with non-blocking socket's.
+ * Any of the possibilities with non-blocking socket's is bad:
+ *   - return a short write (then name is wrong)
+ *   - busy wait adding (errno == EAGAIN) to the loop
+ */
+ssize_t qemu_send_full(int s, const void *buf, size_t count)
+{
+    ssize_t ret = 0;
+    ssize_t total = 0;
+
+    while (count) {
+        ret = send(s, buf, count, 0);
+        if (ret < 0) {
+            if (errno == EINTR) {
+                continue;
+            }
+            break;
+        }
+
+        count -= ret;
+        buf += ret;
+        total += ret;
+    }
+
+    return total;
+}
+
 void qemu_set_hw_version(const char *version)
 {
     hw_version = version;
-- 
2.34.1



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

* [PATCH 10/18] tests/qtest: libqtest: Install signal handler via signal()
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
                   ` (8 preceding siblings ...)
  2022-10-06 15:11 ` [PATCH 09/18] tests/qtest: Use send/recv for socket communication Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 11/18] tests/qtest: Support libqtest to build and run on Windows Bin Meng
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Bin Meng, Laurent Vivier, Paolo Bonzini,
	Thomas Huth

From: Bin Meng <bin.meng@windriver.com>

At present the codes uses sigaction() to install signal handler with
a flag SA_RESETHAND. Such usage can be covered by the signal() API
that is a simplified interface to the general sigaction() facility.

Update to use signal() to install the signal handler, as it is
available on Windows which we are going to support.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---

Changes in v5:
- Replace sighandler_t with its actual definition, since it is not
  available on BSD hosts

 tests/qtest/libqtest.c | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index 8228262938..54e5f64f20 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -66,7 +66,7 @@ struct QTestState
 };
 
 static GHookList abrt_hooks;
-static struct sigaction sigact_old;
+static void (*sighandler_old)(int);
 
 static int qtest_query_target_endianness(QTestState *s);
 
@@ -179,20 +179,12 @@ static void sigabrt_handler(int signo)
 
 static void setup_sigabrt_handler(void)
 {
-    struct sigaction sigact;
-
-    /* Catch SIGABRT to clean up on g_assert() failure */
-    sigact = (struct sigaction){
-        .sa_handler = sigabrt_handler,
-        .sa_flags = SA_RESETHAND,
-    };
-    sigemptyset(&sigact.sa_mask);
-    sigaction(SIGABRT, &sigact, &sigact_old);
+    sighandler_old = signal(SIGABRT, sigabrt_handler);
 }
 
 static void cleanup_sigabrt_handler(void)
 {
-    sigaction(SIGABRT, &sigact_old, NULL);
+    signal(SIGABRT, sighandler_old);
 }
 
 static bool hook_list_is_empty(GHookList *hook_list)
-- 
2.34.1



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

* [PATCH 11/18] tests/qtest: Support libqtest to build and run on Windows
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
                   ` (9 preceding siblings ...)
  2022-10-06 15:11 ` [PATCH 10/18] tests/qtest: libqtest: Install signal handler via signal() Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 12/18] tests/qtest: migration-test: Make sure QEMU process "to" exited after migration is canceled Bin Meng
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Bin Meng, Xuzhou Cheng, Laurent Vivier,
	Paolo Bonzini, Thomas Huth

From: Bin Meng <bin.meng@windriver.com>

At present the libqtest codes were written to depend on several
POSIX APIs, including fork(), kill() and waitpid(). Unfortunately
these APIs are not available on Windows.

This commit implements the corresponding functionalities using
win32 native APIs. With this change, all qtest cases can build
successfully on a Windows host, and we can start qtest testing
on Windows now.

Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---

(no changes since v2)

Changes in v2:
- Move the enabling of building qtests on Windows to a separate
  patch to keep bisectablity
- Call socket_init() unconditionally
- Add a missing CloseHandle() call

 tests/qtest/libqtest.c | 95 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 93 insertions(+), 2 deletions(-)

diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index 54e5f64f20..ecd22cdb11 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -16,9 +16,11 @@
 
 #include "qemu/osdep.h"
 
+#ifndef _WIN32
 #include <sys/socket.h>
 #include <sys/wait.h>
 #include <sys/un.h>
+#endif /* _WIN32 */
 #ifdef __linux__
 #include <sys/prctl.h>
 #endif /* __linux__ */
@@ -27,6 +29,7 @@
 #include "libqmp.h"
 #include "qemu/ctype.h"
 #include "qemu/cutils.h"
+#include "qemu/sockets.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qjson.h"
 #include "qapi/qmp/qlist.h"
@@ -35,6 +38,16 @@
 #define MAX_IRQ 256
 #define SOCKET_TIMEOUT 50
 
+#ifndef _WIN32
+# define CMD_EXEC   "exec "
+# define DEV_STDERR "/dev/fd/2"
+# define DEV_NULL   "/dev/null"
+#else
+# define CMD_EXEC   ""
+# define DEV_STDERR "2"
+# define DEV_NULL   "nul"
+#endif
+
 typedef void (*QTestSendFn)(QTestState *s, const char *buf);
 typedef void (*ExternalSendFn)(void *s, const char *buf);
 typedef GString* (*QTestRecvFn)(QTestState *);
@@ -118,10 +131,19 @@ bool qtest_probe_child(QTestState *s)
     pid_t pid = s->qemu_pid;
 
     if (pid != -1) {
+#ifndef _WIN32
         pid = waitpid(pid, &s->wstatus, WNOHANG);
         if (pid == 0) {
             return true;
         }
+#else
+        DWORD exit_code;
+        GetExitCodeProcess((HANDLE)pid, &exit_code);
+        if (exit_code == STILL_ACTIVE) {
+            return true;
+        }
+        CloseHandle((HANDLE)pid);
+#endif
         s->qemu_pid = -1;
     }
     return false;
@@ -135,13 +157,23 @@ void qtest_set_expected_status(QTestState *s, int status)
 void qtest_kill_qemu(QTestState *s)
 {
     pid_t pid = s->qemu_pid;
+#ifndef _WIN32
     int wstatus;
+#else
+    DWORD ret, exit_code;
+#endif
 
     /* Skip wait if qtest_probe_child already reaped.  */
     if (pid != -1) {
+#ifndef _WIN32
         kill(pid, SIGTERM);
         TFR(pid = waitpid(s->qemu_pid, &s->wstatus, 0));
         assert(pid == s->qemu_pid);
+#else
+        TerminateProcess((HANDLE)pid, s->expected_status);
+        ret = WaitForSingleObject((HANDLE)pid, INFINITE);
+        assert(ret == WAIT_OBJECT_0);
+#endif
         s->qemu_pid = -1;
     }
 
@@ -149,6 +181,7 @@ void qtest_kill_qemu(QTestState *s)
      * Check whether qemu exited with expected exit status; anything else is
      * fishy and should be logged with as much detail as possible.
      */
+#ifndef _WIN32
     wstatus = s->wstatus;
     if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != s->expected_status) {
         fprintf(stderr, "%s:%d: kill_qemu() tried to terminate QEMU "
@@ -165,6 +198,16 @@ void qtest_kill_qemu(QTestState *s)
                 __FILE__, __LINE__, sig, signame, dump);
         abort();
     }
+#else
+    GetExitCodeProcess((HANDLE)pid, &exit_code);
+    CloseHandle((HANDLE)pid);
+    if (exit_code != s->expected_status) {
+        fprintf(stderr, "%s:%d: kill_qemu() tried to terminate QEMU "
+                "process but encountered exit status %ld (expected %d)\n",
+                __FILE__, __LINE__, exit_code, s->expected_status);
+        abort();
+    }
+#endif
 }
 
 static void kill_qemu_hook_func(void *s)
@@ -243,6 +286,38 @@ static const char *qtest_qemu_binary(void)
     return qemu_bin;
 }
 
+#ifdef _WIN32
+static pid_t qtest_create_process(char *cmd)
+{
+    STARTUPINFO si;
+    PROCESS_INFORMATION pi;
+    BOOL ret;
+
+    ZeroMemory(&si, sizeof(si));
+    si.cb = sizeof(si);
+    ZeroMemory(&pi, sizeof(pi));
+
+    ret = CreateProcess(NULL,   /* module name */
+                        cmd,    /* command line */
+                        NULL,   /* process handle not inheritable */
+                        NULL,   /* thread handle not inheritable */
+                        FALSE,  /* set handle inheritance to FALSE */
+                        0,      /* No creation flags */
+                        NULL,   /* use parent's environment block */
+                        NULL,   /* use parent's starting directory */
+                        &si,    /* pointer to STARTUPINFO structure */
+                        &pi     /* pointer to PROCESS_INFORMATION structure */
+                        );
+    if (ret == 0) {
+        fprintf(stderr, "%s:%d: unable to create a new process (%s)\n",
+                __FILE__, __LINE__, strerror(GetLastError()));
+        abort();
+    }
+
+    return (pid_t)pi.hProcess;
+}
+#endif /* _WIN32 */
+
 QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
 {
     QTestState *s;
@@ -270,6 +345,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
     unlink(socket_path);
     unlink(qmp_socket_path);
 
+    socket_init();
     sock = init_socket(socket_path);
     qmpsock = init_socket(qmp_socket_path);
 
@@ -278,7 +354,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
 
     qtest_add_abrt_handler(kill_qemu_hook_func, s);
 
-    command = g_strdup_printf("exec %s %s"
+    command = g_strdup_printf(CMD_EXEC "%s %s"
                               "-qtest unix:%s "
                               "-qtest-log %s "
                               "-chardev socket,path=%s,id=char0 "
@@ -287,7 +363,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
                               "%s"
                               " -accel qtest",
                               qemu_binary, tracearg, socket_path,
-                              getenv("QTEST_LOG") ? "/dev/fd/2" : "/dev/null",
+                              getenv("QTEST_LOG") ? DEV_STDERR : DEV_NULL,
                               qmp_socket_path,
                               extra_args ?: "");
 
@@ -296,6 +372,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
     s->pending_events = NULL;
     s->wstatus = 0;
     s->expected_status = 0;
+#ifndef _WIN32
     s->qemu_pid = fork();
     if (s->qemu_pid == 0) {
 #ifdef __linux__
@@ -318,6 +395,9 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
         execlp("/bin/sh", "sh", "-c", command, NULL);
         exit(1);
     }
+#else
+    s->qemu_pid = qtest_create_process(command);
+#endif /* _WIN32 */
 
     g_free(command);
     s->fd = socket_accept(sock);
@@ -336,9 +416,19 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
         s->irq_level[i] = false;
     }
 
+    /*
+     * Stopping QEMU for debugging is not supported on Windows.
+     *
+     * Using DebugActiveProcess() API can suspend the QEMU process,
+     * but gdb cannot attach to the process. Using the undocumented
+     * NtSuspendProcess() can suspend the QEMU process and gdb can
+     * attach to the process, but gdb cannot resume it.
+     */
+#ifndef _WIN32
     if (getenv("QTEST_STOP")) {
         kill(s->qemu_pid, SIGSTOP);
     }
+#endif
 
     /* ask endianness of the target */
 
@@ -392,6 +482,7 @@ QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd)
     g_assert_true(sock_dir != NULL);
     sock_path = g_strdup_printf("%s/sock", sock_dir);
 
+    socket_init();
     sock_fd_init = init_socket(sock_path);
 
     qts = qtest_initf("-chardev socket,id=s0,path=%s -serial chardev:s0 %s",
-- 
2.34.1



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

* [PATCH 12/18] tests/qtest: migration-test: Make sure QEMU process "to" exited after migration is canceled
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
                   ` (10 preceding siblings ...)
  2022-10-06 15:11 ` [PATCH 11/18] tests/qtest: Support libqtest to build and run on Windows Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 13/18] tests/qtest: libqtest: Correct the timeout unit of blocking receive calls for win32 Bin Meng
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Xuzhou Cheng, Bin Meng,
	Dr. David Alan Gilbert, Juan Quintela, Laurent Vivier,
	Paolo Bonzini, Thomas Huth

From: Xuzhou Cheng <xuzhou.cheng@windriver.com>

Make sure QEMU process "to" exited before launching another target
for migration in the test_multifd_tcp_cancel case.

Signed-off-by: Xuzhou Cheng <xuzhou.cheng@windriver.com>
Signed-off-by: Bin Meng <bin.meng@windriver.com>
---

(no changes since v3)

Changes in v3:
- Add a usleep(1) in the busy wait loop

Changes in v2:
- Change to a busy wait after migration is canceled

 tests/qtest/migration-test.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
index ef4427ff4d..e5ba0e21d2 100644
--- a/tests/qtest/migration-test.c
+++ b/tests/qtest/migration-test.c
@@ -2140,6 +2140,10 @@ static void test_multifd_tcp_cancel(void)
     wait_for_migration_pass(from);
 
     migrate_cancel(from);
+    /* Make sure QEMU process "to" exited */
+    while (qtest_probe_child(to)) {
+        usleep(1);
+    }
 
     args = (MigrateStart){
         .only_target = true,
-- 
2.34.1



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

* [PATCH 13/18] tests/qtest: libqtest: Correct the timeout unit of blocking receive calls for win32
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
                   ` (11 preceding siblings ...)
  2022-10-06 15:11 ` [PATCH 12/18] tests/qtest: migration-test: Make sure QEMU process "to" exited after migration is canceled Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 14/18] io/channel-watch: Drop a superfluous '#ifdef WIN32' Bin Meng
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Bin Meng, Laurent Vivier, Paolo Bonzini,
	Thomas Huth

From: Bin Meng <bin.meng@windriver.com>

Some qtest cases don't get response from the QEMU executable under
test in time on Windows. It turns out that the socket receive call
got timeout before it receive the complete response.

The timeout value is supposed to be set to 50 seconds via the
setsockopt() call, but there is a difference among platforms.
The timeout unit of blocking receive calls is measured in
seconds on non-Windows platforms but milliseconds on Windows.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---

(no changes since v1)

 tests/qtest/libqtest.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index ecd22cdb11..d52883c361 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -36,13 +36,14 @@
 #include "qapi/qmp/qstring.h"
 
 #define MAX_IRQ 256
-#define SOCKET_TIMEOUT 50
 
 #ifndef _WIN32
+# define SOCKET_TIMEOUT 50
 # define CMD_EXEC   "exec "
 # define DEV_STDERR "/dev/fd/2"
 # define DEV_NULL   "/dev/null"
 #else
+# define SOCKET_TIMEOUT 50000
 # define CMD_EXEC   ""
 # define DEV_STDERR "2"
 # define DEV_NULL   "nul"
@@ -103,8 +104,16 @@ static int socket_accept(int sock)
     struct sockaddr_un addr;
     socklen_t addrlen;
     int ret;
+    /*
+     * timeout unit of blocking receive calls is different among platfoms.
+     * It's in seconds on non-Windows platforms but milliseconds on Windows.
+     */
+#ifndef _WIN32
     struct timeval timeout = { .tv_sec = SOCKET_TIMEOUT,
                                .tv_usec = 0 };
+#else
+    DWORD timeout = SOCKET_TIMEOUT;
+#endif
 
     if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO,
                    (void *)&timeout, sizeof(timeout))) {
-- 
2.34.1



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

* [PATCH 14/18] io/channel-watch: Drop a superfluous '#ifdef WIN32'
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
                   ` (12 preceding siblings ...)
  2022-10-06 15:11 ` [PATCH 13/18] tests/qtest: libqtest: Correct the timeout unit of blocking receive calls for win32 Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 15/18] io/channel-watch: Drop the unnecessary cast Bin Meng
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Bin Meng, Daniel P. Berrangé

From: Bin Meng <bin.meng@windriver.com>

In the win32 version qio_channel_create_socket_watch() body there is
no need to do a '#ifdef WIN32'.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---

(no changes since v1)

 io/channel-watch.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/io/channel-watch.c b/io/channel-watch.c
index 0289b3647c..89f3c8a88a 100644
--- a/io/channel-watch.c
+++ b/io/channel-watch.c
@@ -285,11 +285,9 @@ GSource *qio_channel_create_socket_watch(QIOChannel *ioc,
     GSource *source;
     QIOChannelSocketSource *ssource;
 
-#ifdef WIN32
     WSAEventSelect(socket, ioc->event,
                    FD_READ | FD_ACCEPT | FD_CLOSE |
                    FD_CONNECT | FD_WRITE | FD_OOB);
-#endif
 
     source = g_source_new(&qio_channel_socket_source_funcs,
                           sizeof(QIOChannelSocketSource));
-- 
2.34.1



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

* [PATCH 15/18] io/channel-watch: Drop the unnecessary cast
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
                   ` (13 preceding siblings ...)
  2022-10-06 15:11 ` [PATCH 14/18] io/channel-watch: Drop a superfluous '#ifdef WIN32' Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 16/18] io/channel-watch: Fix socket watch on Windows Bin Meng
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Bin Meng, Daniel P. Berrangé

From: Bin Meng <bin.meng@windriver.com>

There is no need to do a type cast on ssource->socket as it is
already declared as a SOCKET.

Suggested-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---

(no changes since v2)

Changes in v2:
- new patch: "io/channel-watch: Drop the unnecessary cast"

 io/channel-watch.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/io/channel-watch.c b/io/channel-watch.c
index 89f3c8a88a..43d38494f7 100644
--- a/io/channel-watch.c
+++ b/io/channel-watch.c
@@ -130,13 +130,13 @@ qio_channel_socket_source_check(GSource *source)
     FD_ZERO(&wfds);
     FD_ZERO(&xfds);
     if (ssource->condition & G_IO_IN) {
-        FD_SET((SOCKET)ssource->socket, &rfds);
+        FD_SET(ssource->socket, &rfds);
     }
     if (ssource->condition & G_IO_OUT) {
-        FD_SET((SOCKET)ssource->socket, &wfds);
+        FD_SET(ssource->socket, &wfds);
     }
     if (ssource->condition & G_IO_PRI) {
-        FD_SET((SOCKET)ssource->socket, &xfds);
+        FD_SET(ssource->socket, &xfds);
     }
     ssource->revents = 0;
     if (select(0, &rfds, &wfds, &xfds, &tv0) == 0) {
-- 
2.34.1



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

* [PATCH 16/18] io/channel-watch: Fix socket watch on Windows
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
                   ` (14 preceding siblings ...)
  2022-10-06 15:11 ` [PATCH 15/18] io/channel-watch: Drop the unnecessary cast Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 17/18] .gitlab-ci.d/windows.yml: Increase the timeout to 90 minutes Bin Meng
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Bin Meng, Daniel P. Berrangé

From: Bin Meng <bin.meng@windriver.com>

Random failure was observed when running qtests on Windows due to
"Broken pipe" detected by qmp_fd_receive(). What happened is that
the qtest executable sends testing data over a socket to the QEMU
under test but no response is received. The errno of the recv()
call from the qtest executable indicates ETIMEOUT, due to the qmp
chardev's tcp_chr_read() is never called to receive testing data
hence no response is sent to the other side.

tcp_chr_read() is registered as the callback of the socket watch
GSource. The reason of the callback not being called by glib, is
that the source check fails to indicate the source is ready. There
are two socket watch sources created to monitor the same socket
event object from the char-socket backend in update_ioc_handlers().
During the source check phase, qio_channel_socket_source_check()
calls WSAEnumNetworkEvents() to discover occurrences of network
events for the indicated socket, clear internal network event records,
and reset the event object. Testing shows that if we don't reset the
event object by not passing the event handle to WSAEnumNetworkEvents()
the symptom goes away and qtest runs very stably.

It seems we don't need to call WSAEnumNetworkEvents() at all, as we
don't parse the result of WSANETWORKEVENTS returned from this API.
We use select() to poll the socket status. Fix this instability by
dropping the WSAEnumNetworkEvents() call.

Some side notes:

During the testing, I removed the following codes in update_ioc_handlers():

  remove_hup_source(s);
  s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP);
  g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup,
                        chr, NULL);
  g_source_attach(s->hup_source, chr->gcontext);

and such change also makes the symptom go away.

And if I moved the above codes to the beginning, before the call to
io_add_watch_poll(), the symptom also goes away.

It seems two sources watching on the same socket event object is
the key that leads to the instability. The order of adding a source
watch seems to also play a role but I can't explain why.
Hopefully a Windows and glib expert could explain this behavior.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
---

(no changes since v1)

 io/channel-watch.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/io/channel-watch.c b/io/channel-watch.c
index 43d38494f7..ad7c568a84 100644
--- a/io/channel-watch.c
+++ b/io/channel-watch.c
@@ -115,17 +115,13 @@ static gboolean
 qio_channel_socket_source_check(GSource *source)
 {
     static struct timeval tv0;
-
     QIOChannelSocketSource *ssource = (QIOChannelSocketSource *)source;
-    WSANETWORKEVENTS ev;
     fd_set rfds, wfds, xfds;
 
     if (!ssource->condition) {
         return 0;
     }
 
-    WSAEnumNetworkEvents(ssource->socket, ssource->ioc->event, &ev);
-
     FD_ZERO(&rfds);
     FD_ZERO(&wfds);
     FD_ZERO(&xfds);
-- 
2.34.1



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

* [PATCH 17/18] .gitlab-ci.d/windows.yml: Increase the timeout to 90 minutes
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
                   ` (15 preceding siblings ...)
  2022-10-06 15:11 ` [PATCH 16/18] io/channel-watch: Fix socket watch on Windows Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:11 ` [PATCH 18/18] tests/qtest: Enable qtest build on Windows Bin Meng
  2022-10-06 15:17 ` [PATCH 00/18] tests/qtest: Enable running qtest " Bin Meng
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Bin Meng, Alex Bennée, Beraldo Leal,
	Philippe Mathieu-Daudé, Thomas Huth,
	Wainer dos Santos Moschetta

From: Bin Meng <bin.meng@windriver.com>

commit 9f8e6cad65a6 ("gitlab-ci: Speed up the msys2-64bit job by using --without-default-devices"
changed to compile QEMU with the --without-default-devices switch for
the msys2-64bit job, due to the build could not complete within the
project timeout (1h), and also mentioned that a bigger timeout was
getting ignored on the shared Gitlab-CI Windows runners.

However as of today it seems the shared Gitlab-CI Windows runners does
honor the job timeout, and the runner has the timeout limit of 2h, so
let's increase the timeout to 90 minutes and drop the configure switch
"--without-default-devices" to get a larger build coverage.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
---

(no changes since v2)

Changes in v2:
- Change the timeout limit to 90 minutes

 .gitlab-ci.d/windows.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.gitlab-ci.d/windows.yml b/.gitlab-ci.d/windows.yml
index a3e7a37022..093276ddbc 100644
--- a/.gitlab-ci.d/windows.yml
+++ b/.gitlab-ci.d/windows.yml
@@ -10,7 +10,7 @@
       - ${CI_PROJECT_DIR}/msys64/var/cache
   needs: []
   stage: build
-  timeout: 70m
+  timeout: 90m
   before_script:
   - If ( !(Test-Path -Path msys64\var\cache ) ) {
       mkdir msys64\var\cache
@@ -60,7 +60,7 @@ msys2-64bit:
   - $env:MSYSTEM = 'MINGW64'     # Start a 64 bit Mingw environment
   - $env:MSYS = 'winsymlinks:native' # Enable native Windows symlink
   - .\msys64\usr\bin\bash -lc './configure --target-list=x86_64-softmmu
-      --enable-capstone --without-default-devices'
+      --enable-capstone'
   - .\msys64\usr\bin\bash -lc 'make'
   - .\msys64\usr\bin\bash -lc 'make check || { cat build/meson-logs/testlog.txt; exit 1; } ;'
 
-- 
2.34.1



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

* [PATCH 18/18] tests/qtest: Enable qtest build on Windows
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
                   ` (16 preceding siblings ...)
  2022-10-06 15:11 ` [PATCH 17/18] .gitlab-ci.d/windows.yml: Increase the timeout to 90 minutes Bin Meng
@ 2022-10-06 15:11 ` Bin Meng
  2022-10-06 15:17 ` [PATCH 00/18] tests/qtest: Enable running qtest " Bin Meng
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:11 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Bin Meng, Thomas Huth, Laurent Vivier,
	Paolo Bonzini

From: Bin Meng <bin.meng@windriver.com>

Now that we have fixed various test case issues as seen when running
on Windows, let's enable the qtest build on Windows.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
---

Changes in v3:
- Drop the host test

Changes in v2:
- new patch: "tests/qtest: Enable qtest build on Windows"

 tests/qtest/meson.build | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 455f1bbb7e..8701c3a8e7 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -1,9 +1,3 @@
-# All QTests for now are POSIX-only, but the dependencies are
-# really in libqtest, not in the testcases themselves.
-if not config_host.has_key('CONFIG_POSIX')
-  subdir_done()
-endif
-
 slow_qtests = {
   'ahci-test' : 60,
   'bios-tables-test' : 120,
-- 
2.34.1



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

* Re: [PATCH 00/18] tests/qtest: Enable running qtest on Windows
  2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
                   ` (17 preceding siblings ...)
  2022-10-06 15:11 ` [PATCH 18/18] tests/qtest: Enable qtest build on Windows Bin Meng
@ 2022-10-06 15:17 ` Bin Meng
  18 siblings, 0 replies; 20+ messages in thread
From: Bin Meng @ 2022-10-06 15:17 UTC (permalink / raw)
  To: qemu-devel
  Cc: Marc-André Lureau, Alex Bennée, Beraldo Leal,
	Christian Schoenebeck, Daniel P. Berrangé,
	Dr. David Alan Gilbert, Eduardo Habkost, Gerd Hoffmann, Greg Kurz,
	Hanna Reitz, Juan Quintela, Kevin Wolf, Laurent Vivier,
	Marcel Apfelbaum, Paolo Bonzini, Philippe Mathieu-Daudé,
	Richard Henderson, Thomas Huth, Wainer dos Santos Moschetta,
	Yanan Wang, qemu-block

On Thu, Oct 6, 2022 at 11:11 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> In preparation to adding virtio-9p support on Windows, this series
> enables running qtest on Windows, so that we can run the virtio-9p
> tests on Windows to make sure it does not break accidently.
>
> Changes in v5:
> - Rebase on qemu/master
> - Drop patches that are already merged
> - Use g_autoptr(GError)
> - Restore to v1 version which does not touch the posix implementation
> - Replace sighandler_t with its actual definition, since it is not
>   available on BSD hosts
>

Sorry, forgot to add the version PREFIX. Will resend.

Regards,
Bin


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

end of thread, other threads:[~2022-10-06 15:51 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-10-06 15:11 [PATCH 00/18] tests/qtest: Enable running qtest on Windows Bin Meng
2022-10-06 15:11 ` [PATCH 01/18] semihosting/arm-compat-semi: Avoid using hardcoded /tmp Bin Meng
2022-10-06 15:11 ` [PATCH 02/18] tcg: " Bin Meng
2022-10-06 15:11 ` [PATCH 03/18] util/qemu-sockets: Use g_get_tmp_dir() to get the directory for temporary files Bin Meng
2022-10-06 15:11 ` [PATCH 04/18] tests/qtest: migration-test: Avoid using hardcoded /tmp Bin Meng
2022-10-06 15:11 ` [PATCH 05/18] block/vvfat: Unify the mkdir() call Bin Meng
2022-10-06 15:11 ` [PATCH 06/18] fsdev/virtfs-proxy-helper: Use g_mkdir() Bin Meng
2022-10-06 15:11 ` [PATCH 07/18] hw/usb: dev-mtp: " Bin Meng
2022-10-06 15:11 ` [PATCH 08/18] accel/qtest: Support qtest accelerator for Windows Bin Meng
2022-10-06 15:11 ` [PATCH 09/18] tests/qtest: Use send/recv for socket communication Bin Meng
2022-10-06 15:11 ` [PATCH 10/18] tests/qtest: libqtest: Install signal handler via signal() Bin Meng
2022-10-06 15:11 ` [PATCH 11/18] tests/qtest: Support libqtest to build and run on Windows Bin Meng
2022-10-06 15:11 ` [PATCH 12/18] tests/qtest: migration-test: Make sure QEMU process "to" exited after migration is canceled Bin Meng
2022-10-06 15:11 ` [PATCH 13/18] tests/qtest: libqtest: Correct the timeout unit of blocking receive calls for win32 Bin Meng
2022-10-06 15:11 ` [PATCH 14/18] io/channel-watch: Drop a superfluous '#ifdef WIN32' Bin Meng
2022-10-06 15:11 ` [PATCH 15/18] io/channel-watch: Drop the unnecessary cast Bin Meng
2022-10-06 15:11 ` [PATCH 16/18] io/channel-watch: Fix socket watch on Windows Bin Meng
2022-10-06 15:11 ` [PATCH 17/18] .gitlab-ci.d/windows.yml: Increase the timeout to 90 minutes Bin Meng
2022-10-06 15:11 ` [PATCH 18/18] tests/qtest: Enable qtest build on Windows Bin Meng
2022-10-06 15:17 ` [PATCH 00/18] tests/qtest: Enable running qtest " Bin Meng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).