#include "hw/bt.h"
#include "sysemu/watchdog.h"
#include "hw/smbios/smbios.h"
+#include "hw/acpi/acpi.h"
#include "hw/xen/xen.h"
#include "hw/qdev.h"
#include "hw/loader.h"
#include "audio/audio.h"
#include "migration/migration.h"
#include "sysemu/cpus.h"
+#include "migration/colo.h"
#include "sysemu/kvm.h"
+#include "sysemu/hax.h"
#include "qapi/qmp/qjson.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "slirp/libslirp.h"
-#include "trace.h"
+#include "trace-root.h"
#include "trace/control.h"
#include "qemu/queue.h"
-#include "sysemu/cpus.h"
#include "sysemu/arch_init.h"
#include "ui/qemu-spice.h"
static int no_frame = 0;
int no_quit = 0;
static bool grab_on_hover;
-CharDriverState *serial_hds[MAX_SERIAL_PORTS];
-CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
-CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
-CharDriverState *sclp_hds[MAX_SCLP_CONSOLES];
+Chardev *serial_hds[MAX_SERIAL_PORTS];
+Chardev *parallel_hds[MAX_PARALLEL_PORTS];
+Chardev *virtcon_hds[MAX_VIRTIO_CONSOLES];
+Chardev *sclp_hds[MAX_SCLP_CONSOLES];
int win2k_install_hack = 0;
int singlestep = 0;
int smp_cpus = 1;
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;
{ .driver = "isa-serial", .flag = &default_serial },
{ .driver = "isa-parallel", .flag = &default_parallel },
{ .driver = "isa-fdc", .flag = &default_floppy },
+ { .driver = "floppy", .flag = &default_floppy },
{ .driver = "ide-cd", .flag = &default_cdrom },
{ .driver = "ide-hd", .flag = &default_cdrom },
{ .driver = "ide-drive", .flag = &default_cdrom },
}, {
.name = "rrfile",
.type = QEMU_OPT_STRING,
+ }, {
+ .name = "rrsnapshot",
+ .type = QEMU_OPT_STRING,
},
{ /* end of list */ }
},
},
};
-#ifdef CONFIG_LIBISCSI
-static QemuOptsList qemu_iscsi_opts = {
- .name = "iscsi",
- .head = QTAILQ_HEAD_INITIALIZER(qemu_iscsi_opts.head),
- .desc = {
- {
- .name = "user",
- .type = QEMU_OPT_STRING,
- .help = "username for CHAP authentication to target",
- },{
- .name = "password",
- .type = QEMU_OPT_STRING,
- .help = "password for CHAP authentication to target",
- },{
- .name = "password-secret",
- .type = QEMU_OPT_STRING,
- .help = "ID of the secret providing password for CHAP "
- "authentication to target",
- },{
- .name = "header-digest",
- .type = QEMU_OPT_STRING,
- .help = "HeaderDigest setting. "
- "{CRC32C|CRC32C-NONE|NONE-CRC32C|NONE}",
- },{
- .name = "initiator-name",
- .type = QEMU_OPT_STRING,
- .help = "Initiator iqn name to use when connecting",
- },{
- .name = "timeout",
- .type = QEMU_OPT_NUMBER,
- .help = "Request timeout in seconds (default 0 = no timeout)",
- },
- { /* end of list */ }
- },
-};
-#endif
-
/**
* Get machine options
*
{ RUN_STATE_INMIGRATE, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_INMIGRATE, RUN_STATE_PRELAUNCH },
{ RUN_STATE_INMIGRATE, RUN_STATE_POSTMIGRATE },
+ { RUN_STATE_INMIGRATE, RUN_STATE_COLO },
{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED },
{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_PAUSED, RUN_STATE_RUNNING },
{ RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_PAUSED, RUN_STATE_PRELAUNCH },
+ { RUN_STATE_PAUSED, RUN_STATE_COLO},
{ RUN_STATE_POSTMIGRATE, RUN_STATE_RUNNING },
{ RUN_STATE_POSTMIGRATE, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_RUNNING },
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE },
{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_PRELAUNCH },
+ { RUN_STATE_FINISH_MIGRATE, RUN_STATE_COLO},
{ RUN_STATE_RESTORE_VM, RUN_STATE_RUNNING },
{ RUN_STATE_RESTORE_VM, RUN_STATE_PRELAUNCH },
+ { RUN_STATE_COLO, RUN_STATE_RUNNING },
+
{ RUN_STATE_RUNNING, RUN_STATE_DEBUG },
{ RUN_STATE_RUNNING, RUN_STATE_INTERNAL_ERROR },
{ RUN_STATE_RUNNING, RUN_STATE_IO_ERROR },
{ RUN_STATE_RUNNING, RUN_STATE_SHUTDOWN },
{ RUN_STATE_RUNNING, RUN_STATE_WATCHDOG },
{ RUN_STATE_RUNNING, RUN_STATE_GUEST_PANICKED },
+ { RUN_STATE_RUNNING, RUN_STATE_COLO},
{ RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
{ RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
{ RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_SUSPENDED, RUN_STATE_PRELAUNCH },
+ { RUN_STATE_SUSPENDED, RUN_STATE_COLO},
{ RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
{ RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
{ RUN_STATE_WATCHDOG, RUN_STATE_PRELAUNCH },
+ { RUN_STATE_WATCHDOG, RUN_STATE_COLO},
{ RUN_STATE_GUEST_PANICKED, RUN_STATE_RUNNING },
{ RUN_STATE_GUEST_PANICKED, RUN_STATE_FINISH_MIGRATE },
max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus);
- if (max_cpus > MAX_CPUMASK_BITS) {
- error_report("unsupported number of maxcpus");
- exit(1);
- }
-
if (max_cpus < cpus) {
error_report("maxcpus must be equal to or greater than smp");
exit(1);
}
}
-/* reset/shutdown handler */
-
-typedef struct QEMUResetEntry {
- QTAILQ_ENTRY(QEMUResetEntry) entry;
- QEMUResetHandler *func;
- void *opaque;
-} QEMUResetEntry;
-
-static QTAILQ_HEAD(reset_handlers, QEMUResetEntry) reset_handlers =
- QTAILQ_HEAD_INITIALIZER(reset_handlers);
static int reset_requested;
static int shutdown_requested, shutdown_signal = -1;
static pid_t shutdown_pid;
return r;
}
-void qemu_register_reset(QEMUResetHandler *func, void *opaque)
-{
- QEMUResetEntry *re = g_malloc0(sizeof(QEMUResetEntry));
-
- re->func = func;
- re->opaque = opaque;
- QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
-}
-
-void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
-{
- QEMUResetEntry *re;
-
- QTAILQ_FOREACH(re, &reset_handlers, entry) {
- if (re->func == func && re->opaque == opaque) {
- QTAILQ_REMOVE(&reset_handlers, re, entry);
- g_free(re);
- return;
- }
- }
-}
-
-void qemu_devices_reset(void)
-{
- QEMUResetEntry *re, *nre;
-
- /* reset all devices */
- QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
- re->func(re->opaque);
- }
-}
-
void qemu_system_reset(bool report)
{
MachineClass *mc;
}
qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_PAUSE, &error_abort);
vm_stop(RUN_STATE_GUEST_PANICKED);
+ if (!no_shutdown) {
+ qapi_event_send_guest_panicked(GUEST_PANIC_ACTION_POWEROFF,
+ &error_abort);
+ qemu_system_shutdown_request();
+ }
}
void qemu_system_reset_request(void)
int64_t ti;
#endif
do {
- nonblocking = !kvm_enabled() && !xen_enabled() && last_io > 0;
+ nonblocking = tcg_enabled() && last_io > 0;
#ifdef CONFIG_PROFILER
ti = profile_getclock();
#endif
static void version(void)
{
- printf("QEMU emulator version " QEMU_VERSION QEMU_PKGVERSION ", "
+ printf("QEMU emulator version " QEMU_VERSION QEMU_PKGVERSION "\n"
QEMU_COPYRIGHT "\n");
}
{
Error *local_err = NULL;
- qemu_chr_new_from_opts(opts, NULL, &local_err);
+ qemu_chr_new_from_opts(opts, &local_err);
if (local_err) {
error_report_err(local_err);
return -1;
static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp)
{
- CharDriverState *chr;
+ Chardev *chr;
const char *chardev;
const char *mode;
int flags;
if (qemu_opt_get_bool(opts, "pretty", 0))
flags |= MONITOR_USE_PRETTY;
- if (qemu_opt_get_bool(opts, "default", 0))
- flags |= MONITOR_IS_DEFAULT;
+ if (qemu_opt_get_bool(opts, "default", 0)) {
+ error_report("option 'default' does nothing and is deprecated");
+ }
chardev = qemu_opt_get(opts, "chardev");
chr = qemu_chr_find(chardev);
exit(1);
}
- qemu_chr_fe_claim_no_fail(chr);
monitor_init(chr, flags);
return 0;
}
QemuOpts *opts;
const char *p;
char label[32];
- int def = 0;
if (strstart(optarg, "chardev:", &p)) {
snprintf(label, sizeof(label), "%s", p);
} else {
snprintf(label, sizeof(label), "compat_monitor%d",
monitor_device_index);
- if (monitor_device_index == 0) {
- def = 1;
- }
opts = qemu_chr_parse_compat(label, optarg);
if (!opts) {
error_report("parse error: %s", optarg);
qemu_opt_set(opts, "mode", mode, &error_abort);
qemu_opt_set(opts, "chardev", label, &error_abort);
qemu_opt_set_bool(opts, "pretty", pretty, &error_abort);
- if (def)
- qemu_opt_set(opts, "default", "on", &error_abort);
monitor_device_index++;
}
exit(1);
}
snprintf(label, sizeof(label), "serial%d", index);
- serial_hds[index] = qemu_chr_new(label, devname, NULL);
+ serial_hds[index] = qemu_chr_new(label, devname);
if (!serial_hds[index]) {
error_report("could not connect serial device"
" to character backend '%s'", devname);
exit(1);
}
snprintf(label, sizeof(label), "parallel%d", index);
- parallel_hds[index] = qemu_chr_new(label, devname, NULL);
+ parallel_hds[index] = qemu_chr_new(label, devname);
if (!parallel_hds[index]) {
error_report("could not connect parallel device"
" to character backend '%s'", devname);
qemu_opt_set(dev_opts, "driver", "virtconsole", &error_abort);
snprintf(label, sizeof(label), "virtcon%d", index);
- virtcon_hds[index] = qemu_chr_new(label, devname, NULL);
+ virtcon_hds[index] = qemu_chr_new(label, devname);
if (!virtcon_hds[index]) {
error_report("could not connect virtio console"
" to character backend '%s'", devname);
qemu_opt_set(dev_opts, "driver", "sclpconsole", &error_abort);
snprintf(label, sizeof(label), "sclpcon%d", index);
- sclp_hds[index] = qemu_chr_new(label, devname, NULL);
+ sclp_hds[index] = qemu_chr_new(label, devname);
if (!sclp_hds[index]) {
error_report("could not connect sclp console"
" to character backend '%s'", devname);
{
QemuOpts *opts;
- if (!qemu_chr_new("debugcon", devname, NULL)) {
+ if (!qemu_chr_new("debugcon", devname)) {
exit(1);
}
opts = qemu_opts_create(qemu_find_opts("device"), "debugcon", 1, NULL);
{
Object *obj = OBJECT(opaque);
Error *local_err = NULL;
- char *c, *qom_name;
+ char *p, *qom_name;
if (strcmp(name, "type") == 0) {
return 0;
}
qom_name = g_strdup(name);
- c = qom_name;
- while (*c++) {
- if (*c == '_') {
- *c = '-';
+ for (p = qom_name; *p; p++) {
+ if (*p == '_') {
+ *p = '-';
}
}
g_str_equal(type, "filter-mirror") ||
g_str_equal(type, "filter-redirector") ||
g_str_equal(type, "colo-compare") ||
- g_str_equal(type, "filter-rewriter")) {
+ g_str_equal(type, "filter-rewriter") ||
+ g_str_equal(type, "filter-replay")) {
return false;
}
return 0;
}
+static int qemu_read_default_config_file(void)
+{
+ int ret;
+
+ ret = qemu_read_config_file(CONFIG_QEMU_CONFDIR "/qemu.conf");
+ if (ret < 0 && ret != -ENOENT) {
+ return ret;
+ }
+
+ return 0;
+}
+
int main(int argc, char **argv, char **envp)
{
int i;
Error *err = NULL;
bool list_data_dirs = false;
+ module_call_init(MODULE_INIT_TRACE);
+
qemu_init_cpu_list();
qemu_init_cpu_loop();
qemu_mutex_lock_iothread();
qemu_add_drive_opts(&qemu_legacy_drive_opts);
qemu_add_drive_opts(&qemu_common_drive_opts);
qemu_add_drive_opts(&qemu_drive_opts);
+ qemu_add_drive_opts(&bdrv_runtime_opts);
qemu_add_opts(&qemu_chardev_opts);
qemu_add_opts(&qemu_device_opts);
qemu_add_opts(&qemu_netdev_opts);
qemu_add_opts(&qemu_icount_opts);
qemu_add_opts(&qemu_semihosting_config_opts);
qemu_add_opts(&qemu_fw_cfg_opts);
-#ifdef CONFIG_LIBISCSI
- qemu_add_opts(&qemu_iscsi_opts);
-#endif
module_call_init(MODULE_INIT_OPTS);
runstate_init();
}
}
- if (defconfig) {
- int ret;
- ret = qemu_read_default_config_files(userconfig);
- if (ret < 0) {
+ if (defconfig && userconfig) {
+ if (qemu_read_default_config_file() < 0) {
exit(1);
}
}
if (!opts) {
exit(1);
}
- do_acpitable_option(opts);
+ acpi_table_add(opts, &error_fatal);
break;
case QEMU_OPTION_smbios:
opts = qemu_opts_parse_noisily(qemu_find_opts("smbios"),
if (!opts) {
exit(1);
}
- do_smbios_option(opts);
+ smbios_entry_add(opts, &error_fatal);
break;
case QEMU_OPTION_fwcfg:
opts = qemu_opts_parse_noisily(qemu_find_opts("fw_cfg"),
olist = qemu_find_opts("machine");
qemu_opts_parse_noisily(olist, "accel=kvm", false);
break;
+ case QEMU_OPTION_enable_hax:
+ olist = qemu_find_opts("machine");
+ qemu_opts_parse_noisily(olist, "accel=hax", false);
+ break;
case QEMU_OPTION_M:
case QEMU_OPTION_machine:
olist = qemu_find_opts("machine");
}
incoming = optarg;
break;
+ case QEMU_OPTION_only_migratable:
+ only_migratable = 1;
+ break;
case QEMU_OPTION_nodefaults:
has_defaults = 0;
break;
os_daemonize();
+ if (pid_file && qemu_create_pidfile(pid_file) != 0) {
+ error_report("could not acquire pid file: %s", strerror(errno));
+ exit(1);
+ }
+
if (qemu_init_main_loop(&main_loop_err)) {
error_report_err(main_loop_err);
exit(1);
}
object_property_add_child(object_get_root(), "machine",
OBJECT(current_machine), &error_abort);
+
+ if (machine_class->minimum_page_bits) {
+ if (!set_preferred_target_page_bits(machine_class->minimum_page_bits)) {
+ /* This would be a board error: specifying a minimum smaller than
+ * a target's compile-time fixed setting.
+ */
+ g_assert_not_reached();
+ }
+ }
+
cpu_exec_init_all();
if (machine_class->hw_version) {
sdl_display_early_init(request_opengl);
}
+ qemu_console_early_init();
+
if (request_opengl == 1 && display_opengl == 0) {
#if defined(CONFIG_OPENGL)
error_report("OpenGL is not supported by the display");
}
#endif
- if (pid_file && qemu_create_pidfile(pid_file) != 0) {
- error_report("could not acquire pid file: %s", strerror(errno));
- exit(1);
- }
-
if (qemu_opts_foreach(qemu_find_opts("device"),
device_help_func, NULL, NULL)) {
exit(0);
exit(1);
}
- if (!linux_boot && qemu_opt_get(machine_opts, "dtb")) {
- error_report("-dtb only allowed with -kernel option");
- exit(1);
- }
-
if (semihosting_enabled() && !semihosting_get_argc() && kernel_filename) {
/* fall back to the -kernel/-append */
semihosting_arg_fallback(kernel_filename, kernel_cmdline);
cpu_ticks_init();
if (icount_opts) {
- if (kvm_enabled() || xen_enabled()) {
- error_report("-icount is not allowed with kvm or xen");
+ if (!tcg_enabled()) {
+ error_report("-icount is not allowed with hardware virtualization");
exit(1);
}
configure_icount(icount_opts, &error_abort);
#endif
}
+ colo_info_init();
+
if (net_init_clients() < 0) {
exit(1);
}
cpu_synchronize_all_post_init();
- numa_post_machine_init();
+ if (hax_enabled()) {
+ hax_sync_vcpus();
+ }
if (qemu_opts_foreach(qemu_find_opts("fw_cfg"),
parse_fw_cfg, fw_cfg_find(), NULL) != 0) {
device_init_func, NULL, NULL)) {
exit(1);
}
+
+ numa_post_machine_init();
+
rom_reset_order_override();
/* Did we create any drives that we failed to create a device for? */
replay_checkpoint(CHECKPOINT_RESET);
qemu_system_reset(VMRESET_SILENT);
register_global_state();
- if (loadvm) {
+ if (replay_mode != REPLAY_MODE_NONE) {
+ replay_vmstate_init();
+ } else if (loadvm) {
if (load_vmstate(loadvm) < 0) {
autostart = 0;
}