#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/units.h"
+#include "hw/qdev-properties.h"
#include "qapi/error.h"
#include "qemu-version.h"
#include "qemu/cutils.h"
#include "qemu/help_option.h"
#include "qemu/uuid.h"
+#include "sysemu/reset.h"
+#include "sysemu/runstate.h"
#include "sysemu/seccomp.h"
#include "sysemu/tcg.h"
#include "qemu/error-report.h"
#include "qemu/sockets.h"
-#include "hw/hw.h"
#include "sysemu/accel.h"
#include "hw/usb.h"
#include "hw/isa/isa.h"
#include "hw/firmware/smbios.h"
#include "hw/acpi/acpi.h"
#include "hw/xen/xen.h"
-#include "hw/qdev.h"
#include "hw/loader.h"
#include "monitor/qdev.h"
#include "sysemu/bt.h"
#include "trace-root.h"
#include "trace/control.h"
+#include "qemu/plugin.h"
#include "qemu/queue.h"
#include "sysemu/arch_init.h"
switch (clock) {
case QEMU_CLOCK_REALTIME:
value -= rtc_realtime_clock_offset;
- /* no break */
+ /* fall through */
case QEMU_CLOCK_VIRTUAL:
value += rtc_ref_start_datetime;
break;
qapi_free_BlockdevOptions(bdo->bdo);
g_free(bdo);
}
- if (snapshot || replay_mode != REPLAY_MODE_NONE) {
+ if (snapshot) {
qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot,
NULL, NULL);
}
return 1;
}
-struct vm_change_state_entry {
+struct VMChangeStateEntry {
VMChangeStateHandler *cb;
void *opaque;
- QTAILQ_ENTRY(vm_change_state_entry) entries;
+ QTAILQ_ENTRY(VMChangeStateEntry) entries;
int priority;
};
-static QTAILQ_HEAD(, vm_change_state_entry) vm_change_state_head;
+static QTAILQ_HEAD(, VMChangeStateEntry) vm_change_state_head;
/**
* qemu_add_vm_change_state_handler_prio:
cpu_synchronize_all_post_reset();
}
+/*
+ * Wake the VM after suspend.
+ */
+static void qemu_system_wakeup(void)
+{
+ MachineClass *mc;
+
+ mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL;
+
+ if (mc && mc->wakeup) {
+ mc->wakeup(current_machine);
+ }
+}
+
void qemu_system_guest_panicked(GuestPanicInformation *info)
{
qemu_log_mask(LOG_GUEST_ERROR, "Guest crashed");
RunState r;
ShutdownCause request;
+ if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
+ return false;
+ }
if (preconfig_exit_requested) {
if (runstate_check(RUN_STATE_PRECONFIG)) {
runstate_set(RUN_STATE_PRELAUNCH);
}
if (qemu_wakeup_requested()) {
pause_all_vcpus();
- qemu_system_reset(SHUTDOWN_CAUSE_NONE);
+ qemu_system_wakeup();
notifier_list_notify(&wakeup_notifiers, &wakeup_reason);
wakeup_reason = QEMU_WAKEUP_REASON_NONE;
resume_all_vcpus();
DeviceState *dev;
dev = qdev_device_add(opts, errp);
- if (!dev) {
+ if (!dev && *errp) {
+ error_report_err(*errp);
return -1;
+ } else if (dev) {
+ object_unref(OBJECT(dev));
}
- object_unref(OBJECT(dev));
return 0;
}
*/
static bool object_create_initial(const char *type, QemuOpts *opts)
{
- ObjectClass *klass;
-
- if (is_help_option(type)) {
- GSList *l, *list;
-
- printf("List of user creatable objects:\n");
- list = object_class_get_list_sorted(TYPE_USER_CREATABLE, false);
- for (l = list; l != NULL; l = l->next) {
- ObjectClass *oc = OBJECT_CLASS(l->data);
- printf(" %s\n", object_class_get_name(oc));
- }
- g_slist_free(list);
- exit(0);
- }
-
- klass = object_class_by_name(type);
- if (klass && qemu_opt_has_help_opt(opts)) {
- ObjectPropertyIterator iter;
- ObjectProperty *prop;
- GPtrArray *array = g_ptr_array_new();
- int i;
-
- object_class_property_iter_init(&iter, klass);
- while ((prop = object_property_iter_next(&iter))) {
- GString *str;
-
- if (!prop->set) {
- continue;
- }
-
- str = g_string_new(NULL);
- g_string_append_printf(str, " %s=<%s>", prop->name, prop->type);
- if (prop->description) {
- if (str->len < 24) {
- g_string_append_printf(str, "%*s", 24 - (int)str->len, "");
- }
- g_string_append_printf(str, " - %s", prop->description);
- }
- g_ptr_array_add(array, g_string_free(str, false));
- }
- g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
- if (array->len > 0) {
- printf("%s options:\n", type);
- } else {
- printf("There are no options for %s.\n", type);
- }
- for (i = 0; i < array->len; i++) {
- printf("%s\n", (char *)array->pdata[i]);
- }
- g_ptr_array_set_free_func(array, g_free);
- g_ptr_array_free(array, true);
+ if (user_creatable_print_help(type, opts)) {
exit(0);
}
bool list_data_dirs = false;
char *dir, **dirs;
BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
+ QemuPluginList plugin_list = QTAILQ_HEAD_INITIALIZER(plugin_list);
os_set_line_buffering();
qemu_add_opts(&qemu_global_opts);
qemu_add_opts(&qemu_mon_opts);
qemu_add_opts(&qemu_trace_opts);
+ qemu_plugin_add_opts();
qemu_add_opts(&qemu_option_rom_opts);
qemu_add_opts(&qemu_machine_opts);
qemu_add_opts(&qemu_accel_opts);
drive_add(IF_PFLASH, -1, optarg, PFLASH_OPTS);
break;
case QEMU_OPTION_snapshot:
- snapshot = 1;
+ {
+ Error *blocker = NULL;
+ snapshot = 1;
+ error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED,
+ "-snapshot");
+ replay_add_blocker(blocker);
+ }
break;
case QEMU_OPTION_numa:
opts = qemu_opts_parse_noisily(qemu_find_opts("numa"),
if (*p == 'x') {
p++;
depth = strtol(p, (char **)&p, 10);
- if (depth != 8 && depth != 15 && depth != 16 &&
+ if (depth != 1 && depth != 2 && depth != 4 &&
+ depth != 8 && depth != 15 && depth != 16 &&
depth != 24 && depth != 32)
goto graphic_error;
} else if (*p == '\0') {
case QEMU_OPTION_virtfs: {
QemuOpts *fsdev;
QemuOpts *device;
- const char *writeout, *sock_fd, *socket, *path, *security_model;
+ const char *writeout, *sock_fd, *socket, *path, *security_model,
+ *multidevs;
olist = qemu_find_opts("virtfs");
if (!olist) {
qemu_opt_set_bool(fsdev, "readonly",
qemu_opt_get_bool(opts, "readonly", 0),
&error_abort);
+ multidevs = qemu_opt_get(opts, "multidevs");
+ if (multidevs) {
+ qemu_opt_set(fsdev, "multidevs", multidevs, &error_abort);
+ }
device = qemu_opts_create(qemu_find_opts("device"), NULL, 0,
&error_abort);
qemu_opt_set(device, "driver", "virtio-9p-pci", &error_abort);
g_slist_free(accel_list);
exit(0);
}
+ if (optarg && strchr(optarg, ':')) {
+ error_report("Don't use ':' with -accel, "
+ "use -M accel=... for now instead");
+ exit(1);
+ }
opts = qemu_opts_create(qemu_find_opts("machine"), NULL,
false, &error_abort);
qemu_opt_set(opts, "accel", optarg, &error_abort);
g_free(trace_file);
trace_file = trace_opt_parse(optarg);
break;
+ case QEMU_OPTION_plugin:
+ qemu_plugin_opt_parse(optarg, &plugin_list);
+ break;
case QEMU_OPTION_readconfig:
{
int ret = qemu_read_config_file(optarg);
machine_class->default_machine_opts, 0);
}
+ /* process plugin before CPUs are created, but once -smp has been parsed */
+ if (qemu_plugin_load_list(&plugin_list)) {
+ exit(1);
+ }
+
qemu_opts_foreach(qemu_find_opts("device"),
default_driver_check, NULL, NULL);
qemu_opts_foreach(qemu_find_opts("global"),
/* No more vcpu or device emulation activity beyond this point */
vm_shutdown();
+ replay_finish();
job_cancel_sync_all();
bdrv_close_all();