X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/e35ee7c1aa1f257d3e0e52422cf4bd79d3b68d58..a74229597e2c226a1a1f46a8926a0d2ec9c7574e:/vl.c diff --git a/vl.c b/vl.c index 064870561a..9bb7f4cd70 100644 --- a/vl.c +++ b/vl.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "qemu/osdep.h" +#include "qemu-version.h" #include "qemu/cutils.h" #include "qemu/help_option.h" @@ -51,7 +52,6 @@ int main(int argc, char **argv) #define main qemu_main #endif /* CONFIG_COCOA */ -#include #include "qemu/error-report.h" #include "qemu/sockets.h" @@ -129,10 +129,8 @@ static const char *data_dir[16]; static int data_dir_idx; const char *bios_name = NULL; enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB; -DisplayType display_type = DT_DEFAULT; int request_opengl = -1; int display_opengl; -static int display_remote; const char* keyboard_layout = NULL; ram_addr_t ram_size; const char *mem_path = NULL; @@ -148,9 +146,7 @@ int vga_interface_type = VGA_NONE; static int full_screen = 0; static int no_frame = 0; int no_quit = 0; -#ifdef CONFIG_GTK static bool grab_on_hover; -#endif CharDriverState *serial_hds[MAX_SERIAL_PORTS]; CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES]; @@ -158,7 +154,7 @@ CharDriverState *sclp_hds[MAX_SCLP_CONSOLES]; int win2k_install_hack = 0; int singlestep = 0; int smp_cpus = 1; -int max_cpus = 0; +int max_cpus = 1; int smp_cores = 1; int smp_threads = 1; int acpi_enabled = 1; @@ -211,6 +207,7 @@ static int default_floppy = 1; static int default_cdrom = 1; static int default_sdcard = 1; static int default_vga = 1; +static int default_net = 1; static struct { const char *driver; @@ -265,26 +262,6 @@ static QemuOptsList qemu_sandbox_opts = { }, }; -static QemuOptsList qemu_trace_opts = { - .name = "trace", - .implied_opt_name = "enable", - .head = QTAILQ_HEAD_INITIALIZER(qemu_trace_opts.head), - .desc = { - { - .name = "enable", - .type = QEMU_OPT_STRING, - }, - { - .name = "events", - .type = QEMU_OPT_STRING, - },{ - .name = "file", - .type = QEMU_OPT_STRING, - }, - { /* end of list */ } - }, -}; - static QemuOptsList qemu_option_rom_opts = { .name = "option-rom", .implied_opt_name = "romfile", @@ -694,6 +671,10 @@ void runstate_set(RunState new_state) { assert(new_state < RUN_STATE__MAX); + if (current_run_state == new_state) { + return; + } + if (!runstate_valid_transitions[current_run_state][new_state]) { error_report("invalid runstate transition: '%s' -> '%s'", RunState_lookup[current_run_state], @@ -892,16 +873,13 @@ static void configure_rtc(QemuOpts *opts) value = qemu_opt_get(opts, "driftfix"); if (value) { if (!strcmp(value, "slew")) { - static GlobalProperty slew_lost_ticks[] = { - { - .driver = "mc146818rtc", - .property = "lost_tick_policy", - .value = "slew", - }, - { /* end of list */ } + static GlobalProperty slew_lost_ticks = { + .driver = "mc146818rtc", + .property = "lost_tick_policy", + .value = "slew", }; - qdev_prop_register_global_list(slew_lost_ticks); + qdev_prop_register_global(&slew_lost_ticks); } else if (!strcmp(value, "none")) { /* discard is default */ } else { @@ -1074,11 +1052,6 @@ bool defaults_enabled(void) return has_defaults; } -bool usb_enabled(void) -{ - return machine_usb(current_machine); -} - #ifndef _WIN32 static int parse_add_fd(void *opaque, QemuOpts *opts, Error **errp) { @@ -1225,7 +1198,6 @@ static QemuOptsList qemu_smp_opts = { static void smp_parse(QemuOpts *opts) { if (opts) { - unsigned cpus = qemu_opt_get_number(opts, "cpus", 0); unsigned sockets = qemu_opt_get_number(opts, "sockets", 0); unsigned cores = qemu_opt_get_number(opts, "cores", 0); @@ -1242,8 +1214,10 @@ static void smp_parse(QemuOpts *opts) } else if (cores == 0) { threads = threads > 0 ? threads : 1; cores = cpus / (sockets * threads); + cores = cores > 0 ? cores : 1; } else if (threads == 0) { threads = cpus / (cores * sockets); + threads = threads > 0 ? threads : 1; } else if (sockets * cores * threads < cpus) { error_report("cpu topology: " "sockets (%u) * cores (%u) * threads (%u) < " @@ -1253,6 +1227,17 @@ 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); + } + if (sockets * cores * threads > max_cpus) { error_report("cpu topology: " "sockets (%u) * cores (%u) * threads (%u) > " @@ -1262,25 +1247,11 @@ static void smp_parse(QemuOpts *opts) } smp_cpus = cpus; - smp_cores = cores > 0 ? cores : 1; - smp_threads = threads > 0 ? threads : 1; - - } - - if (max_cpus == 0) { - max_cpus = smp_cpus; - } - - if (max_cpus > MAX_CPUMASK_BITS) { - error_report("unsupported number of maxcpus"); - exit(1); - } - if (max_cpus < smp_cpus) { - error_report("maxcpus must be equal to or greater than smp"); - exit(1); + smp_cores = cores; + smp_threads = threads; } - if (smp_cpus > 1 || smp_cores > 1 || smp_threads > 1) { + if (smp_cpus > 1) { Error *blocker = NULL; error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp"); replay_add_blocker(blocker); @@ -1395,7 +1366,7 @@ static int usb_device_add(const char *devname) const char *p; #endif - if (!usb_enabled()) { + if (!machine_usb(current_machine)) { return -1; } @@ -1427,7 +1398,7 @@ static int usb_device_del(const char *devname) return -1; } - if (!usb_enabled()) { + if (!machine_usb(current_machine)) { return -1; } @@ -1535,6 +1506,7 @@ MachineInfoList *qmp_query_machines(Error **errp) info->name = g_strdup(mc->name); info->cpu_max = !mc->max_cpus ? 1 : mc->max_cpus; + info->hotpluggable_cpus = !!mc->query_hotpluggable_cpus; entry = g_malloc0(sizeof(*entry)); entry->value = info; @@ -2080,6 +2052,15 @@ static void select_vgahw(const char *p) } } +typedef enum DisplayType { + DT_DEFAULT, + DT_CURSES, + DT_SDL, + DT_COCOA, + DT_GTK, + DT_NONE, +} DisplayType; + static DisplayType select_display(const char *p) { const char *opts; @@ -2149,11 +2130,7 @@ static DisplayType select_display(const char *p) #endif } else if (strstart(p, "vnc", &opts)) { if (*opts == '=') { - Error *err = NULL; - if (vnc_parse(opts + 1, &err) == NULL) { - error_report_err(err); - exit(1); - } + vnc_parse(opts + 1, &error_fatal); } else { error_report("VNC requires a display argument vnc="); exit(1); @@ -2358,10 +2335,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) { - int ret; - ret = qemu_fsdev_add(opts); - - return ret; + return qemu_fsdev_add(opts); } #endif @@ -2406,7 +2380,6 @@ static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp) static void monitor_parse(const char *optarg, const char *mode, bool pretty) { static int monitor_device_index = 0; - Error *local_err = NULL; QemuOpts *opts; const char *p; char label[32]; @@ -2427,11 +2400,7 @@ static void monitor_parse(const char *optarg, const char *mode, bool pretty) } } - opts = qemu_opts_create(qemu_find_opts("mon"), label, 1, &local_err); - if (!opts) { - error_report_err(local_err); - exit(1); - } + opts = qemu_opts_create(qemu_find_opts("mon"), label, 1, &error_fatal); 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); @@ -2961,9 +2930,11 @@ int main(int argc, char **argv, char **envp) const char *qtest_log = NULL; const char *pid_file = NULL; const char *incoming = NULL; - int show_vnc_port = 0; bool defconfig = true; bool userconfig = true; + bool nographic = false; + DisplayType display_type = DT_DEFAULT; + int display_remote = 0; const char *log_mask = NULL; const char *log_file = NULL; char *trace_file = NULL; @@ -2972,6 +2943,7 @@ int main(int argc, char **argv, char **envp) FILE *vmstate_dump_file = NULL; Error *main_loop_err = NULL; Error *err = NULL; + bool list_data_dirs = false; qemu_init_cpu_loop(); qemu_mutex_lock_iothread(); @@ -3075,7 +3047,7 @@ int main(int argc, char **argv, char **envp) popt = lookup_opt(argc, argv, &optarg, &optind); if (!(popt->arch_mask & arch_type)) { - printf("Option %s not supported for this target\n", popt->name); + error_report("Option not supported for this target"); exit(1); } switch(popt->index) { @@ -3208,7 +3180,10 @@ int main(int argc, char **argv, char **envp) display_type = select_display(optarg); break; case QEMU_OPTION_nographic: - display_type = DT_NOGRAPHIC; + olist = qemu_find_opts("machine"); + qemu_opts_parse_noisily(olist, "graphics=off", false); + nographic = true; + display_type = DT_NONE; break; case QEMU_OPTION_curses: #ifdef CONFIG_CURSES @@ -3264,11 +3239,13 @@ int main(int argc, char **argv, char **envp) fd_bootchk = 0; break; case QEMU_OPTION_netdev: + default_net = 0; if (net_client_parse(qemu_find_opts("netdev"), optarg) == -1) { exit(1); } break; case QEMU_OPTION_net: + default_net = 0; if (net_client_parse(qemu_find_opts("net"), optarg) == -1) { exit(1); } @@ -3344,7 +3321,7 @@ int main(int argc, char **argv, char **envp) log_file = optarg; break; case QEMU_OPTION_DFILTER: - qemu_set_dfilter_ranges(optarg); + qemu_set_dfilter_ranges(optarg, &error_fatal); break; case QEMU_OPTION_s: add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT); @@ -3353,7 +3330,9 @@ int main(int argc, char **argv, char **envp) add_device_config(DEV_GDB, optarg); break; case QEMU_OPTION_L: - if (data_dir_idx < ARRAY_SIZE(data_dir)) { + if (is_help_option(optarg)) { + list_data_dirs = true; + } else if (data_dir_idx < ARRAY_SIZE(data_dir)) { data_dir[data_dir_idx++] = optarg; } break; @@ -3615,16 +3594,13 @@ int main(int argc, char **argv, char **envp) win2k_install_hack = 1; break; case QEMU_OPTION_rtc_td_hack: { - static GlobalProperty slew_lost_ticks[] = { - { - .driver = "mc146818rtc", - .property = "lost_tick_policy", - .value = "slew", - }, - { /* end of list */ } + static GlobalProperty slew_lost_ticks = { + .driver = "mc146818rtc", + .property = "lost_tick_policy", + .value = "slew", }; - qdev_prop_register_global_list(slew_lost_ticks); + qdev_prop_register_global(&slew_lost_ticks); break; } case QEMU_OPTION_acpitable: @@ -3671,18 +3647,15 @@ int main(int argc, char **argv, char **envp) break; } case QEMU_OPTION_no_kvm_pit_reinjection: { - static GlobalProperty kvm_pit_lost_tick_policy[] = { - { - .driver = "kvm-pit", - .property = "lost_tick_policy", - .value = "discard", - }, - { /* end of list */ } + static GlobalProperty kvm_pit_lost_tick_policy = { + .driver = "kvm-pit", + .property = "lost_tick_policy", + .value = "discard", }; error_report("warning: deprecated, replaced by " "-global kvm-pit.lost_tick_policy=discard"); - qdev_prop_register_global_list(kvm_pit_lost_tick_policy); + qdev_prop_register_global(&kvm_pit_lost_tick_policy); break; } case QEMU_OPTION_usb: @@ -3707,15 +3680,8 @@ int main(int argc, char **argv, char **envp) } break; case QEMU_OPTION_vnc: - { - Error *local_err = NULL; - - if (vnc_parse(optarg, &local_err) == NULL) { - error_report_err(local_err); - exit(1); - } + vnc_parse(optarg, &error_fatal); break; - } case QEMU_OPTION_no_acpi: acpi_enabled = 0; break; @@ -3859,43 +3825,29 @@ int main(int argc, char **argv, char **envp) break; case QEMU_OPTION_xen_domid: if (!(xen_available())) { - printf("Option %s not supported for this target\n", popt->name); + error_report("Option not supported for this target"); exit(1); } xen_domid = atoi(optarg); break; case QEMU_OPTION_xen_create: if (!(xen_available())) { - printf("Option %s not supported for this target\n", popt->name); + error_report("Option not supported for this target"); exit(1); } xen_mode = XEN_CREATE; break; case QEMU_OPTION_xen_attach: if (!(xen_available())) { - printf("Option %s not supported for this target\n", popt->name); + error_report("Option not supported for this target"); exit(1); } xen_mode = XEN_ATTACH; break; case QEMU_OPTION_trace: - { - opts = qemu_opts_parse_noisily(qemu_find_opts("trace"), - optarg, true); - if (!opts) { - exit(1); - } - if (qemu_opt_get(opts, "enable")) { - trace_enable_events(qemu_opt_get(opts, "enable")); - } - trace_init_events(qemu_opt_get(opts, "events")); - if (trace_file) { - g_free(trace_file); - } - trace_file = g_strdup(qemu_opt_get(opts, "file")); - qemu_opts_del(opts); + g_free(trace_file); + trace_file = trace_opt_parse(optarg); break; - } case QEMU_OPTION_readconfig: { int ret = qemu_read_config_file(optarg); @@ -4057,13 +4009,6 @@ int main(int argc, char **argv, char **envp) qemu_set_hw_version(machine_class->hw_version); } - /* Init CPU def lists, based on config - * - Must be called after all the qemu_read_config_file() calls - * - Must be called before list_cpus() - * - Must be called before machine_class->init() - */ - cpudef_init(); - if (cpu_model && is_help_option(cpu_model)) { list_cpus(stdout, &fprintf, cpu_model); exit(0); @@ -4077,7 +4022,7 @@ int main(int argc, char **argv, char **envp) /* Open the logfile at this point and set the log mask if necessary. */ if (log_file) { - qemu_set_log_filename(log_file); + qemu_set_log_filename(log_file, &error_fatal); } if (log_mask) { @@ -4105,6 +4050,14 @@ int main(int argc, char **argv, char **envp) data_dir[data_dir_idx++] = CONFIG_QEMU_DATADIR; } + /* -L help lists the data directories and exits. */ + if (list_data_dirs) { + for (i = 0; i < data_dir_idx; i++) { + printf("%s\n", data_dir[i]); + } + exit(0); + } + smp_parse(qemu_opts_find(qemu_find_opts("smp-opts"), NULL)); machine_class->max_cpus = machine_class->max_cpus ?: 1; /* Default to UP */ @@ -4169,7 +4122,7 @@ int main(int argc, char **argv, char **envp) * -nographic _and_ redirects all ports explicitly - this is valid * usage, -nographic is just a no-op in this case. */ - if (display_type == DT_NOGRAPHIC + if (nographic && (default_parallel || default_serial || default_monitor || default_virtcon)) { error_report("-nographic cannot be used with -daemonize"); @@ -4183,7 +4136,7 @@ int main(int argc, char **argv, char **envp) #endif } - if (display_type == DT_NOGRAPHIC) { + if (nographic) { if (default_parallel) add_device_config(DEV_PARALLEL, "null"); if (default_serial && default_monitor) { @@ -4231,7 +4184,6 @@ int main(int argc, char **argv, char **envp) display_type = DT_COCOA; #elif defined(CONFIG_VNC) vnc_parse("localhost:0,to=99,id=default", &error_abort); - show_vnc_port = 1; #else display_type = DT_NONE; #endif @@ -4246,11 +4198,10 @@ int main(int argc, char **argv, char **envp) "ignoring option"); } -#if defined(CONFIG_GTK) if (display_type == DT_GTK) { early_gtk_display_init(request_opengl); } -#endif + if (display_type == DT_SDL) { sdl_display_early_init(request_opengl); } @@ -4363,10 +4314,8 @@ int main(int argc, char **argv, char **envp) os_set_line_buffering(); -#ifdef CONFIG_SPICE /* spice needs the timers to be initialized by this point */ qemu_spice_init(); -#endif cpu_ticks_init(); if (icount_opts) { @@ -4381,6 +4330,14 @@ int main(int argc, char **argv, char **envp) /* clean up network at qemu process termination */ atexit(&net_cleanup); + if (default_net) { + QemuOptsList *net = qemu_find_opts("net"); + qemu_opts_set(net, NULL, "type", "nic", &error_abort); +#ifdef CONFIG_SLIRP + qemu_opts_set(net, NULL, "type", "user", &error_abort); +#endif + } + if (net_init_clients() < 0) { exit(1); } @@ -4474,7 +4431,11 @@ int main(int argc, char **argv, char **envp) } if (machine_class->compat_props) { - qdev_prop_register_global_list(machine_class->compat_props); + GlobalProperty *p; + for (i = 0; i < machine_class->compat_props->len; i++) { + p = g_array_index(machine_class->compat_props, GlobalProperty *, i); + qdev_prop_register_global(p); + } } qemu_add_globals(); @@ -4506,7 +4467,7 @@ int main(int argc, char **argv, char **envp) } /* init USB devices */ - if (usb_enabled()) { + if (machine_usb(current_machine)) { if (foreach_device_config(DEV_USB, usb_parse) < 0) exit(1); } @@ -4525,7 +4486,18 @@ int main(int argc, char **argv, char **envp) /* Did we create any drives that we failed to create a device for? */ drive_check_orphaned(); - net_check_clients(); + /* Don't warn about the default network setup that you get if + * no command line -net or -netdev options are specified. There + * are two cases that we would otherwise complain about: + * (1) board doesn't support a NIC but the implicit "-net nic" + * requested one + * (2) CONFIG_SLIRP not set, in which case the implicit "-net nic" + * sets up a nic that isn't connected to anything. + */ + if (!default_net) { + net_check_clients(); + } + if (boot_once) { qemu_boot_set(boot_once, &error_fatal); @@ -4536,9 +4508,6 @@ int main(int argc, char **argv, char **envp) /* init local displays */ switch (display_type) { - case DT_NOGRAPHIC: - (void)ds; /* avoid warning if no display is configured */ - break; case DT_CURSES: curses_display_init(ds, full_screen); break; @@ -4548,11 +4517,9 @@ int main(int argc, char **argv, char **envp) case DT_COCOA: cocoa_display_init(ds, full_screen); break; -#if defined(CONFIG_GTK) case DT_GTK: gtk_display_init(ds, full_screen, grab_on_hover); break; -#endif default: break; } @@ -4561,19 +4528,14 @@ int main(int argc, char **argv, char **envp) os_setup_signal_handling(); /* init remote displays */ +#ifdef CONFIG_VNC qemu_opts_foreach(qemu_find_opts("vnc"), vnc_init_func, NULL, NULL); - if (show_vnc_port) { - char *ret = vnc_display_local_addr("default"); - printf("VNC server running on '%s'\n", ret); - g_free(ret); - } +#endif -#ifdef CONFIG_SPICE if (using_spice) { qemu_spice_display_init(); } -#endif if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) { exit(1);