#include "sysemu/numa.h"
#include "exec/gdbstub.h"
#include "qemu/timer.h"
-#include "sysemu/char.h"
+#include "chardev/char.h"
#include "qemu/bitmap.h"
#include "qemu/log.h"
#include "sysemu/blockdev.h"
#include "hw/block/block.h"
-#include "migration/block.h"
+#include "migration/misc.h"
+#include "migration/snapshot.h"
+#include "migration/global_state.h"
#include "sysemu/tpm.h"
#include "sysemu/dma.h"
-#include "hw/audio/audio.h"
+#include "hw/audio/soundhw.h"
#include "audio/audio.h"
-#include "migration/migration.h"
#include "sysemu/cpus.h"
#include "migration/colo.h"
#include "sysemu/kvm.h"
uint8_t *boot_splash_filedata;
size_t boot_splash_filedata_size;
uint8_t qemu_extra_params_fw[2];
-int only_migratable; /* turn it off unless user states otherwise */
int icount_align_option;
void hmp_usb_add(Monitor *mon, const QDict *qdict)
{
const char *devname = qdict_get_str(qdict, "devname");
+
+ error_report("usb_add is deprecated, please use device_add instead");
+
if (usb_device_add(devname) < 0) {
error_report("could not add USB device '%s'", devname);
}
void hmp_usb_del(Monitor *mon, const QDict *qdict)
{
const char *devname = qdict_get_str(qdict, "devname");
+
+ error_report("usb_del is deprecated, please use device_del instead");
+
if (usb_device_del(devname) < 0) {
error_report("could not delete USB device '%s'", devname);
}
}
}
-static int reset_requested;
-static int shutdown_requested, shutdown_signal = -1;
+static ShutdownCause reset_requested;
+static ShutdownCause shutdown_requested;
+static int shutdown_signal;
static pid_t shutdown_pid;
static int powerdown_requested;
static int debug_requested;
NOTIFIER_LIST_INITIALIZER(wakeup_notifiers);
static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE);
-int qemu_shutdown_requested_get(void)
+ShutdownCause qemu_shutdown_requested_get(void)
{
return shutdown_requested;
}
-int qemu_reset_requested_get(void)
+ShutdownCause qemu_reset_requested_get(void)
{
return reset_requested;
}
static int qemu_shutdown_requested(void)
{
- return atomic_xchg(&shutdown_requested, 0);
+ return atomic_xchg(&shutdown_requested, SHUTDOWN_CAUSE_NONE);
}
static void qemu_kill_report(void)
{
- if (!qtest_driver() && shutdown_signal != -1) {
+ if (!qtest_driver() && shutdown_signal) {
if (shutdown_pid == 0) {
/* This happens for eg ^C at the terminal, so it's worth
* avoiding printing an odd message in that case.
shutdown_cmd ? shutdown_cmd : "<unknown process>");
g_free(shutdown_cmd);
}
- shutdown_signal = -1;
+ shutdown_signal = 0;
}
}
-static int qemu_reset_requested(void)
+static ShutdownCause qemu_reset_requested(void)
{
- int r = reset_requested;
+ ShutdownCause r = reset_requested;
+
if (r && replay_checkpoint(CHECKPOINT_RESET_REQUESTED)) {
- reset_requested = 0;
+ reset_requested = SHUTDOWN_CAUSE_NONE;
return r;
}
- return false;
+ return SHUTDOWN_CAUSE_NONE;
}
static int qemu_suspend_requested(void)
return r;
}
-void qemu_system_reset(bool report)
+/*
+ * Reset the VM. Issue an event unless @reason is SHUTDOWN_CAUSE_NONE.
+ */
+void qemu_system_reset(ShutdownCause reason)
{
MachineClass *mc;
} else {
qemu_devices_reset();
}
- if (report) {
- qapi_event_send_reset(&error_abort);
+ if (reason) {
+ qapi_event_send_reset(shutdown_caused_by_guest(reason),
+ &error_abort);
}
cpu_synchronize_all_post_reset();
}
if (!no_shutdown) {
qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF,
!!info, info, &error_abort);
- qemu_system_shutdown_request();
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_PANIC);
}
if (info) {
}
}
-void qemu_system_reset_request(void)
+void qemu_system_reset_request(ShutdownCause reason)
{
if (no_reboot) {
- shutdown_requested = 1;
+ shutdown_requested = reason;
} else {
- reset_requested = 1;
+ reset_requested = reason;
}
cpu_stop_current();
qemu_notify_event();
/* Cannot call qemu_system_shutdown_request directly because
* we are in a signal handler.
*/
- shutdown_requested = 1;
+ shutdown_requested = SHUTDOWN_CAUSE_HOST_SIGNAL;
qemu_notify_event();
}
-void qemu_system_shutdown_request(void)
+void qemu_system_shutdown_request(ShutdownCause reason)
{
- trace_qemu_system_shutdown_request();
- replay_shutdown_request();
- shutdown_requested = 1;
+ trace_qemu_system_shutdown_request(reason);
+ replay_shutdown_request(reason);
+ shutdown_requested = reason;
qemu_notify_event();
}
static bool main_loop_should_exit(void)
{
RunState r;
+ ShutdownCause request;
+
if (qemu_debug_requested()) {
vm_stop(RUN_STATE_DEBUG);
}
if (qemu_suspend_requested()) {
qemu_system_suspend();
}
- if (qemu_shutdown_requested()) {
+ request = qemu_shutdown_requested();
+ if (request) {
qemu_kill_report();
- qapi_event_send_shutdown(&error_abort);
+ qapi_event_send_shutdown(shutdown_caused_by_guest(request),
+ &error_abort);
if (no_shutdown) {
vm_stop(RUN_STATE_SHUTDOWN);
} else {
return true;
}
}
- if (qemu_reset_requested()) {
+ request = qemu_reset_requested();
+ if (request) {
pause_all_vcpus();
- qemu_system_reset(VMRESET_REPORT);
+ qemu_system_reset(request);
resume_all_vcpus();
if (!runstate_check(RUN_STATE_RUNNING) &&
!runstate_check(RUN_STATE_INMIGRATE)) {
}
if (qemu_wakeup_requested()) {
pause_all_vcpus();
- qemu_system_reset(VMRESET_SILENT);
+ qemu_system_reset(SHUTDOWN_CAUSE_NONE);
notifier_list_notify(&wakeup_notifiers, &wakeup_reason);
wakeup_reason = QEMU_WAKEUP_REASON_NONE;
resume_all_vcpus();
exit(1);
}
} else if (strstart(p, "egl-headless", &opts)) {
-#ifdef CONFIG_OPENGL
+#ifdef CONFIG_OPENGL_DMABUF
request_opengl = 1;
display_opengl = 1;
display = DT_EGL;
return 0;
}
+static void user_register_global_props(void)
+{
+ qemu_opts_foreach(qemu_find_opts("global"),
+ global_init_func, NULL, NULL);
+}
+
+/*
+ * Note: we should see that these properties are actually having a
+ * priority: accel < machine < user. This means e.g. when user
+ * specifies something in "-global", it'll always be used with highest
+ * priority than either machine/accelerator compat properties.
+ */
+static void register_global_properties(MachineState *ms)
+{
+ accel_register_compat_props(ms->accelerator);
+ machine_register_compat_props(ms);
+ user_register_global_props();
+}
+
int main(int argc, char **argv, char **envp)
{
int i;
qdev_prop_register_global(&kvm_pit_lost_tick_policy);
break;
}
- case QEMU_OPTION_accel: {
- QemuOpts *accel_opts;
-
+ case QEMU_OPTION_accel:
accel_opts = qemu_opts_parse_noisily(qemu_find_opts("accel"),
optarg, true);
optarg = qemu_opt_get(accel_opts, "accel");
if (!optarg || is_help_option(optarg)) {
error_printf("Possible accelerators: kvm, xen, hax, tcg\n");
- exit(1);
+ exit(0);
}
- accel_opts = qemu_opts_create(qemu_find_opts("machine"), NULL,
- false, &error_abort);
- qemu_opt_set(accel_opts, "accel", optarg, &error_abort);
+ opts = qemu_opts_create(qemu_find_opts("machine"), NULL,
+ false, &error_abort);
+ qemu_opt_set(opts, "accel", optarg, &error_abort);
break;
- }
case QEMU_OPTION_usb:
olist = qemu_find_opts("machine");
qemu_opts_parse_noisily(olist, "usb=on", false);
break;
case QEMU_OPTION_usbdevice:
+ error_report("'-usbdevice' is deprecated, please use "
+ "'-device usb-...' instead");
olist = qemu_find_opts("machine");
qemu_opts_parse_noisily(olist, "usb=on", false);
add_device_config(DEV_USB, optarg);
configure_rtc(opts);
break;
case QEMU_OPTION_tb_size:
- tcg_tb_size = strtol(optarg, NULL, 0);
- if (tcg_tb_size < 0) {
- tcg_tb_size = 0;
+ if (!tcg_enabled()) {
+ error_report("TCG is disabled");
+ exit(1);
+ }
+ if (qemu_strtoul(optarg, NULL, 0, &tcg_tb_size) < 0) {
+ error_report("Invalid argument to -tb-size");
+ exit(1);
}
break;
case QEMU_OPTION_icount:
incoming = optarg;
break;
case QEMU_OPTION_only_migratable:
- only_migratable = 1;
+ /*
+ * TODO: we can remove this option one day, and we
+ * should all use:
+ *
+ * "-global migration.only-migratable=true"
+ */
+ qemu_global_option("migration.only-migratable=true");
break;
case QEMU_OPTION_nodefaults:
has_defaults = 0;
configure_accelerator(current_machine);
+ /*
+ * Register all the global properties, including accel properties,
+ * machine properties, and user-specified ones.
+ */
+ register_global_properties(current_machine);
+
+ /*
+ * Migration object can only be created after global properties
+ * are applied correctly.
+ */
+ migration_object_init();
+
if (qtest_chrdev) {
qtest_init(qtest_chrdev, qtest_log, &error_fatal);
}
qemu_opts_del(icount_opts);
}
- qemu_tcg_configure(accel_opts, &error_fatal);
+ if (tcg_enabled()) {
+ qemu_tcg_configure(accel_opts, &error_fatal);
+ }
if (default_net) {
QemuOptsList *net = qemu_find_opts("net");
exit (i == 1 ? 1 : 0);
}
- machine_register_compat_props(current_machine);
-
- qemu_opts_foreach(qemu_find_opts("global"),
- global_init_func, NULL, NULL);
-
/* This checkpoint is required by replay to separate prior clock
reading from the other reads, because timer polling functions query
clock values from the log. */
realtime_init();
- audio_init();
+ soundhw_init();
if (hax_enabled()) {
hax_sync_vcpus();
qemu_spice_display_init();
}
-#ifdef CONFIG_OPENGL
+#ifdef CONFIG_OPENGL_DMABUF
if (display_type == DT_EGL) {
egl_headless_init();
}
reading from the other reads, because timer polling functions query
clock values from the log. */
replay_checkpoint(CHECKPOINT_RESET);
- qemu_system_reset(VMRESET_SILENT);
+ qemu_system_reset(SHUTDOWN_CAUSE_NONE);
register_global_state();
if (replay_mode != REPLAY_MODE_NONE) {
replay_vmstate_init();
} else if (loadvm) {
Error *local_err = NULL;
- if (load_vmstate(loadvm, &local_err) < 0) {
+ if (load_snapshot(loadvm, &local_err) < 0) {
error_report_err(local_err);
autostart = 0;
}