X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=vl.c;h=68e8c003d1b34986cb76b39038608a2b726c0de7;hb=1dfb1b2d34840dce27e672f147bc4ef122abab74;hp=f3abd99eb2f9b2e7153d06f911d20b5d21cca61b;hpb=d681127d37e192dcf6f15802236d1fbfaf15d682;p=mirror_qemu.git diff --git a/vl.c b/vl.c index f3abd99eb2..68e8c003d1 100644 --- a/vl.c +++ b/vl.c @@ -65,6 +65,7 @@ int main(int argc, char **argv) #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" @@ -90,7 +91,9 @@ int main(int argc, char **argv) #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" @@ -110,7 +113,6 @@ int main(int argc, char **argv) #include "trace.h" #include "trace/control.h" #include "qemu/queue.h" -#include "sysemu/cpus.h" #include "sysemu/arch_init.h" #include "ui/qemu-spice.h" @@ -180,6 +182,7 @@ bool boot_strict; 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; @@ -218,6 +221,7 @@ static struct { { .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 }, @@ -612,6 +616,7 @@ static const RunStateTransition runstate_transitions_def[] = { { 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 }, @@ -624,6 +629,7 @@ static const RunStateTransition runstate_transitions_def[] = { { 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 }, @@ -636,10 +642,13 @@ static const RunStateTransition runstate_transitions_def[] = { { 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 }, @@ -650,6 +659,7 @@ static const RunStateTransition runstate_transitions_def[] = { { 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 }, @@ -662,10 +672,12 @@ static const RunStateTransition runstate_transitions_def[] = { { 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 }, @@ -1268,11 +1280,6 @@ static void smp_parse(QemuOpts *opts) 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); @@ -1626,16 +1633,6 @@ void vm_state_notify(int running, RunState state) } } -/* 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; @@ -1675,8 +1672,12 @@ static void qemu_kill_report(void) */ error_report("terminating on signal %d", shutdown_signal); } else { - error_report("terminating on signal %d from pid " FMT_pid, - shutdown_signal, shutdown_pid); + char *shutdown_cmd = qemu_get_pid_name(shutdown_pid); + + error_report("terminating on signal %d from pid " FMT_pid " (%s)", + shutdown_signal, shutdown_pid, + shutdown_cmd ? shutdown_cmd : ""); + g_free(shutdown_cmd); } shutdown_signal = -1; } @@ -1721,38 +1722,6 @@ static int qemu_debug_requested(void) 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; @@ -1779,6 +1748,11 @@ void qemu_system_guest_panicked(void) } 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) @@ -1941,7 +1915,7 @@ static void main_loop(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 @@ -1954,7 +1928,7 @@ static void main_loop(void) static void version(void) { - printf("QEMU emulator version " QEMU_VERSION QEMU_PKGVERSION ", " + printf("QEMU emulator version " QEMU_VERSION QEMU_PKGVERSION "\n" QEMU_COPYRIGHT "\n"); } @@ -2365,7 +2339,7 @@ static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp) { 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; @@ -2403,8 +2377,9 @@ static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp) 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); @@ -2413,7 +2388,6 @@ static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp) exit(1); } - qemu_chr_fe_claim_no_fail(chr); monitor_init(chr, flags); return 0; } @@ -2424,16 +2398,12 @@ static void monitor_parse(const char *optarg, const char *mode, bool pretty) 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); @@ -2445,8 +2415,6 @@ static void monitor_parse(const char *optarg, const char *mode, bool pretty) 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++; } @@ -2510,7 +2478,7 @@ static int serial_parse(const char *devname) 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); @@ -2532,7 +2500,7 @@ static int parallel_parse(const char *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); @@ -2563,7 +2531,7 @@ static int virtcon_parse(const char *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); @@ -2596,7 +2564,7 @@ static int sclp_parse(const char *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); @@ -2612,7 +2580,7 @@ static int debugcon_parse(const char *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); @@ -2800,17 +2768,16 @@ static int machine_set_property(void *opaque, { 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 = '-'; } } @@ -2848,7 +2815,8 @@ static bool object_create_initial(const char *type) 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; } @@ -2983,6 +2951,18 @@ static int global_init_func(void *opaque, QemuOpts *opts, Error **errp) 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; @@ -3020,6 +3000,8 @@ int main(int argc, char **argv, char **envp) 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(); @@ -3035,6 +3017,7 @@ int main(int argc, char **argv, char **envp) 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); @@ -3107,10 +3090,8 @@ int main(int argc, char **argv, char **envp) } } - 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); } } @@ -3689,7 +3670,7 @@ int main(int argc, char **argv, char **envp) 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"), @@ -3697,7 +3678,7 @@ int main(int argc, char **argv, char **envp) 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"), @@ -3710,6 +3691,10 @@ int main(int argc, char **argv, char **envp) 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"); @@ -3900,6 +3885,9 @@ int main(int argc, char **argv, char **envp) } incoming = optarg; break; + case QEMU_OPTION_only_migratable: + only_migratable = 1; + break; case QEMU_OPTION_nodefaults: has_defaults = 0; break; @@ -4049,6 +4037,11 @@ int main(int argc, char **argv, char **envp) 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); @@ -4083,6 +4076,16 @@ int main(int argc, char **argv, char **envp) } 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) { @@ -4316,11 +4319,6 @@ int main(int argc, char **argv, char **envp) } #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); @@ -4382,11 +4380,6 @@ int main(int argc, char **argv, char **envp) 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); @@ -4399,8 +4392,8 @@ int main(int argc, char **argv, char **envp) 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); @@ -4415,6 +4408,8 @@ int main(int argc, char **argv, char **envp) #endif } + colo_info_init(); + if (net_init_clients() < 0) { exit(1); } @@ -4532,7 +4527,9 @@ int main(int argc, char **argv, char **envp) 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) { @@ -4554,6 +4551,9 @@ int main(int argc, char **argv, char **envp) 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? */