From 69c056fbc0cd57b4b2db7b3e823a9f6945756b38 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Fri, 28 Oct 2022 12:57:31 +0800 Subject: [PATCH] tests/qtest: libqtest: Introduce qtest_wait_qemu() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce an API for qtest to wait for the QEMU process to terminate. Suggested-by: Marc-André Lureau Signed-off-by: Bin Meng Reviewed-by: Marc-André Lureau Message-Id: <20221028045736.679903-7-bin.meng@windriver.com> Signed-off-by: Thomas Huth --- tests/qtest/libqtest.c | 63 +++++++++++++++++++++++++----------------- tests/qtest/libqtest.h | 9 ++++++ 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c index d12a604d78..e1e2d39a6e 100644 --- a/tests/qtest/libqtest.c +++ b/tests/qtest/libqtest.c @@ -156,37 +156,14 @@ void qtest_set_expected_status(QTestState *s, int status) s->expected_status = status; } -void qtest_kill_qemu(QTestState *s) +static void qtest_check_status(QTestState *s) { - pid_t pid = s->qemu_pid; -#ifndef _WIN32 - int wstatus; -#else - DWORD ret; -#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); - GetExitCodeProcess((HANDLE)pid, &s->exit_code); - CloseHandle((HANDLE)pid); -#endif - s->qemu_pid = -1; - } - /* * 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; + int wstatus = s->wstatus; if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != s->expected_status) { fprintf(stderr, "%s:%d: kill_qemu() tried to terminate QEMU " "process but encountered exit status %d (expected %d)\n", @@ -212,6 +189,42 @@ void qtest_kill_qemu(QTestState *s) #endif } +void qtest_wait_qemu(QTestState *s) +{ +#ifndef _WIN32 + pid_t pid; + + TFR(pid = waitpid(s->qemu_pid, &s->wstatus, 0)); + assert(pid == s->qemu_pid); +#else + DWORD ret; + + ret = WaitForSingleObject((HANDLE)s->qemu_pid, INFINITE); + assert(ret == WAIT_OBJECT_0); + GetExitCodeProcess((HANDLE)s->qemu_pid, &s->exit_code); + CloseHandle((HANDLE)s->qemu_pid); +#endif + + qtest_check_status(s); +} + +void qtest_kill_qemu(QTestState *s) +{ + /* Skip wait if qtest_probe_child() already reaped */ + if (s->qemu_pid != -1) { +#ifndef _WIN32 + kill(s->qemu_pid, SIGTERM); +#else + TerminateProcess((HANDLE)s->qemu_pid, s->expected_status); +#endif + qtest_wait_qemu(s); + s->qemu_pid = -1; + return; + } + + qtest_check_status(s); +} + static void kill_qemu_hook_func(void *s) { qtest_kill_qemu(s); diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h index 65c040e504..91a5f7edd9 100644 --- a/tests/qtest/libqtest.h +++ b/tests/qtest/libqtest.h @@ -75,6 +75,15 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args); */ QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd); +/** + * qtest_wait_qemu: + * @s: #QTestState instance to operate on. + * + * Wait for the QEMU process to terminate. It is safe to call this function + * multiple times. + */ +void qtest_wait_qemu(QTestState *s); + /** * qtest_kill_qemu: * @s: #QTestState instance to operate on.