X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/dd4af97733401e200c39184ecca4c8eabb222637..2c324b284aac7b87f65af043b8cb6196bd6ad16b:/vl.c diff --git a/vl.c b/vl.c index d84857c064..db04aea7f8 100644 --- a/vl.c +++ b/vl.c @@ -61,7 +61,7 @@ int main(int argc, char **argv) #include "hw/display/vga.h" #include "hw/bt.h" #include "sysemu/watchdog.h" -#include "hw/smbios/smbios.h" +#include "hw/firmware/smbios.h" #include "hw/acpi/acpi.h" #include "hw/xen/xen.h" #include "hw/qdev.h" @@ -106,9 +106,6 @@ int main(int argc, char **argv) #include "disas/disas.h" - -#include "slirp/libslirp.h" - #include "trace-root.h" #include "trace/control.h" #include "qemu/queue.h" @@ -128,6 +125,7 @@ int main(int argc, char **argv) #include "qapi/qapi-commands-block-core.h" #include "qapi/qapi-commands-misc.h" #include "qapi/qapi-commands-run-state.h" +#include "qapi/qapi-commands-ui.h" #include "qapi/qmp/qerror.h" #include "sysemu/iothread.h" @@ -147,16 +145,21 @@ bool enable_cpu_pm = false; int nb_nics; NICInfo nd_table[MAX_NICS]; int autostart; -static int rtc_utc = 1; -static int rtc_date_offset = -1; /* -1 means no change */ +static enum { + RTC_BASE_UTC, + RTC_BASE_LOCALTIME, + RTC_BASE_DATETIME, +} rtc_base_type = RTC_BASE_UTC; +static time_t rtc_ref_start_datetime; +static int rtc_realtime_clock_offset; /* used only with QEMU_CLOCK_REALTIME */ +static int rtc_host_datetime_offset = -1; /* valid & used only with + RTC_BASE_DATETIME */ QEMUClockType rtc_clock; int vga_interface_type = VGA_NONE; static DisplayOptions dpy; -int no_frame; static int num_serial_hds; static Chardev **serial_hds; Chardev *parallel_hds[MAX_PARALLEL_PORTS]; -Chardev *virtcon_hds[MAX_VIRTIO_CONSOLES]; int win2k_install_hack = 0; int singlestep = 0; int smp_cpus; @@ -183,7 +186,7 @@ int boot_menu; bool boot_strict; uint8_t *boot_splash_filedata; size_t boot_splash_filedata_size; -uint8_t qemu_extra_params_fw[2]; +bool wakeup_suspend_enabled; int icount_align_option; @@ -207,7 +210,6 @@ bool xen_domid_restrict; static int has_defaults = 1; static int default_serial = 1; static int default_parallel = 1; -static int default_virtcon = 1; static int default_monitor = 1; static int default_floppy = 1; static int default_cdrom = 1; @@ -228,8 +230,6 @@ static struct { { .driver = "ide-drive", .flag = &default_cdrom }, { .driver = "scsi-cd", .flag = &default_cdrom }, { .driver = "scsi-hd", .flag = &default_cdrom }, - { .driver = "virtio-serial-pci", .flag = &default_virtcon }, - { .driver = "virtio-serial", .flag = &default_virtcon }, { .driver = "VGA", .flag = &default_vga }, { .driver = "isa-vga", .flag = &default_vga }, { .driver = "cirrus-vga", .flag = &default_vga }, @@ -242,6 +242,7 @@ static struct { static QemuOptsList qemu_rtc_opts = { .name = "rtc", .head = QTAILQ_HEAD_INITIALIZER(qemu_rtc_opts.head), + .merge_lists = true, .desc = { { .name = "base", @@ -328,10 +329,10 @@ static QemuOptsList qemu_boot_opts = { .type = QEMU_OPT_STRING, }, { .name = "splash-time", - .type = QEMU_OPT_STRING, + .type = QEMU_OPT_NUMBER, }, { .name = "reboot-timeout", - .type = QEMU_OPT_STRING, + .type = QEMU_OPT_NUMBER, }, { .name = "strict", .type = QEMU_OPT_BOOL, @@ -529,7 +530,7 @@ static QemuOptsList qemu_fw_cfg_opts = { }, { .name = "file", .type = QEMU_OPT_STRING, - .help = "Sets the name of the file from which\n" + .help = "Sets the name of the file from which " "the fw_cfg blob will be loaded", }, { .name = "string", @@ -722,6 +723,9 @@ void runstate_set(RunState new_state) { assert(new_state < RUN_STATE__MAX); + trace_runstate_set(current_run_state, RunState_str(current_run_state), + new_state, RunState_str(current_run_state)); + if (current_run_state == new_state) { return; } @@ -732,7 +736,7 @@ void runstate_set(RunState new_state) RunState_str(new_state)); abort(); } - trace_runstate_set(new_state); + current_run_state = new_state; } @@ -780,28 +784,42 @@ void qemu_system_vmstop_request(RunState state) } /***********************************************************/ -/* real time host monotonic timer */ - -static time_t qemu_time(void) +/* RTC reference time/date access */ +static time_t qemu_ref_timedate(QEMUClockType clock) { - return qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000; + time_t value = qemu_clock_get_ms(clock) / 1000; + switch (clock) { + case QEMU_CLOCK_REALTIME: + value -= rtc_realtime_clock_offset; + /* no break */ + case QEMU_CLOCK_VIRTUAL: + value += rtc_ref_start_datetime; + break; + case QEMU_CLOCK_HOST: + if (rtc_base_type == RTC_BASE_DATETIME) { + value -= rtc_host_datetime_offset; + } + break; + default: + assert(0); + } + return value; } -/***********************************************************/ -/* host time/date access */ void qemu_get_timedate(struct tm *tm, int offset) { - time_t ti = qemu_time(); + time_t ti = qemu_ref_timedate(rtc_clock); ti += offset; - if (rtc_date_offset == -1) { - if (rtc_utc) - gmtime_r(&ti, tm); - else - localtime_r(&ti, tm); - } else { - ti -= rtc_date_offset; + + switch (rtc_base_type) { + case RTC_BASE_DATETIME: + case RTC_BASE_UTC: gmtime_r(&ti, tm); + break; + case RTC_BASE_LOCALTIME: + localtime_r(&ti, tm); + break; } } @@ -809,23 +827,28 @@ int qemu_timedate_diff(struct tm *tm) { time_t seconds; - if (rtc_date_offset == -1) - if (rtc_utc) - seconds = mktimegm(tm); - else { - struct tm tmp = *tm; - tmp.tm_isdst = -1; /* use timezone to figure it out */ - seconds = mktime(&tmp); - } - else - seconds = mktimegm(tm) + rtc_date_offset; + switch (rtc_base_type) { + case RTC_BASE_DATETIME: + case RTC_BASE_UTC: + seconds = mktimegm(tm); + break; + case RTC_BASE_LOCALTIME: + { + struct tm tmp = *tm; + tmp.tm_isdst = -1; /* use timezone to figure it out */ + seconds = mktime(&tmp); + break; + } + default: + abort(); + } - return seconds - qemu_time(); + return seconds - qemu_ref_timedate(QEMU_CLOCK_HOST); } -static void configure_rtc_date_offset(const char *startdate) +static void configure_rtc_base_datetime(const char *startdate) { - time_t rtc_start_date; + time_t rtc_start_datetime; struct tm tm; if (sscanf(startdate, "%d-%d-%dT%d:%d:%d", &tm.tm_year, &tm.tm_mon, @@ -841,33 +864,40 @@ static void configure_rtc_date_offset(const char *startdate) } tm.tm_year -= 1900; tm.tm_mon--; - rtc_start_date = mktimegm(&tm); - if (rtc_start_date == -1) { + rtc_start_datetime = mktimegm(&tm); + if (rtc_start_datetime == -1) { date_fail: - error_report("invalid date format"); + error_report("invalid datetime format"); error_printf("valid formats: " "'2006-06-17T16:01:21' or '2006-06-17'\n"); exit(1); } - rtc_date_offset = qemu_time() - rtc_start_date; + rtc_host_datetime_offset = rtc_ref_start_datetime - rtc_start_datetime; + rtc_ref_start_datetime = rtc_start_datetime; } static void configure_rtc(QemuOpts *opts) { const char *value; + /* Set defaults */ + rtc_clock = QEMU_CLOCK_HOST; + rtc_ref_start_datetime = qemu_clock_get_ms(QEMU_CLOCK_HOST) / 1000; + rtc_realtime_clock_offset = qemu_clock_get_ms(QEMU_CLOCK_REALTIME) / 1000; + value = qemu_opt_get(opts, "base"); if (value) { if (!strcmp(value, "utc")) { - rtc_utc = 1; + rtc_base_type = RTC_BASE_UTC; } else if (!strcmp(value, "localtime")) { Error *blocker = NULL; - rtc_utc = 0; + rtc_base_type = RTC_BASE_LOCALTIME; error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "-rtc base=localtime"); replay_add_blocker(blocker); } else { - configure_rtc_date_offset(value); + rtc_base_type = RTC_BASE_DATETIME; + configure_rtc_base_datetime(value); } } value = qemu_opt_get(opts, "clock"); @@ -1129,7 +1159,7 @@ static int drive_init_func(void *opaque, QemuOpts *opts, Error **errp) { BlockInterfaceType *block_default_type = opaque; - return drive_new(opts, *block_default_type) == NULL; + return drive_new(opts, *block_default_type, errp) == NULL; } static int drive_enable_snapshot(void *opaque, QemuOpts *opts, Error **errp) @@ -1155,10 +1185,7 @@ static void default_drive(int enable, int snapshot, BlockInterfaceType type, drive_enable_snapshot(NULL, opts, NULL); } - dinfo = drive_new(opts, type); - if (!dinfo) { - exit(1); - } + dinfo = drive_new(opts, type, &error_abort); dinfo->is_default = true; } @@ -1199,11 +1226,14 @@ static void smp_parse(QemuOpts *opts) /* compute missing values, prefer sockets over cores over threads */ if (cpus == 0 || sockets == 0) { - sockets = sockets > 0 ? sockets : 1; cores = cores > 0 ? cores : 1; threads = threads > 0 ? threads : 1; if (cpus == 0) { + sockets = sockets > 0 ? sockets : 1; cpus = cores * threads * sockets; + } else { + max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus); + sockets = max_cpus / (cores * threads); } } else if (cores == 0) { threads = threads > 0 ? threads : 1; @@ -1235,6 +1265,13 @@ static void smp_parse(QemuOpts *opts) exit(1); } + if (sockets * cores * threads != max_cpus) { + warn_report("Invalid CPU topology deprecated: " + "sockets (%u) * cores (%u) * threads (%u) " + "!= maxcpus (%u)", + sockets, cores, threads, max_cpus); + } + smp_cpus = cpus; smp_cores = cores; smp_threads = threads; @@ -1481,16 +1518,13 @@ static int machine_help_func(QemuOpts *opts, MachineState *machine) return 1; } -/***********************************************************/ -/* main execution loop */ - struct vm_change_state_entry { VMChangeStateHandler *cb; void *opaque; QLIST_ENTRY (vm_change_state_entry) entries; }; -static QLIST_HEAD(vm_change_state_head, vm_change_state_entry) vm_change_state_head; +static QLIST_HEAD(, vm_change_state_entry) vm_change_state_head; VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb, void *opaque) @@ -1515,7 +1549,7 @@ void vm_state_notify(int running, RunState state) { VMChangeStateEntry *e, *next; - trace_vm_state_notify(running, state); + trace_vm_state_notify(running, state, RunState_str(state)); QLIST_FOREACH_SAFE(e, &vm_change_state_head, entries, next) { e->cb(e->opaque, running, state); @@ -1537,6 +1571,8 @@ static NotifierList suspend_notifiers = NOTIFIER_LIST_INITIALIZER(suspend_notifiers); static NotifierList wakeup_notifiers = NOTIFIER_LIST_INITIALIZER(wakeup_notifiers); +static NotifierList shutdown_notifiers = + NOTIFIER_LIST_INITIALIZER(shutdown_notifiers); static uint32_t wakeup_reason_mask = ~(1 << QEMU_WAKEUP_REASON_NONE); ShutdownCause qemu_shutdown_requested_get(void) @@ -1636,7 +1672,7 @@ void qemu_system_reset(ShutdownCause reason) qemu_devices_reset(); } if (reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) { - qapi_event_send_reset(shutdown_caused_by_guest(reason)); + qapi_event_send_reset(shutdown_caused_by_guest(reason), reason); } cpu_synchronize_all_post_reset(); } @@ -1712,11 +1748,13 @@ void qemu_register_suspend_notifier(Notifier *notifier) notifier_list_add(&suspend_notifiers, notifier); } -void qemu_system_wakeup_request(WakeupReason reason) +void qemu_system_wakeup_request(WakeupReason reason, Error **errp) { trace_system_wakeup_request(reason); if (!runstate_check(RUN_STATE_SUSPENDED)) { + error_setg(errp, + "Unable to wake up: guest is not in suspended state"); return; } if (!(wakeup_reason_mask & (1 << reason))) { @@ -1741,6 +1779,24 @@ void qemu_register_wakeup_notifier(Notifier *notifier) notifier_list_add(&wakeup_notifiers, notifier); } +void qemu_register_wakeup_support(void) +{ + wakeup_suspend_enabled = true; +} + +bool qemu_wakeup_suspend_enabled(void) +{ + return wakeup_suspend_enabled; +} + +CurrentMachineParams *qmp_query_current_machine(Error **errp) +{ + CurrentMachineParams *params = g_malloc0(sizeof(*params)); + params->wakeup_suspend_support = qemu_wakeup_suspend_enabled(); + + return params; +} + void qemu_system_killed(int signal, pid_t pid) { shutdown_signal = signal; @@ -1768,6 +1824,12 @@ static void qemu_system_powerdown(void) notifier_list_notify(&powerdown_notifiers, NULL); } +static void qemu_system_shutdown(ShutdownCause cause) +{ + qapi_event_send_shutdown(shutdown_caused_by_guest(cause), cause); + notifier_list_notify(&shutdown_notifiers, &cause); +} + void qemu_system_powerdown_request(void) { trace_qemu_system_powerdown_request(); @@ -1780,6 +1842,11 @@ void qemu_register_powerdown_notifier(Notifier *notifier) notifier_list_add(&powerdown_notifiers, notifier); } +void qemu_register_shutdown_notifier(Notifier *notifier) +{ + notifier_list_add(&shutdown_notifiers, notifier); +} + void qemu_system_debug_request(void) { debug_requested = 1; @@ -1807,7 +1874,7 @@ static bool main_loop_should_exit(void) request = qemu_shutdown_requested(); if (request) { qemu_kill_report(); - qapi_event_send_shutdown(shutdown_caused_by_guest(request)); + qemu_system_shutdown(request); if (no_shutdown) { vm_stop(RUN_STATE_SHUTDOWN); } else { @@ -2014,6 +2081,11 @@ static void parse_display_qapi(const char *optarg) visit_free(v); } +DisplayOptions *qmp_query_display_options(Error **errp) +{ + return QAPI_CLONE(DisplayOptions, &dpy); +} + static void parse_display(const char *p) { const char *opts; @@ -2033,18 +2105,7 @@ static void parse_display(const char *p) while (*opts) { const char *nextopt; - if (strstart(opts, ",frame=", &nextopt)) { - g_printerr("The frame= sdl option is deprecated, and will be\n" - "removed in a future release.\n"); - opts = nextopt; - if (strstart(opts, "on", &nextopt)) { - no_frame = 0; - } else if (strstart(opts, "off", &nextopt)) { - no_frame = 1; - } else { - goto invalid_sdl_args; - } - } else if (strstart(opts, ",alt_grab=", &nextopt)) { + if (strstart(opts, ",alt_grab=", &nextopt)) { opts = nextopt; if (strstart(opts, "on", &nextopt)) { alt_grab = 1; @@ -2174,7 +2235,7 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp) FWCfgState *fw_cfg = (FWCfgState *) opaque; if (fw_cfg == NULL) { - error_report("fw_cfg device not available"); + error_setg(errp, "fw_cfg device not available"); return -1; } name = qemu_opt_get(opts, "name"); @@ -2183,15 +2244,16 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp) /* we need name and either a file or the content string */ if (!(nonempty_str(name) && (nonempty_str(file) || nonempty_str(str)))) { - error_report("invalid argument(s)"); + error_setg(errp, "invalid argument(s)"); return -1; } if (nonempty_str(file) && nonempty_str(str)) { - error_report("file and string are mutually exclusive"); + error_setg(errp, "file and string are mutually exclusive"); return -1; } if (strlen(name) > FW_CFG_MAX_FILE_PATH - 1) { - error_report("name too long (max. %d char)", FW_CFG_MAX_FILE_PATH - 1); + error_setg(errp, "name too long (max. %d char)", + FW_CFG_MAX_FILE_PATH - 1); return -1; } if (strncmp(name, "opt/", 4) != 0) { @@ -2202,8 +2264,10 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp) size = strlen(str); /* NUL terminator NOT included in fw_cfg blob */ buf = g_memdup(str, size); } else { - if (!g_file_get_contents(file, &buf, &size, NULL)) { - error_report("can't load %s", file); + GError *err = NULL; + if (!g_file_get_contents(file, &buf, &size, &err)) { + error_setg(errp, "can't load %s: %s", file, err->message); + g_error_free(err); return -1; } } @@ -2221,12 +2285,10 @@ static int device_help_func(void *opaque, QemuOpts *opts, Error **errp) static int device_init_func(void *opaque, QemuOpts *opts, Error **errp) { - Error *err = NULL; DeviceState *dev; - dev = qdev_device_add(opts, &err); + dev = qdev_device_add(opts, errp); if (!dev) { - error_report_err(err); return -1; } object_unref(OBJECT(dev)); @@ -2237,7 +2299,7 @@ static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp) { Error *local_err = NULL; - if (!qemu_chr_new_from_opts(opts, &local_err)) { + if (!qemu_chr_new_from_opts(opts, NULL, &local_err)) { if (local_err) { error_propagate(errp, local_err); return -1; @@ -2250,7 +2312,7 @@ static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp) #ifdef CONFIG_VIRTFS static int fsdev_init_func(void *opaque, QemuOpts *opts, Error **errp) { - return qemu_fsdev_add(opts); + return qemu_fsdev_add(opts, errp); } #endif @@ -2270,23 +2332,22 @@ static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp) } else if (strcmp(mode, "control") == 0) { flags = MONITOR_USE_CONTROL; } else { - error_report("unknown monitor mode \"%s\"", mode); - exit(1); + error_setg(errp, "unknown monitor mode \"%s\"", mode); + return -1; } if (qemu_opt_get_bool(opts, "pretty", 0)) flags |= MONITOR_USE_PRETTY; - /* OOB is off by default */ - if (qemu_opt_get_bool(opts, "x-oob", 0)) { - flags |= MONITOR_USE_OOB; - } - chardev = qemu_opt_get(opts, "chardev"); + if (!chardev) { + error_report("chardev is required"); + exit(1); + } chr = qemu_chr_find(chardev); if (chr == NULL) { - error_report("chardev \"%s\" not found", chardev); - exit(1); + error_setg(errp, "chardev \"%s\" not found", chardev); + return -1; } monitor_init(chr, flags); @@ -2325,7 +2386,6 @@ struct device_config { DEV_BT, /* -bt */ DEV_SERIAL, /* -serial */ DEV_PARALLEL, /* -parallel */ - DEV_VIRTCON, /* -virtioconsole */ DEV_DEBUGCON, /* -debugcon */ DEV_GDB, /* -gdb, -s */ DEV_SCLP, /* s390 sclp */ @@ -2377,7 +2437,7 @@ static int serial_parse(const char *devname) snprintf(label, sizeof(label), "serial%d", index); serial_hds = g_renew(Chardev *, serial_hds, index + 1); - serial_hds[index] = qemu_chr_new_mux_mon(label, devname); + serial_hds[index] = qemu_chr_new_mux_mon(label, devname, NULL); if (!serial_hds[index]) { error_report("could not connect serial device" " to character backend '%s'", devname); @@ -2413,7 +2473,7 @@ static int parallel_parse(const char *devname) exit(1); } snprintf(label, sizeof(label), "parallel%d", index); - parallel_hds[index] = qemu_chr_new_mux_mon(label, devname); + parallel_hds[index] = qemu_chr_new_mux_mon(label, devname, NULL); if (!parallel_hds[index]) { error_report("could not connect parallel device" " to character backend '%s'", devname); @@ -2423,44 +2483,11 @@ static int parallel_parse(const char *devname) return 0; } -static int virtcon_parse(const char *devname) -{ - QemuOptsList *device = qemu_find_opts("device"); - static int index = 0; - char label[32]; - QemuOpts *bus_opts, *dev_opts; - - if (strcmp(devname, "none") == 0) - return 0; - if (index == MAX_VIRTIO_CONSOLES) { - error_report("too many virtio consoles"); - exit(1); - } - - bus_opts = qemu_opts_create(device, NULL, 0, &error_abort); - qemu_opt_set(bus_opts, "driver", "virtio-serial", &error_abort); - - dev_opts = qemu_opts_create(device, NULL, 0, &error_abort); - qemu_opt_set(dev_opts, "driver", "virtconsole", &error_abort); - - snprintf(label, sizeof(label), "virtcon%d", index); - virtcon_hds[index] = qemu_chr_new_mux_mon(label, devname); - if (!virtcon_hds[index]) { - error_report("could not connect virtio console" - " to character backend '%s'", devname); - return -1; - } - qemu_opt_set(dev_opts, "chardev", label, &error_abort); - - index++; - return 0; -} - static int debugcon_parse(const char *devname) { QemuOpts *opts; - if (!qemu_chr_new_mux_mon("debugcon", devname)) { + if (!qemu_chr_new_mux_mon("debugcon", devname, NULL)) { error_report("invalid character backend '%s'", devname); exit(1); } @@ -2677,7 +2704,7 @@ static int machine_set_property(void *opaque, g_free(qom_name); if (local_err) { - error_report_err(local_err); + error_propagate(errp, local_err); return -1; } @@ -2703,7 +2730,7 @@ static bool object_create_initial(const char *type, QemuOpts *opts) 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)); + printf(" %s\n", object_class_get_name(oc)); } g_slist_free(list); exit(0); @@ -2725,14 +2752,21 @@ static bool object_create_initial(const char *type, QemuOpts *opts) } str = g_string_new(NULL); - g_string_append_printf(str, "%s.%s=%s", type, - prop->name, prop->type); + 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]); } @@ -2880,8 +2914,6 @@ static int global_init_func(void *opaque, QemuOpts *opts, Error **errp) g->driver = qemu_opt_get(opts, "driver"); g->property = qemu_opt_get(opts, "property"); g->value = qemu_opt_get(opts, "value"); - g->user_provided = true; - g->errp = &error_fatal; qdev_prop_register_global(g); return 0; } @@ -2912,8 +2944,6 @@ static void user_register_global_props(void) */ static void register_global_properties(MachineState *ms) { - accel_register_compat_props(ms->accelerator); - machine_register_compat_props(ms); user_register_global_props(); } @@ -3006,6 +3036,7 @@ int main(int argc, char **argv, char **envp) module_call_init(MODULE_INIT_OPTS); runstate_init(); + precopy_infrastructure_init(); postcopy_infrastructure_init(); monitor_init_globals(); @@ -3013,7 +3044,6 @@ int main(int argc, char **argv, char **envp) error_reportf_err(err, "cannot initialize crypto: "); exit(1); } - rtc_clock = QEMU_CLOCK_HOST; QLIST_INIT (&vm_change_state_head); os_setup_early_signal_handling(); @@ -3083,11 +3113,8 @@ int main(int argc, char **argv, char **envp) Visitor *v; BlockdevOptions_queue *bdo; - v = qobject_input_visitor_new_str(optarg, "driver", &err); - if (!v) { - error_report_err(err); - exit(1); - } + v = qobject_input_visitor_new_str(optarg, "driver", + &error_fatal); bdo = g_new(BlockdevOptions_queue, 1); visit_type_BlockdevOptions(v, NULL, &bdo->bdo, @@ -3219,12 +3246,19 @@ int main(int argc, char **argv, char **envp) break; #endif case QEMU_OPTION_bt: + warn_report("The bluetooth subsystem is deprecated and will " + "be removed soon. If the bluetooth subsystem is " + "still useful for you, please send a mail to " + "qemu-devel@nongnu.org with your usecase."); add_device_config(DEV_BT, optarg); break; case QEMU_OPTION_audio_help: - AUD_help (); + audio_legacy_help(); exit (0); break; + case QEMU_OPTION_audiodev: + audio_parse_option(optarg); + break; case QEMU_OPTION_soundhw: select_soundhw (optarg); break; @@ -3487,15 +3521,6 @@ int main(int argc, char **argv, char **envp) exit(1); } break; - case QEMU_OPTION_virtiocon: - warn_report("This option is deprecated, " - "use '-device virtconsole' instead"); - add_device_config(DEV_VIRTCON, optarg); - default_virtcon = 0; - if (strncmp(optarg, "mon:", 4) == 0) { - default_monitor = 0; - } - break; case QEMU_OPTION_parallel: add_device_config(DEV_PARALLEL, optarg); default_parallel = 0; @@ -3513,11 +3538,6 @@ int main(int argc, char **argv, char **envp) dpy.has_full_screen = true; dpy.full_screen = true; break; - case QEMU_OPTION_no_frame: - g_printerr("The -no-frame switch is deprecated, and will be\n" - "removed in a future release.\n"); - no_frame = 1; - break; case QEMU_OPTION_alt_grab: alt_grab = 1; break; @@ -3572,11 +3592,6 @@ 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: - warn_report("Option is deprecated, use '-accel hax' instead"); - 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"); @@ -3721,19 +3736,12 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_old_param: old_param = 1; break; - case QEMU_OPTION_clock: - /* Clock options no longer exist. Keep this option for - * backward compatibility. - */ - warn_report("This option is ignored and will be removed soon"); - break; case QEMU_OPTION_rtc: opts = qemu_opts_parse_noisily(qemu_find_opts("rtc"), optarg, false); if (!opts) { exit(1); } - configure_rtc(opts); break; case QEMU_OPTION_tb_size: #ifndef CONFIG_TCG @@ -3777,13 +3785,6 @@ int main(int argc, char **argv, char **envp) } xen_domid = atoi(optarg); break; - case QEMU_OPTION_xen_create: - if (!(xen_available())) { - error_report("Option not supported for this target"); - exit(1); - } - xen_mode = XEN_CREATE; - break; case QEMU_OPTION_xen_attach: if (!(xen_available())) { error_report("Option not supported for this target"); @@ -3951,6 +3952,8 @@ int main(int argc, char **argv, char **envp) exit(EXIT_FAILURE); } + configure_rtc(qemu_find_opts_singleton("rtc")); + machine_class = select_machine(); set_memory_options(&ram_slots, &maxram_size, machine_class); @@ -3978,10 +3981,8 @@ int main(int argc, char **argv, char **envp) } #endif - if (qemu_opts_foreach(qemu_find_opts("name"), - parse_name, NULL, NULL)) { - exit(1); - } + qemu_opts_foreach(qemu_find_opts("name"), + parse_name, NULL, &error_fatal); #ifndef _WIN32 qemu_opts_foreach(qemu_find_opts("add-fd"), @@ -4113,9 +4114,6 @@ int main(int argc, char **argv, char **envp) if (!has_defaults || machine_class->no_parallel) { default_parallel = 0; } - if (!has_defaults || !machine_class->use_virtcon) { - default_virtcon = 0; - } if (!has_defaults || machine_class->no_floppy) { default_floppy = 0; } @@ -4148,8 +4146,7 @@ int main(int argc, char **argv, char **envp) * usage, -nographic is just a no-op in this case. */ if (nographic - && (default_parallel || default_serial - || default_monitor || default_virtcon)) { + && (default_parallel || default_serial || default_monitor)) { error_report("-nographic cannot be used with -daemonize"); exit(1); } @@ -4166,13 +4163,9 @@ int main(int argc, char **argv, char **envp) add_device_config(DEV_PARALLEL, "null"); if (default_serial && default_monitor) { add_device_config(DEV_SERIAL, "mon:stdio"); - } else if (default_virtcon && default_monitor) { - add_device_config(DEV_VIRTCON, "mon:stdio"); } else { if (default_serial) add_device_config(DEV_SERIAL, "stdio"); - if (default_virtcon) - add_device_config(DEV_VIRTCON, "stdio"); if (default_monitor) monitor_parse("stdio", "readline", false); } @@ -4183,8 +4176,6 @@ int main(int argc, char **argv, char **envp) add_device_config(DEV_PARALLEL, "vc:80Cx24C"); if (default_monitor) monitor_parse("vc:80Cx24C", "readline", false); - if (default_virtcon) - add_device_config(DEV_VIRTCON, "vc:80Cx24C"); } #if defined(CONFIG_VNC) @@ -4204,8 +4195,8 @@ int main(int argc, char **argv, char **envp) dpy.type = DISPLAY_TYPE_NONE; } - if ((no_frame || alt_grab || ctrl_grab) && dpy.type != DISPLAY_TYPE_SDL) { - error_report("-no-frame, -alt-grab and -ctrl-grab are only valid " + if ((alt_grab || ctrl_grab) && dpy.type != DISPLAY_TYPE_SDL) { + error_report("-alt-grab and -ctrl-grab are only valid " "for SDL, ignoring option"); } if (dpy.has_window_close && @@ -4237,10 +4228,8 @@ int main(int argc, char **argv, char **envp) chardev_init_func, NULL, &error_fatal); #ifdef CONFIG_VIRTFS - if (qemu_opts_foreach(qemu_find_opts("fsdev"), - fsdev_init_func, NULL, NULL)) { - exit(1); - } + qemu_opts_foreach(qemu_find_opts("fsdev"), + fsdev_init_func, NULL, &error_fatal); #endif if (qemu_opts_foreach(qemu_find_opts("device"), @@ -4249,13 +4238,13 @@ int main(int argc, char **argv, char **envp) } machine_opts = qemu_get_machine_opts(); - if (qemu_opt_foreach(machine_opts, machine_set_property, current_machine, - NULL)) { - object_unref(OBJECT(current_machine)); - exit(1); - } + qemu_opt_foreach(machine_opts, machine_set_property, current_machine, + &error_fatal); + current_machine->ram_size = ram_size; + current_machine->maxram_size = maxram_size; + current_machine->ram_slots = ram_slots; - configure_accelerator(current_machine); + configure_accelerator(current_machine, argv[0]); if (!qtest_enabled() && machine_class->deprecation_reason) { error_report("Machine type '%s' is deprecated: %s", @@ -4353,8 +4342,6 @@ int main(int argc, char **argv, char **envp) #endif } - colo_info_init(); - if (net_init_clients(&err) < 0) { error_report_err(err); exit(1); @@ -4364,9 +4351,7 @@ int main(int argc, char **argv, char **envp) user_creatable_add_opts_foreach, object_create_delayed, &error_fatal); - if (tpm_init() < 0) { - exit(1); - } + tpm_init(); /* init the bluetooth world */ if (foreach_device_config(DEV_BT, bt_parse)) @@ -4407,8 +4392,9 @@ int main(int argc, char **argv, char **envp) NULL, NULL); } if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func, - &machine_class->block_default_type, NULL)) { - exit(1); + &machine_class->block_default_type, &error_fatal)) { + /* We printed help */ + exit(0); } default_drive(default_cdrom, snapshot, machine_class->block_default_type, 2, @@ -4416,17 +4402,13 @@ int main(int argc, char **argv, char **envp) default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS); default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS); - if (qemu_opts_foreach(qemu_find_opts("mon"), - mon_init_func, NULL, NULL)) { - exit(1); - } + qemu_opts_foreach(qemu_find_opts("mon"), + mon_init_func, NULL, &error_fatal); if (foreach_device_config(DEV_SERIAL, serial_parse) < 0) exit(1); if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0) exit(1); - if (foreach_device_config(DEV_VIRTCON, virtcon_parse) < 0) - exit(1); if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0) exit(1); @@ -4456,9 +4438,6 @@ int main(int argc, char **argv, char **envp) replay_checkpoint(CHECKPOINT_INIT); qdev_machine_init(); - current_machine->ram_size = ram_size; - current_machine->maxram_size = maxram_size; - current_machine->ram_slots = ram_slots; current_machine->boot_order = boot_order; /* parse features once if machine provides default cpu_type */ @@ -4471,6 +4450,8 @@ int main(int argc, char **argv, char **envp) /* do monitor/qmp handling at preconfig state if requested */ main_loop(); + audio_init_audiodevs(); + /* from here on runstate is RUN_STATE_PRELAUNCH */ machine_run_board_init(current_machine); @@ -4482,10 +4463,8 @@ int main(int argc, char **argv, char **envp) hax_sync_vcpus(); } - if (qemu_opts_foreach(qemu_find_opts("fw_cfg"), - parse_fw_cfg, fw_cfg_find(), NULL) != 0) { - exit(1); - } + qemu_opts_foreach(qemu_find_opts("fw_cfg"), + parse_fw_cfg, fw_cfg_find(), &error_fatal); /* init USB devices */ if (machine_usb(current_machine)) { @@ -4498,10 +4477,8 @@ int main(int argc, char **argv, char **envp) /* init generic devices */ rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE); - if (qemu_opts_foreach(qemu_find_opts("device"), - device_init_func, NULL, NULL)) { - exit(1); - } + qemu_opts_foreach(qemu_find_opts("device"), + device_init_func, NULL, &error_fatal); cpu_synchronize_all_post_init(); @@ -4537,7 +4514,7 @@ int main(int argc, char **argv, char **envp) /* init remote displays */ #ifdef CONFIG_VNC qemu_opts_foreach(qemu_find_opts("vnc"), - vnc_init_func, NULL, NULL); + vnc_init_func, NULL, &error_fatal); #endif if (using_spice) { @@ -4605,6 +4582,12 @@ int main(int argc, char **argv, char **envp) gdbserver_cleanup(); + /* + * cleaning up the migration object cancels any existing migration + * try to do this early so that it also stops using devices. + */ + migration_shutdown(); + /* No more vcpu or device emulation activity beyond this point */ vm_shutdown(); @@ -4620,7 +4603,6 @@ int main(int argc, char **argv, char **envp) monitor_cleanup(); qemu_chr_cleanup(); user_creatable_cleanup(); - migration_object_finalize(); /* TODO: unref root container, check all devices are ok */ return 0;