vl: Add an -action option specifying response to guest events

Several command line options currently in use are meant to modify
the behavior of QEMU in response to certain guest events like:
-no-reboot, -no-shutdown, -watchdog-action.

These can be grouped into a single option of the form:

-action event=action

Which can be used to specify the existing options above in the
following format:

-action reboot=none|shutdown
-action shutdown=poweroff|pause
-action watchdog=reset|shutdown|poweroff|pause|debug|none|inject-nmi

This is done in preparation for adding yet another option of this
type, which modifies the QEMU behavior when a guest panic occurs.

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
Message-Id: <1607705564-26264-2-git-send-email-alejandro.j.jimenez@oracle.com>
[Use QemuOpts help support, invoke QMP command. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Alejandro Jimenez 2020-12-11 11:52:41 -05:00 committed by Paolo Bonzini
parent e6dba04813
commit 2a5ad60b54
2 changed files with 78 additions and 2 deletions

View File

@ -3894,6 +3894,28 @@ SRST
changes to the disk image. changes to the disk image.
ERST ERST
DEF("action", HAS_ARG, QEMU_OPTION_action,
"-action reboot=none|shutdown\n"
" action when guest reboots [default=none]\n"
"-action shutdown=poweroff|pause\n"
" action when guest shuts down [default=poweroff]\n"
"-action watchdog=reset|shutdown|poweroff|inject-nmi|pause|debug|none\n"
" action when watchdog fires [default=reset]\n",
QEMU_ARCH_ALL)
SRST
``-action event=action``
The action parameter serves to modify QEMU's default behavior when
certain guest events occur. It provides a generic method for specifying the
same behaviors that are modified by the ``-no-reboot`` and ``-no-shutdown``
parameters.
Examples:
``-action reboot=shutdown,shutdown=pause``
``-watchdog i6300esb -action watchdog=pause``
ERST
DEF("loadvm", HAS_ARG, QEMU_OPTION_loadvm, \ DEF("loadvm", HAS_ARG, QEMU_OPTION_loadvm, \
"-loadvm [tag|id]\n" \ "-loadvm [tag|id]\n" \
" start right away with a saved state (loadvm in monitor)\n", " start right away with a saved state (loadvm in monitor)\n",

View File

@ -30,6 +30,7 @@
#include "hw/boards.h" #include "hw/boards.h"
#include "hw/qdev-properties.h" #include "hw/qdev-properties.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "qemu-version.h" #include "qemu-version.h"
#include "qemu/cutils.h" #include "qemu/cutils.h"
#include "qemu/help_option.h" #include "qemu/help_option.h"
@ -477,6 +478,25 @@ static QemuOptsList qemu_fw_cfg_opts = {
}, },
}; };
static QemuOptsList qemu_action_opts = {
.name = "action",
.merge_lists = true,
.head = QTAILQ_HEAD_INITIALIZER(qemu_action_opts.head),
.desc = {
{
.name = "shutdown",
.type = QEMU_OPT_STRING,
},{
.name = "reboot",
.type = QEMU_OPT_STRING,
},{
.name = "watchdog",
.type = QEMU_OPT_STRING,
},
{ /* end of list */ }
},
};
/** /**
* Get machine options * Get machine options
* *
@ -2298,6 +2318,26 @@ static void qemu_process_sugar_options(void)
} }
} }
/* -action processing */
/*
* Process all the -action parameters parsed from cmdline.
*/
static int process_runstate_actions(void *opaque, QemuOpts *opts, Error **errp)
{
Error *local_err = NULL;
QDict *qdict = qemu_opts_to_qdict(opts, NULL);
QObject *ret = NULL;
qmp_marshal_set_action(qdict, &ret, &local_err);
qobject_unref(ret);
qobject_unref(qdict);
if (local_err) {
error_propagate(errp, local_err);
return 1;
}
return 0;
}
static void qemu_process_early_options(void) static void qemu_process_early_options(void)
{ {
#ifdef CONFIG_SECCOMP #ifdef CONFIG_SECCOMP
@ -2310,6 +2350,11 @@ static void qemu_process_early_options(void)
qemu_opts_foreach(qemu_find_opts("name"), qemu_opts_foreach(qemu_find_opts("name"),
parse_name, NULL, &error_fatal); parse_name, NULL, &error_fatal);
if (qemu_opts_foreach(qemu_find_opts("action"),
process_runstate_actions, NULL, &error_fatal)) {
exit(1);
}
#ifndef _WIN32 #ifndef _WIN32
qemu_opts_foreach(qemu_find_opts("add-fd"), qemu_opts_foreach(qemu_find_opts("add-fd"),
parse_add_fd, NULL, &error_fatal); parse_add_fd, NULL, &error_fatal);
@ -2560,6 +2605,7 @@ void qemu_init(int argc, char **argv, char **envp)
qemu_add_opts(&qemu_icount_opts); qemu_add_opts(&qemu_icount_opts);
qemu_add_opts(&qemu_semihosting_config_opts); qemu_add_opts(&qemu_semihosting_config_opts);
qemu_add_opts(&qemu_fw_cfg_opts); qemu_add_opts(&qemu_fw_cfg_opts);
qemu_add_opts(&qemu_action_opts);
module_call_init(MODULE_INIT_OPTS); module_call_init(MODULE_INIT_OPTS);
error_init(argv[0]); error_init(argv[0]);
@ -3010,6 +3056,12 @@ void qemu_init(int argc, char **argv, char **envp)
} }
watchdog = optarg; watchdog = optarg;
break; break;
case QEMU_OPTION_action:
olist = qemu_find_opts("action");
if (!qemu_opts_parse_noisily(olist, optarg, false)) {
exit(1);
}
break;
case QEMU_OPTION_watchdog_action: case QEMU_OPTION_watchdog_action:
if (select_watchdog_action(optarg) == -1) { if (select_watchdog_action(optarg) == -1) {
error_report("unknown -watchdog-action parameter"); error_report("unknown -watchdog-action parameter");
@ -3155,10 +3207,12 @@ void qemu_init(int argc, char **argv, char **envp)
qemu_opts_parse_noisily(olist, "hpet=off", false); qemu_opts_parse_noisily(olist, "hpet=off", false);
break; break;
case QEMU_OPTION_no_reboot: case QEMU_OPTION_no_reboot:
reboot_action = REBOOT_ACTION_SHUTDOWN; olist = qemu_find_opts("action");
qemu_opts_parse_noisily(olist, "reboot=shutdown", false);
break; break;
case QEMU_OPTION_no_shutdown: case QEMU_OPTION_no_shutdown:
shutdown_action = SHUTDOWN_ACTION_PAUSE; olist = qemu_find_opts("action");
qemu_opts_parse_noisily(olist, "shutdown=pause", false);
break; break;
case QEMU_OPTION_show_cursor: case QEMU_OPTION_show_cursor:
warn_report("The -show-cursor option is deprecated. Please " warn_report("The -show-cursor option is deprecated. Please "