qga-pull-2023-05-04
-----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEwsLBCepDxjwUI+uE711egWG6hOcFAmRTf4EACgkQ711egWG6 hOdczhAAoMkw/bWZtpiEmeLIcliNVuF3gzouHRp2sBFeHCUtaE2jzmriuy4QqH81 G+kgqdEogqv7G5Qq2LXNcbSl76eZnKbumtlj+N4XIDoukPWUmItIjuM9NYM0U84Y DAsj6o8Kw1W+GMBmk6AuLFNYMwv41GS6RyvH/daeYEGmFf0jYIARpeldTUxkxY86 dfEylVPBfLjkctKfgl0h5GzRkYjmxyeisyigx4Wk8sVLvz5LLXx27sFVZ7//Rn16 7Ca88kzF9SUenF+ulV0HmVgR02b69w74izVII/Hh3pPkv4T2m98DeXlnHdyuc3Lb bWggM2pf1Yr/jUOPtscQ9IqKTdYTLKqaErVSQJYabG9lLXRerXLj8mhH/W070jzT hZwp+5VJzF/OykiM0PW/tI5a0Upg8/8w/LRPwuqP0nFsW5QYdAQXSFbtsUfVdPlE Htk66xoQTLJ2a38m5WCvaRL97psGHmVXuWq0VUByNCAlWv6EiAAbTZBimIo4FZj+ Ps6e7Tnvhv5kai2qZ4ijxJq88n9/mv8t0s/oD/BoGQMXmNn+87bR18byY5NZWi/4 CKk60zbmgo8fGZ/zzwk4T+48I3SLfM+wnHePYs8nrHgoqGVEUXsCdXUYifxIcpel Vnb1OHXN3n+U8LnleQ158oQcSVFicvwQMBkzM+mW16WMQlReRRM= =GvNm -----END PGP SIGNATURE----- Merge tag 'qga-pull-2023-05-04' of https://github.com/kostyanf14/qemu into staging qga-pull-2023-05-04 # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCgAdFiEEwsLBCepDxjwUI+uE711egWG6hOcFAmRTf4EACgkQ711egWG6 # hOdczhAAoMkw/bWZtpiEmeLIcliNVuF3gzouHRp2sBFeHCUtaE2jzmriuy4QqH81 # G+kgqdEogqv7G5Qq2LXNcbSl76eZnKbumtlj+N4XIDoukPWUmItIjuM9NYM0U84Y # DAsj6o8Kw1W+GMBmk6AuLFNYMwv41GS6RyvH/daeYEGmFf0jYIARpeldTUxkxY86 # dfEylVPBfLjkctKfgl0h5GzRkYjmxyeisyigx4Wk8sVLvz5LLXx27sFVZ7//Rn16 # 7Ca88kzF9SUenF+ulV0HmVgR02b69w74izVII/Hh3pPkv4T2m98DeXlnHdyuc3Lb # bWggM2pf1Yr/jUOPtscQ9IqKTdYTLKqaErVSQJYabG9lLXRerXLj8mhH/W070jzT # hZwp+5VJzF/OykiM0PW/tI5a0Upg8/8w/LRPwuqP0nFsW5QYdAQXSFbtsUfVdPlE # Htk66xoQTLJ2a38m5WCvaRL97psGHmVXuWq0VUByNCAlWv6EiAAbTZBimIo4FZj+ # Ps6e7Tnvhv5kai2qZ4ijxJq88n9/mv8t0s/oD/BoGQMXmNn+87bR18byY5NZWi/4 # CKk60zbmgo8fGZ/zzwk4T+48I3SLfM+wnHePYs8nrHgoqGVEUXsCdXUYifxIcpel # Vnb1OHXN3n+U8LnleQ158oQcSVFicvwQMBkzM+mW16WMQlReRRM= # =GvNm # -----END PGP SIGNATURE----- # gpg: Signature made Thu 04 May 2023 10:48:49 AM BST # gpg: using RSA key C2C2C109EA43C63C1423EB84EF5D5E8161BA84E7 # gpg: Good signature from "Kostiantyn Kostiuk (Upstream PR sign) <kkostiuk@redhat.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: C2C2 C109 EA43 C63C 1423 EB84 EF5D 5E81 61BA 84E7 * tag 'qga-pull-2023-05-04' of https://github.com/kostyanf14/qemu: qga: Fix suspend on Linux guests without systemd qga/commands-win32.c: Drop the check for _WIN32_WINNT >= 0x0601 qga: test: Add tests for `merged` flag qga: Add `merged` variant to GuestExecCaptureOutputMode qga: Refactor guest-exec capture-output to take enum qga/linux: add usb support to guest-get-fsinfo Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
f6b761bdbd
@ -879,7 +879,9 @@ static bool build_guest_fsinfo_for_pci_dev(char const *syspath,
|
||||
g_str_equal(driver, "sym53c8xx") ||
|
||||
g_str_equal(driver, "virtio-pci") ||
|
||||
g_str_equal(driver, "ahci") ||
|
||||
g_str_equal(driver, "nvme"))) {
|
||||
g_str_equal(driver, "nvme") ||
|
||||
g_str_equal(driver, "xhci_hcd") ||
|
||||
g_str_equal(driver, "ehci-pci"))) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -976,6 +978,8 @@ static bool build_guest_fsinfo_for_pci_dev(char const *syspath,
|
||||
}
|
||||
} else if (strcmp(driver, "nvme") == 0) {
|
||||
disk->bus_type = GUEST_DISK_BUS_TYPE_NVME;
|
||||
} else if (strcmp(driver, "ehci-pci") == 0 || strcmp(driver, "xhci_hcd") == 0) {
|
||||
disk->bus_type = GUEST_DISK_BUS_TYPE_USB;
|
||||
} else {
|
||||
g_debug("unknown driver '%s' (sysfs path '%s')", driver, syspath);
|
||||
goto cleanup;
|
||||
@ -1918,10 +1922,10 @@ static void guest_suspend(SuspendMode mode, Error **errp)
|
||||
if (systemd_supports_mode(mode, &local_err)) {
|
||||
mode_supported = true;
|
||||
systemd_suspend(mode, &local_err);
|
||||
}
|
||||
|
||||
if (!local_err) {
|
||||
return;
|
||||
if (!local_err) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
error_free(local_err);
|
||||
@ -1930,10 +1934,10 @@ static void guest_suspend(SuspendMode mode, Error **errp)
|
||||
if (pmutils_supports_mode(mode, &local_err)) {
|
||||
mode_supported = true;
|
||||
pmutils_suspend(mode, &local_err);
|
||||
}
|
||||
|
||||
if (!local_err) {
|
||||
return;
|
||||
if (!local_err) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
error_free(local_err);
|
||||
|
@ -484,7 +484,6 @@ static GuestDiskBusType win2qemu[] = {
|
||||
[BusTypeSata] = GUEST_DISK_BUS_TYPE_SATA,
|
||||
[BusTypeSd] = GUEST_DISK_BUS_TYPE_SD,
|
||||
[BusTypeMmc] = GUEST_DISK_BUS_TYPE_MMC,
|
||||
#if (_WIN32_WINNT >= 0x0601)
|
||||
[BusTypeVirtual] = GUEST_DISK_BUS_TYPE_VIRTUAL,
|
||||
[BusTypeFileBackedVirtual] = GUEST_DISK_BUS_TYPE_FILE_BACKED_VIRTUAL,
|
||||
/*
|
||||
@ -492,7 +491,6 @@ static GuestDiskBusType win2qemu[] = {
|
||||
*/
|
||||
[BusTypeSpaces] = GUEST_DISK_BUS_TYPE_UNKNOWN,
|
||||
[BusTypeNvme] = GUEST_DISK_BUS_TYPE_NVME,
|
||||
#endif
|
||||
};
|
||||
|
||||
static GuestDiskBusType find_bus_type(STORAGE_BUS_TYPE bus)
|
||||
|
@ -270,12 +270,26 @@ static void guest_exec_child_watch(GPid pid, gint status, gpointer data)
|
||||
g_spawn_close_pid(pid);
|
||||
}
|
||||
|
||||
/** Reset ignored signals back to default. */
|
||||
static void guest_exec_task_setup(gpointer data)
|
||||
{
|
||||
#if !defined(G_OS_WIN32)
|
||||
bool has_merge = *(bool *)data;
|
||||
struct sigaction sigact;
|
||||
|
||||
if (has_merge) {
|
||||
/*
|
||||
* FIXME: When `GLIB_VERSION_MIN_REQUIRED` is bumped to 2.58+, use
|
||||
* g_spawn_async_with_fds() to be portable on windows. The current
|
||||
* logic does not work on windows b/c `GSpawnChildSetupFunc` is run
|
||||
* inside the parent, not the child.
|
||||
*/
|
||||
if (dup2(STDOUT_FILENO, STDERR_FILENO) != 0) {
|
||||
slog("dup2() failed to merge stderr into stdout: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset ignored signals back to default. */
|
||||
memset(&sigact, 0, sizeof(struct sigaction));
|
||||
sigact.sa_handler = SIG_DFL;
|
||||
|
||||
@ -379,11 +393,23 @@ close:
|
||||
return false;
|
||||
}
|
||||
|
||||
static GuestExecCaptureOutputMode ga_parse_capture_output(
|
||||
GuestExecCaptureOutput *capture_output)
|
||||
{
|
||||
if (!capture_output)
|
||||
return GUEST_EXEC_CAPTURE_OUTPUT_MODE_NONE;
|
||||
else if (capture_output->type == QTYPE_QBOOL)
|
||||
return capture_output->u.flag ? GUEST_EXEC_CAPTURE_OUTPUT_MODE_SEPARATED
|
||||
: GUEST_EXEC_CAPTURE_OUTPUT_MODE_NONE;
|
||||
else
|
||||
return capture_output->u.mode;
|
||||
}
|
||||
|
||||
GuestExec *qmp_guest_exec(const char *path,
|
||||
bool has_arg, strList *arg,
|
||||
bool has_env, strList *env,
|
||||
const char *input_data,
|
||||
bool has_capture_output, bool capture_output,
|
||||
GuestExecCaptureOutput *capture_output,
|
||||
Error **errp)
|
||||
{
|
||||
GPid pid;
|
||||
@ -396,7 +422,9 @@ GuestExec *qmp_guest_exec(const char *path,
|
||||
gint in_fd, out_fd, err_fd;
|
||||
GIOChannel *in_ch, *out_ch, *err_ch;
|
||||
GSpawnFlags flags;
|
||||
bool has_output = (has_capture_output && capture_output);
|
||||
bool has_output = false;
|
||||
bool has_merge = false;
|
||||
GuestExecCaptureOutputMode output_mode;
|
||||
g_autofree uint8_t *input = NULL;
|
||||
size_t ninput = 0;
|
||||
|
||||
@ -415,12 +443,36 @@ GuestExec *qmp_guest_exec(const char *path,
|
||||
|
||||
flags = G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD |
|
||||
G_SPAWN_SEARCH_PATH_FROM_ENVP;
|
||||
if (!has_output) {
|
||||
|
||||
output_mode = ga_parse_capture_output(capture_output);
|
||||
switch (output_mode) {
|
||||
case GUEST_EXEC_CAPTURE_OUTPUT_MODE_NONE:
|
||||
flags |= G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL;
|
||||
break;
|
||||
case GUEST_EXEC_CAPTURE_OUTPUT_MODE_STDOUT:
|
||||
has_output = true;
|
||||
flags |= G_SPAWN_STDERR_TO_DEV_NULL;
|
||||
break;
|
||||
case GUEST_EXEC_CAPTURE_OUTPUT_MODE_STDERR:
|
||||
has_output = true;
|
||||
flags |= G_SPAWN_STDOUT_TO_DEV_NULL;
|
||||
break;
|
||||
case GUEST_EXEC_CAPTURE_OUTPUT_MODE_SEPARATED:
|
||||
has_output = true;
|
||||
break;
|
||||
#if !defined(G_OS_WIN32)
|
||||
case GUEST_EXEC_CAPTURE_OUTPUT_MODE_MERGED:
|
||||
has_output = true;
|
||||
has_merge = true;
|
||||
break;
|
||||
#endif
|
||||
case GUEST_EXEC_CAPTURE_OUTPUT_MODE__MAX:
|
||||
/* Silence warning; impossible branch */
|
||||
break;
|
||||
}
|
||||
|
||||
ret = g_spawn_async_with_pipes(NULL, argv, envp, flags,
|
||||
guest_exec_task_setup, NULL, &pid, input_data ? &in_fd : NULL,
|
||||
guest_exec_task_setup, &has_merge, &pid, input_data ? &in_fd : NULL,
|
||||
has_output ? &out_fd : NULL, has_output ? &err_fd : NULL, &gerr);
|
||||
if (!ret) {
|
||||
error_setg(errp, QERR_QGA_COMMAND_FAILED, gerr->message);
|
||||
|
@ -1200,6 +1200,40 @@
|
||||
{ 'struct': 'GuestExec',
|
||||
'data': { 'pid': 'int'} }
|
||||
|
||||
##
|
||||
# @GuestExecCaptureOutputMode:
|
||||
#
|
||||
# An enumeration of guest-exec capture modes.
|
||||
#
|
||||
# @none: do not capture any output
|
||||
# @stdout: only capture stdout
|
||||
# @stderr: only capture stderr
|
||||
# @separated: capture both stdout and stderr, but separated into
|
||||
# GuestExecStatus out-data and err-data, respectively
|
||||
# @merged: capture both stdout and stderr, but merge together
|
||||
# into out-data. not effective on windows guests.
|
||||
#
|
||||
# Since: 8.0
|
||||
##
|
||||
{ 'enum': 'GuestExecCaptureOutputMode',
|
||||
'data': [ 'none', 'stdout', 'stderr', 'separated',
|
||||
{ 'name': 'merged', 'if': { 'not': 'CONFIG_WIN32' } } ] }
|
||||
|
||||
##
|
||||
# @GuestExecCaptureOutput:
|
||||
#
|
||||
# Controls what guest-exec output gets captures.
|
||||
#
|
||||
# @flag: captures both stdout and stderr if true. Equivalent
|
||||
# to GuestExecCaptureOutputMode::all. (since 2.5)
|
||||
# @mode: capture mode; preferred interface
|
||||
#
|
||||
# Since: 8.0
|
||||
##
|
||||
{ 'alternate': 'GuestExecCaptureOutput',
|
||||
'data': { 'flag': 'bool',
|
||||
'mode': 'GuestExecCaptureOutputMode'} }
|
||||
|
||||
##
|
||||
# @guest-exec:
|
||||
#
|
||||
@ -1218,7 +1252,7 @@
|
||||
##
|
||||
{ 'command': 'guest-exec',
|
||||
'data': { 'path': 'str', '*arg': ['str'], '*env': ['str'],
|
||||
'*input-data': 'str', '*capture-output': 'bool' },
|
||||
'*input-data': 'str', '*capture-output': 'GuestExecCaptureOutput' },
|
||||
'returns': 'GuestExec' }
|
||||
|
||||
|
||||
|
@ -755,32 +755,16 @@ static void test_qga_fsfreeze_status(gconstpointer fix)
|
||||
g_assert_cmpstr(status, ==, "thawed");
|
||||
}
|
||||
|
||||
static void test_qga_guest_exec(gconstpointer fix)
|
||||
static QDict *wait_for_guest_exec_completion(int fd, int64_t pid)
|
||||
{
|
||||
const TestFixture *fixture = fix;
|
||||
g_autoptr(QDict) ret = NULL;
|
||||
QDict *val;
|
||||
const gchar *out;
|
||||
g_autofree guchar *decoded = NULL;
|
||||
int64_t pid, now, exitcode;
|
||||
gsize len;
|
||||
QDict *ret = NULL;
|
||||
int64_t now;
|
||||
bool exited;
|
||||
QDict *val;
|
||||
|
||||
/* exec 'echo foo bar' */
|
||||
ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
|
||||
" 'path': '/bin/echo', 'arg': [ '-n', '\" test_str \"' ],"
|
||||
" 'capture-output': true } }");
|
||||
g_assert_nonnull(ret);
|
||||
qmp_assert_no_error(ret);
|
||||
val = qdict_get_qdict(ret, "return");
|
||||
pid = qdict_get_int(val, "pid");
|
||||
g_assert_cmpint(pid, >, 0);
|
||||
qobject_unref(ret);
|
||||
|
||||
/* wait for completion */
|
||||
now = g_get_monotonic_time();
|
||||
do {
|
||||
ret = qmp_fd(fixture->fd,
|
||||
ret = qmp_fd(fd,
|
||||
"{'execute': 'guest-exec-status',"
|
||||
" 'arguments': { 'pid': %" PRId64 " } }", pid);
|
||||
g_assert_nonnull(ret);
|
||||
@ -793,7 +777,34 @@ static void test_qga_guest_exec(gconstpointer fix)
|
||||
g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND);
|
||||
g_assert(exited);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void test_qga_guest_exec(gconstpointer fix)
|
||||
{
|
||||
const TestFixture *fixture = fix;
|
||||
g_autoptr(QDict) ret = NULL;
|
||||
QDict *val;
|
||||
const gchar *out;
|
||||
g_autofree guchar *decoded = NULL;
|
||||
int64_t pid, exitcode;
|
||||
gsize len;
|
||||
|
||||
/* exec 'echo foo bar' */
|
||||
ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
|
||||
" 'path': '/bin/echo', 'arg': [ '-n', '\" test_str \"' ],"
|
||||
" 'capture-output': true } }");
|
||||
g_assert_nonnull(ret);
|
||||
qmp_assert_no_error(ret);
|
||||
val = qdict_get_qdict(ret, "return");
|
||||
pid = qdict_get_int(val, "pid");
|
||||
g_assert_cmpint(pid, >, 0);
|
||||
qobject_unref(ret);
|
||||
|
||||
ret = wait_for_guest_exec_completion(fixture->fd, pid);
|
||||
|
||||
/* check stdout */
|
||||
val = qdict_get_qdict(ret, "return");
|
||||
exitcode = qdict_get_int(val, "exitcode");
|
||||
g_assert_cmpint(exitcode, ==, 0);
|
||||
out = qdict_get_str(val, "out-data");
|
||||
@ -802,6 +813,115 @@ static void test_qga_guest_exec(gconstpointer fix)
|
||||
g_assert_cmpstr((char *)decoded, ==, "\" test_str \"");
|
||||
}
|
||||
|
||||
#if defined(G_OS_WIN32)
|
||||
static void test_qga_guest_exec_separated(gconstpointer fix)
|
||||
{
|
||||
}
|
||||
static void test_qga_guest_exec_merged(gconstpointer fix)
|
||||
{
|
||||
const TestFixture *fixture = fix;
|
||||
g_autoptr(QDict) ret = NULL;
|
||||
QDict *val;
|
||||
const gchar *class, *desc;
|
||||
g_autofree guchar *decoded = NULL;
|
||||
|
||||
/* exec 'echo foo bar' */
|
||||
ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
|
||||
" 'path': 'echo',"
|
||||
" 'arg': [ 'execution never reaches here' ],"
|
||||
" 'capture-output': 'merged' } }");
|
||||
|
||||
g_assert_nonnull(ret);
|
||||
val = qdict_get_qdict(ret, "error");
|
||||
g_assert_nonnull(val);
|
||||
class = qdict_get_str(val, "class");
|
||||
desc = qdict_get_str(val, "desc");
|
||||
g_assert_cmpstr(class, ==, "GenericError");
|
||||
g_assert_cmpint(strlen(desc), >, 0);
|
||||
}
|
||||
#else
|
||||
static void test_qga_guest_exec_separated(gconstpointer fix)
|
||||
{
|
||||
const TestFixture *fixture = fix;
|
||||
g_autoptr(QDict) ret = NULL;
|
||||
QDict *val;
|
||||
const gchar *out, *err;
|
||||
g_autofree guchar *out_decoded = NULL;
|
||||
g_autofree guchar *err_decoded = NULL;
|
||||
int64_t pid, exitcode;
|
||||
gsize len;
|
||||
|
||||
/* exec 'echo foo bar' */
|
||||
ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
|
||||
" 'path': '/bin/bash',"
|
||||
" 'arg': [ '-c', 'for i in $(seq 4); do if (( $i %% 2 )); then echo stdout; else echo stderr 1>&2; fi; done;' ],"
|
||||
" 'capture-output': 'separated' } }");
|
||||
g_assert_nonnull(ret);
|
||||
qmp_assert_no_error(ret);
|
||||
val = qdict_get_qdict(ret, "return");
|
||||
pid = qdict_get_int(val, "pid");
|
||||
g_assert_cmpint(pid, >, 0);
|
||||
qobject_unref(ret);
|
||||
|
||||
ret = wait_for_guest_exec_completion(fixture->fd, pid);
|
||||
|
||||
val = qdict_get_qdict(ret, "return");
|
||||
exitcode = qdict_get_int(val, "exitcode");
|
||||
g_assert_cmpint(exitcode, ==, 0);
|
||||
|
||||
/* check stdout */
|
||||
out = qdict_get_str(val, "out-data");
|
||||
out_decoded = g_base64_decode(out, &len);
|
||||
g_assert_cmpint(len, ==, 14);
|
||||
g_assert_cmpstr((char *)out_decoded, ==, "stdout\nstdout\n");
|
||||
|
||||
/* check stderr */
|
||||
err = qdict_get_try_str(val, "err-data");
|
||||
err_decoded = g_base64_decode(err, &len);
|
||||
g_assert_cmpint(len, ==, 14);
|
||||
g_assert_cmpstr((char *)err_decoded, ==, "stderr\nstderr\n");
|
||||
}
|
||||
|
||||
static void test_qga_guest_exec_merged(gconstpointer fix)
|
||||
{
|
||||
const TestFixture *fixture = fix;
|
||||
g_autoptr(QDict) ret = NULL;
|
||||
QDict *val;
|
||||
const gchar *out, *err;
|
||||
g_autofree guchar *decoded = NULL;
|
||||
int64_t pid, exitcode;
|
||||
gsize len;
|
||||
|
||||
/* exec 'echo foo bar' */
|
||||
ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
|
||||
" 'path': '/bin/bash',"
|
||||
" 'arg': [ '-c', 'for i in $(seq 4); do if (( $i %% 2 )); then echo stdout; else echo stderr 1>&2; fi; done;' ],"
|
||||
" 'capture-output': 'merged' } }");
|
||||
g_assert_nonnull(ret);
|
||||
qmp_assert_no_error(ret);
|
||||
val = qdict_get_qdict(ret, "return");
|
||||
pid = qdict_get_int(val, "pid");
|
||||
g_assert_cmpint(pid, >, 0);
|
||||
qobject_unref(ret);
|
||||
|
||||
ret = wait_for_guest_exec_completion(fixture->fd, pid);
|
||||
|
||||
val = qdict_get_qdict(ret, "return");
|
||||
exitcode = qdict_get_int(val, "exitcode");
|
||||
g_assert_cmpint(exitcode, ==, 0);
|
||||
|
||||
/* check stdout */
|
||||
out = qdict_get_str(val, "out-data");
|
||||
decoded = g_base64_decode(out, &len);
|
||||
g_assert_cmpint(len, ==, 28);
|
||||
g_assert_cmpstr((char *)decoded, ==, "stdout\nstderr\nstdout\nstderr\n");
|
||||
|
||||
/* check stderr */
|
||||
err = qdict_get_try_str(val, "err-data");
|
||||
g_assert_null(err);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void test_qga_guest_exec_invalid(gconstpointer fix)
|
||||
{
|
||||
const TestFixture *fixture = fix;
|
||||
@ -972,6 +1092,10 @@ int main(int argc, char **argv)
|
||||
g_test_add_data_func("/qga/blockedrpcs", NULL, test_qga_blockedrpcs);
|
||||
g_test_add_data_func("/qga/config", NULL, test_qga_config);
|
||||
g_test_add_data_func("/qga/guest-exec", &fix, test_qga_guest_exec);
|
||||
g_test_add_data_func("/qga/guest-exec-separated", &fix,
|
||||
test_qga_guest_exec_separated);
|
||||
g_test_add_data_func("/qga/guest-exec-merged", &fix,
|
||||
test_qga_guest_exec_merged);
|
||||
g_test_add_data_func("/qga/guest-exec-invalid", &fix,
|
||||
test_qga_guest_exec_invalid);
|
||||
g_test_add_data_func("/qga/guest-get-osinfo", &fix,
|
||||
|
Loading…
x
Reference in New Issue
Block a user