From patchwork Thu Dec 2 07:04:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 12651845 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A5B7CC433F5 for ; Thu, 2 Dec 2021 07:36:00 +0000 (UTC) Received: from localhost ([::1]:48356 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1msgdJ-000452-Q7 for qemu-devel@archiver.kernel.org; Thu, 02 Dec 2021 02:35:59 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39726) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9Y-0005Wc-2b for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:12 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:27385) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9S-0006GW-8t for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:11 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1638428705; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UzbvYN56df4LIB93KRQZmMV/XvEkPHi500j7K31YoB0=; b=G0N+VYeXTtHLOt79aZw4gqGB2TQw+DraJ3FwQQDlgXEB9Jj+zQdywc6WekFrwMzQe6p8PD 4Pa59MrV88nCSmzaS5yaIdDTRMCwT1fh+rdHwbX8X2Mj6vO97B32E+LhDFC/ajVq1vckJ5 ao0jNiyVxS0yxtpE+QUcgJNIBws0LIo= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-344-xIF6AqeQNsuWhvVYK2ymSg-1; Thu, 02 Dec 2021 02:04:58 -0500 X-MC-Unique: xIF6AqeQNsuWhvVYK2ymSg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CA7E483DD20; Thu, 2 Dec 2021 07:04:56 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-112-7.ams2.redhat.com [10.36.112.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 95F1F60C05; Thu, 2 Dec 2021 07:04:51 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 119211138606; Thu, 2 Dec 2021 08:04:50 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Subject: [PATCH RFC 01/11] vl: Cut off the CLI with an axe Date: Thu, 2 Dec 2021 08:04:40 +0100 Message-Id: <20211202070450.264743-2-armbru@redhat.com> In-Reply-To: <20211202070450.264743-1-armbru@redhat.com> References: <20211202070450.264743-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=armbru@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.719, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: damien.hedde@greensocs.com, berrange@redhat.com, mark.burton@greensocs.com, edgar.iglesias@gmail.co, mirela.grujic@greensocs.com, marcandre.lureau@redhat.com, pbonzini@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" qemu-system-FOO starts up like this: 0. Basic, configuration-independent initialization 1. Parse and partially process CLI left to right 2. Startup with the remaining CLI processing mixed in With -preconfig, some of this is delayed until QMP command x-exit-preconfig. 3. Run main loop Monitors (if any) become available here. Note: * CLI is processed out of order. Few people understand the order, and only while starting at the code. Pretty much every time we mess with the order, we break something. * Without -preconfig, QMP becomes available only after startup is complete. Precludes use for initial configuration. -preconfig gives QMP one hook into startup, right before machine initialization. That's too early for cold-plugging devices. One hook doesn't fit all. * With -preconfig, CLI processing is interleaved with (in-order) QMP execution. I'm going to explore cleaner and more flexible startup code and CLI processing. The intertwined nature of the two makes this hard. So I start with cutting off the CLI entirely. I cut with an axe: certainly not enough (there's plenty of now unused CLI processing left, mostly in other files), and possibly too much (startup work might hide in the code I cut). Signed-off-by: Markus Armbruster --- softmmu/vl.c | 2694 +------------------------------------------------- 1 file changed, 13 insertions(+), 2681 deletions(-) diff --git a/softmmu/vl.c b/softmmu/vl.c index 620a1f1367..2bad7a437e 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -129,89 +129,14 @@ #include "config-host.h" -#define MAX_VIRTIO_CONSOLES 1 - -typedef struct BlockdevOptionsQueueEntry { - BlockdevOptions *bdo; - Location loc; - QSIMPLEQ_ENTRY(BlockdevOptionsQueueEntry) entry; -} BlockdevOptionsQueueEntry; - -typedef QSIMPLEQ_HEAD(, BlockdevOptionsQueueEntry) BlockdevOptionsQueue; - -typedef struct ObjectOption { - ObjectOptions *opts; - QTAILQ_ENTRY(ObjectOption) next; -} ObjectOption; - -typedef struct DeviceOption { - QDict *opts; - Location loc; - QTAILQ_ENTRY(DeviceOption) next; -} DeviceOption; - -static const char *cpu_option; -static const char *mem_path; static const char *incoming; -static const char *loadvm; static const char *accelerators; -static QDict *machine_opts_dict; -static QTAILQ_HEAD(, ObjectOption) object_opts = QTAILQ_HEAD_INITIALIZER(object_opts); -static QTAILQ_HEAD(, DeviceOption) device_opts = QTAILQ_HEAD_INITIALIZER(device_opts); static ram_addr_t maxram_size; static uint64_t ram_slots; static int display_remote; -static int snapshot; static bool preconfig_requested; -static QemuPluginList plugin_list = QTAILQ_HEAD_INITIALIZER(plugin_list); -static BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue); -static bool nographic = false; -static int mem_prealloc; /* force preallocation of physical target memory */ static ram_addr_t ram_size; -static const char *vga_model = NULL; static DisplayOptions dpy; -static int num_serial_hds; -static Chardev **serial_hds; -static const char *log_mask; -static const char *log_file; -static bool list_data_dirs; -static const char *watchdog; -static const char *qtest_chrdev; -static const char *qtest_log; - -static int has_defaults = 1; -static int default_serial = 1; -static int default_parallel = 1; -static int default_monitor = 1; -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; - int *flag; -} default_list[] = { - { .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 = "scsi-cd", .flag = &default_cdrom }, - { .driver = "scsi-hd", .flag = &default_cdrom }, - { .driver = "VGA", .flag = &default_vga }, - { .driver = "isa-vga", .flag = &default_vga }, - { .driver = "cirrus-vga", .flag = &default_vga }, - { .driver = "isa-cirrus-vga", .flag = &default_vga }, - { .driver = "vmware-svga", .flag = &default_vga }, - { .driver = "qxl-vga", .flag = &default_vga }, - { .driver = "virtio-vga", .flag = &default_vga }, - { .driver = "ati-vga", .flag = &default_vga }, - { .driver = "vhost-user-vga", .flag = &default_vga }, - { .driver = "virtio-vga-gl", .flag = &default_vga }, -}; static QemuOptsList qemu_rtc_opts = { .name = "rtc", @@ -501,214 +426,9 @@ const char *qemu_get_vm_name(void) return qemu_name; } -static void default_driver_disable(const char *driver) -{ - int i; - - if (!driver) { - return; - } - - for (i = 0; i < ARRAY_SIZE(default_list); i++) { - if (strcmp(default_list[i].driver, driver) != 0) - continue; - *(default_list[i].flag) = 0; - } -} - -static int default_driver_check(void *opaque, QemuOpts *opts, Error **errp) -{ - const char *driver = qemu_opt_get(opts, "driver"); - - default_driver_disable(driver); - return 0; -} - -static void default_driver_check_json(void) -{ - DeviceOption *opt; - - QTAILQ_FOREACH(opt, &device_opts, next) { - const char *driver = qdict_get_try_str(opt->opts, "driver"); - default_driver_disable(driver); - } -} - -static int parse_name(void *opaque, QemuOpts *opts, Error **errp) -{ - const char *proc_name; - - if (qemu_opt_get(opts, "debug-threads")) { - qemu_thread_naming(qemu_opt_get_bool(opts, "debug-threads", false)); - } - qemu_name = qemu_opt_get(opts, "guest"); - - proc_name = qemu_opt_get(opts, "process"); - if (proc_name) { - os_set_proc_name(proc_name); - } - - return 0; -} - bool defaults_enabled(void) { - return has_defaults; -} - -#ifndef _WIN32 -static int parse_add_fd(void *opaque, QemuOpts *opts, Error **errp) -{ - int fd, dupfd, flags; - int64_t fdset_id; - const char *fd_opaque = NULL; - AddfdInfo *fdinfo; - - fd = qemu_opt_get_number(opts, "fd", -1); - fdset_id = qemu_opt_get_number(opts, "set", -1); - fd_opaque = qemu_opt_get(opts, "opaque"); - - if (fd < 0) { - error_setg(errp, "fd option is required and must be non-negative"); - return -1; - } - - if (fd <= STDERR_FILENO) { - error_setg(errp, "fd cannot be a standard I/O stream"); - return -1; - } - - /* - * All fds inherited across exec() necessarily have FD_CLOEXEC - * clear, while qemu sets FD_CLOEXEC on all other fds used internally. - */ - flags = fcntl(fd, F_GETFD); - if (flags == -1 || (flags & FD_CLOEXEC)) { - error_setg(errp, "fd is not valid or already in use"); - return -1; - } - - if (fdset_id < 0) { - error_setg(errp, "set option is required and must be non-negative"); - return -1; - } - -#ifdef F_DUPFD_CLOEXEC - dupfd = fcntl(fd, F_DUPFD_CLOEXEC, 0); -#else - dupfd = dup(fd); - if (dupfd != -1) { - qemu_set_cloexec(dupfd); - } -#endif - if (dupfd == -1) { - error_setg(errp, "error duplicating fd: %s", strerror(errno)); - return -1; - } - - /* add the duplicate fd, and optionally the opaque string, to the fd set */ - fdinfo = monitor_fdset_add_fd(dupfd, true, fdset_id, !!fd_opaque, fd_opaque, - &error_abort); - g_free(fdinfo); - - return 0; -} - -static int cleanup_add_fd(void *opaque, QemuOpts *opts, Error **errp) -{ - int fd; - - fd = qemu_opt_get_number(opts, "fd", -1); - close(fd); - - return 0; -} -#endif - -/***********************************************************/ -/* QEMU Block devices */ - -#define HD_OPTS "media=disk" -#define CDROM_OPTS "media=cdrom" -#define FD_OPTS "" -#define PFLASH_OPTS "" -#define MTD_OPTS "" -#define SD_OPTS "" - -static int drive_init_func(void *opaque, QemuOpts *opts, Error **errp) -{ - BlockInterfaceType *block_default_type = opaque; - - return drive_new(opts, *block_default_type, errp) == NULL; -} - -static int drive_enable_snapshot(void *opaque, QemuOpts *opts, Error **errp) -{ - if (qemu_opt_get(opts, "snapshot") == NULL) { - qemu_opt_set(opts, "snapshot", "on", &error_abort); - } - return 0; -} - -static void default_drive(int enable, int snapshot, BlockInterfaceType type, - int index, const char *optstr) -{ - QemuOpts *opts; - DriveInfo *dinfo; - - if (!enable || drive_get_by_index(type, index)) { - return; - } - - opts = drive_add(type, index, NULL, optstr); - if (snapshot) { - drive_enable_snapshot(NULL, opts, NULL); - } - - dinfo = drive_new(opts, type, &error_abort); - dinfo->is_default = true; - -} - -static void configure_blockdev(BlockdevOptionsQueue *bdo_queue, - MachineClass *machine_class, int snapshot) -{ - /* - * If the currently selected machine wishes to override the - * units-per-bus property of its default HBA interface type, do so - * now. - */ - if (machine_class->units_per_default_bus) { - override_max_devs(machine_class->block_default_type, - machine_class->units_per_default_bus); - } - - /* open the virtual block devices */ - while (!QSIMPLEQ_EMPTY(bdo_queue)) { - BlockdevOptionsQueueEntry *bdo = QSIMPLEQ_FIRST(bdo_queue); - - QSIMPLEQ_REMOVE_HEAD(bdo_queue, entry); - loc_push_restore(&bdo->loc); - qmp_blockdev_add(bdo->bdo, &error_fatal); - loc_pop(&bdo->loc); - qapi_free_BlockdevOptions(bdo->bdo); - g_free(bdo); - } - if (snapshot) { - qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot, - NULL, NULL); - } - if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func, - &machine_class->block_default_type, &error_fatal)) { - /* We printed help */ - exit(0); - } - - default_drive(default_cdrom, snapshot, machine_class->block_default_type, 2, - CDROM_OPTS); - default_drive(default_floppy, snapshot, IF_FLOPPY, 0, FD_OPTS); - default_drive(default_sdcard, snapshot, IF_SD, 0, SD_OPTS); - + return false; } static QemuOptsList qemu_smp_opts = { @@ -751,41 +471,6 @@ static void realtime_init(void) } -static void configure_msg(QemuOpts *opts) -{ - message_with_timestamp = qemu_opt_get_bool(opts, "timestamp", false); - error_with_guestname = qemu_opt_get_bool(opts, "guest-name", false); -} - - -/***********************************************************/ -/* USB devices */ - -static int usb_device_add(const char *devname) -{ - USBDevice *dev = NULL; - - if (!machine_usb(current_machine)) { - return -1; - } - - dev = usbdevice_create(devname); - if (!dev) - return -1; - - return 0; -} - -static int usb_parse(const char *cmdline) -{ - int r; - r = usb_device_add(cmdline); - if (r < 0) { - error_report("could not add USB device '%s'", cmdline); - } - return r; -} - /***********************************************************/ /* machine registration */ @@ -821,64 +506,6 @@ static MachineClass *find_default_machine(GSList *machines) return default_machineclass; } -static void version(void) -{ - printf("QEMU emulator version " QEMU_FULL_VERSION "\n" - QEMU_COPYRIGHT "\n"); -} - -static void help(int exitcode) -{ - version(); - printf("usage: %s [options] [disk_image]\n\n" - "'disk_image' is a raw hard disk image for IDE hard disk 0\n\n", - error_get_progname()); - -#define DEF(option, opt_arg, opt_enum, opt_help, arch_mask) \ - if ((arch_mask) & arch_type) \ - fputs(opt_help, stdout); - -#define ARCHHEADING(text, arch_mask) \ - if ((arch_mask) & arch_type) \ - puts(stringify(text)); - -#define DEFHEADING(text) ARCHHEADING(text, QEMU_ARCH_ALL) - -#include "qemu-options.def" - - printf("\nDuring emulation, the following keys are useful:\n" - "ctrl-alt-f toggle full screen\n" - "ctrl-alt-n switch to virtual console 'n'\n" - "ctrl-alt toggle mouse and keyboard grab\n" - "\n" - "When using -nographic, press 'ctrl-a h' to get some help.\n" - "\n" - QEMU_HELP_BOTTOM "\n"); - - exit(exitcode); -} - -#define HAS_ARG 0x0001 - -typedef struct QEMUOption { - const char *name; - int flags; - int index; - uint32_t arch_mask; -} QEMUOption; - -static const QEMUOption qemu_options[] = { - { "h", 0, QEMU_OPTION_h, QEMU_ARCH_ALL }, - -#define DEF(option, opt_arg, opt_enum, opt_help, arch_mask) \ - { option, opt_arg, opt_enum, arch_mask }, -#define DEFHEADING(text) -#define ARCHHEADING(text, arch_mask) - -#include "qemu-options.def" - { NULL }, -}; - typedef struct VGAInterfaceInfo { const char *opt_name; /* option name */ const char *name; /* human-readable name */ @@ -887,540 +514,13 @@ typedef struct VGAInterfaceInfo { const char *class_names[2]; } VGAInterfaceInfo; -static const VGAInterfaceInfo vga_interfaces[VGA_TYPE_MAX] = { - [VGA_NONE] = { - .opt_name = "none", - .name = "no graphic card", - }, - [VGA_STD] = { - .opt_name = "std", - .name = "standard VGA", - .class_names = { "VGA", "isa-vga" }, - }, - [VGA_CIRRUS] = { - .opt_name = "cirrus", - .name = "Cirrus VGA", - .class_names = { "cirrus-vga", "isa-cirrus-vga" }, - }, - [VGA_VMWARE] = { - .opt_name = "vmware", - .name = "VMWare SVGA", - .class_names = { "vmware-svga" }, - }, - [VGA_VIRTIO] = { - .opt_name = "virtio", - .name = "Virtio VGA", - .class_names = { "virtio-vga" }, - }, - [VGA_QXL] = { - .opt_name = "qxl", - .name = "QXL VGA", - .class_names = { "qxl-vga" }, - }, - [VGA_TCX] = { - .opt_name = "tcx", - .name = "TCX framebuffer", - .class_names = { "sun-tcx" }, - }, - [VGA_CG3] = { - .opt_name = "cg3", - .name = "CG3 framebuffer", - .class_names = { "cgthree" }, - }, - [VGA_XENFB] = { - .opt_name = "xenfb", - .name = "Xen paravirtualized framebuffer", - }, -}; - -static bool vga_interface_available(VGAInterfaceType t) -{ - const VGAInterfaceInfo *ti = &vga_interfaces[t]; - - assert(t < VGA_TYPE_MAX); - return !ti->class_names[0] || - module_object_class_by_name(ti->class_names[0]) || - module_object_class_by_name(ti->class_names[1]); -} - -static const char * -get_default_vga_model(const MachineClass *machine_class) -{ - if (machine_class->default_display) { - return machine_class->default_display; - } else if (vga_interface_available(VGA_CIRRUS)) { - return "cirrus"; - } else if (vga_interface_available(VGA_STD)) { - return "std"; - } - - return NULL; -} - -static void select_vgahw(const MachineClass *machine_class, const char *p) -{ - const char *opts; - int t; - - if (g_str_equal(p, "help")) { - const char *def = get_default_vga_model(machine_class); - - for (t = 0; t < VGA_TYPE_MAX; t++) { - const VGAInterfaceInfo *ti = &vga_interfaces[t]; - - if (vga_interface_available(t) && ti->opt_name) { - printf("%-20s %s%s\n", ti->opt_name, ti->name ?: "", - g_str_equal(ti->opt_name, def) ? " (default)" : ""); - } - } - exit(0); - } - - assert(vga_interface_type == VGA_NONE); - for (t = 0; t < VGA_TYPE_MAX; t++) { - const VGAInterfaceInfo *ti = &vga_interfaces[t]; - if (ti->opt_name && strstart(p, ti->opt_name, &opts)) { - if (!vga_interface_available(t)) { - error_report("%s not available", ti->name); - exit(1); - } - vga_interface_type = t; - break; - } - } - if (t == VGA_TYPE_MAX) { - invalid_vga: - error_report("unknown vga type: %s", p); - exit(1); - } - while (*opts) { - const char *nextopt; - - if (strstart(opts, ",retrace=", &nextopt)) { - opts = nextopt; - if (strstart(opts, "dumb", &nextopt)) - vga_retrace_method = VGA_RETRACE_DUMB; - else if (strstart(opts, "precise", &nextopt)) - vga_retrace_method = VGA_RETRACE_PRECISE; - else goto invalid_vga; - } else goto invalid_vga; - opts = nextopt; - } -} - -static void parse_display_qapi(const char *optarg) -{ - DisplayOptions *opts; - Visitor *v; - - v = qobject_input_visitor_new_str(optarg, "type", &error_fatal); - - visit_type_DisplayOptions(v, NULL, &opts, &error_fatal); - QAPI_CLONE_MEMBERS(DisplayOptions, &dpy, opts); - - qapi_free_DisplayOptions(opts); - 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; - - if (is_help_option(p)) { - qemu_display_help(); - exit(0); - } - - if (strstart(p, "sdl", &opts)) { - /* - * sdl DisplayType needs hand-crafted parser instead of - * parse_display_qapi() due to some options not in - * DisplayOptions, specifically: - * - ctrl_grab + alt_grab - * They can't be moved into the QAPI since they use underscores, - * thus they will get replaced by "grab-mod" in the long term - */ -#if defined(CONFIG_SDL) - dpy.type = DISPLAY_TYPE_SDL; - while (*opts) { - const char *nextopt; - - if (strstart(opts, ",grab-mod=", &nextopt)) { - opts = nextopt; - if (strstart(opts, "lshift-lctrl-lalt", &nextopt)) { - alt_grab = 1; - } else if (strstart(opts, "rctrl", &nextopt)) { - ctrl_grab = 1; - } else { - goto invalid_sdl_args; - } - } else if (strstart(opts, ",alt_grab=", &nextopt)) { - opts = nextopt; - if (strstart(opts, "on", &nextopt)) { - alt_grab = 1; - } else if (strstart(opts, "off", &nextopt)) { - alt_grab = 0; - } else { - goto invalid_sdl_args; - } - warn_report("alt_grab is deprecated, use grab-mod instead."); - } else if (strstart(opts, ",ctrl_grab=", &nextopt)) { - opts = nextopt; - if (strstart(opts, "on", &nextopt)) { - ctrl_grab = 1; - } else if (strstart(opts, "off", &nextopt)) { - ctrl_grab = 0; - } else { - goto invalid_sdl_args; - } - warn_report("ctrl_grab is deprecated, use grab-mod instead."); - } else if (strstart(opts, ",window_close=", &nextopt) || - strstart(opts, ",window-close=", &nextopt)) { - if (strstart(opts, ",window_close=", NULL)) { - warn_report("window_close with an underscore is deprecated," - " please use window-close instead."); - } - opts = nextopt; - dpy.has_window_close = true; - if (strstart(opts, "on", &nextopt)) { - dpy.window_close = true; - } else if (strstart(opts, "off", &nextopt)) { - dpy.window_close = false; - } else { - goto invalid_sdl_args; - } - } else if (strstart(opts, ",show-cursor=", &nextopt)) { - opts = nextopt; - dpy.has_show_cursor = true; - if (strstart(opts, "on", &nextopt)) { - dpy.show_cursor = true; - } else if (strstart(opts, "off", &nextopt)) { - dpy.show_cursor = false; - } else { - goto invalid_sdl_args; - } - } else if (strstart(opts, ",gl=", &nextopt)) { - opts = nextopt; - dpy.has_gl = true; - if (strstart(opts, "on", &nextopt)) { - dpy.gl = DISPLAYGL_MODE_ON; - } else if (strstart(opts, "core", &nextopt)) { - dpy.gl = DISPLAYGL_MODE_CORE; - } else if (strstart(opts, "es", &nextopt)) { - dpy.gl = DISPLAYGL_MODE_ES; - } else if (strstart(opts, "off", &nextopt)) { - dpy.gl = DISPLAYGL_MODE_OFF; - } else { - goto invalid_sdl_args; - } - } else { - invalid_sdl_args: - error_report("invalid SDL option string"); - exit(1); - } - opts = nextopt; - } -#else - error_report("SDL display supported is not available in this binary"); - exit(1); -#endif - } else if (strstart(p, "vnc", &opts)) { - /* - * vnc isn't a (local) DisplayType but a protocol for remote - * display access. - */ - if (*opts == '=') { - vnc_parse(opts + 1); - } else { - error_report("VNC requires a display argument vnc="); - exit(1); - } - } else { - parse_display_qapi(p); - } -} - -static inline bool nonempty_str(const char *str) -{ - return str && *str; -} - -static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp) -{ - gchar *buf; - size_t size; - const char *name, *file, *str, *gen_id; - FWCfgState *fw_cfg = (FWCfgState *) opaque; - - if (fw_cfg == NULL) { - error_setg(errp, "fw_cfg device not available"); - return -1; - } - name = qemu_opt_get(opts, "name"); - file = qemu_opt_get(opts, "file"); - str = qemu_opt_get(opts, "string"); - gen_id = qemu_opt_get(opts, "gen_id"); - - /* we need the name, and exactly one of: file, content string, gen_id */ - if (!nonempty_str(name) || - nonempty_str(file) + nonempty_str(str) + nonempty_str(gen_id) != 1) { - error_setg(errp, "name, plus exactly one of file," - " string and gen_id, are needed"); - return -1; - } - if (strlen(name) > FW_CFG_MAX_FILE_PATH - 1) { - error_setg(errp, "name too long (max. %d char)", - FW_CFG_MAX_FILE_PATH - 1); - return -1; - } - if (nonempty_str(gen_id)) { - /* - * In this particular case where the content is populated - * internally, the "etc/" namespace protection is relaxed, - * so do not emit a warning. - */ - } else if (strncmp(name, "opt/", 4) != 0) { - warn_report("externally provided fw_cfg item names " - "should be prefixed with \"opt/\""); - } - if (nonempty_str(str)) { - size = strlen(str); /* NUL terminator NOT included in fw_cfg blob */ - buf = g_memdup(str, size); - } else if (nonempty_str(gen_id)) { - if (!fw_cfg_add_from_generator(fw_cfg, name, gen_id, errp)) { - return -1; - } - return 0; - } else { - 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; - } - } - /* For legacy, keep user files in a specific global order. */ - fw_cfg_set_order_override(fw_cfg, FW_CFG_ORDER_OVERRIDE_USER); - fw_cfg_add_file(fw_cfg, name, buf, size); - fw_cfg_reset_order_override(fw_cfg); - return 0; -} - -static int device_help_func(void *opaque, QemuOpts *opts, Error **errp) -{ - return qdev_device_help(opts); -} - -static int device_init_func(void *opaque, QemuOpts *opts, Error **errp) -{ - DeviceState *dev; - - dev = qdev_device_add(opts, errp); - if (!dev && *errp) { - error_report_err(*errp); - return -1; - } else if (dev) { - object_unref(OBJECT(dev)); - } - return 0; -} - -static int chardev_init_func(void *opaque, QemuOpts *opts, Error **errp) -{ - Error *local_err = NULL; - - if (!qemu_chr_new_from_opts(opts, NULL, &local_err)) { - if (local_err) { - error_propagate(errp, local_err); - return -1; - } - exit(0); - } - return 0; -} - -#ifdef CONFIG_VIRTFS -static int fsdev_init_func(void *opaque, QemuOpts *opts, Error **errp) -{ - return qemu_fsdev_add(opts, errp); -} -#endif - -static int mon_init_func(void *opaque, QemuOpts *opts, Error **errp) -{ - return monitor_init_opts(opts, errp); -} - -static void monitor_parse(const char *optarg, const char *mode, bool pretty) -{ - static int monitor_device_index = 0; - QemuOpts *opts; - const char *p; - char label[32]; - - if (strstart(optarg, "chardev:", &p)) { - snprintf(label, sizeof(label), "%s", p); - } else { - snprintf(label, sizeof(label), "compat_monitor%d", - monitor_device_index); - opts = qemu_chr_parse_compat(label, optarg, true); - if (!opts) { - error_report("parse error: %s", optarg); - 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); - if (!strcmp(mode, "control")) { - qemu_opt_set_bool(opts, "pretty", pretty, &error_abort); - } else { - assert(pretty == false); - } - monitor_device_index++; -} - -struct device_config { - enum { - DEV_USB, /* -usbdevice */ - DEV_SERIAL, /* -serial */ - DEV_PARALLEL, /* -parallel */ - DEV_DEBUGCON, /* -debugcon */ - DEV_GDB, /* -gdb, -s */ - DEV_SCLP, /* s390 sclp */ - } type; - const char *cmdline; - Location loc; - QTAILQ_ENTRY(device_config) next; -}; - -static QTAILQ_HEAD(, device_config) device_configs = - QTAILQ_HEAD_INITIALIZER(device_configs); - -static void add_device_config(int type, const char *cmdline) -{ - struct device_config *conf; - - conf = g_malloc0(sizeof(*conf)); - conf->type = type; - conf->cmdline = cmdline; - loc_save(&conf->loc); - QTAILQ_INSERT_TAIL(&device_configs, conf, next); -} - -static int foreach_device_config(int type, int (*func)(const char *cmdline)) -{ - struct device_config *conf; - int rc; - - QTAILQ_FOREACH(conf, &device_configs, next) { - if (conf->type != type) - continue; - loc_push_restore(&conf->loc); - rc = func(conf->cmdline); - loc_pop(&conf->loc); - if (rc) { - return rc; - } - } - return 0; -} - -static void qemu_disable_default_devices(void) -{ - MachineClass *machine_class = MACHINE_GET_CLASS(current_machine); - - default_driver_check_json(); - qemu_opts_foreach(qemu_find_opts("device"), - default_driver_check, NULL, NULL); - qemu_opts_foreach(qemu_find_opts("global"), - default_driver_check, NULL, NULL); - - if (!vga_model && !default_vga) { - vga_interface_type = VGA_DEVICE; - } - if (!has_defaults || machine_class->no_serial) { - default_serial = 0; - } - if (!has_defaults || machine_class->no_parallel) { - default_parallel = 0; - } - if (!has_defaults || machine_class->no_floppy) { - default_floppy = 0; - } - if (!has_defaults || machine_class->no_cdrom) { - default_cdrom = 0; - } - if (!has_defaults || machine_class->no_sdcard) { - default_sdcard = 0; - } - if (!has_defaults) { - default_monitor = 0; - default_net = 0; - default_vga = 0; - } -} - static void qemu_create_default_devices(void) { - MachineClass *machine_class = MACHINE_GET_CLASS(current_machine); - - if (is_daemonized()) { - /* According to documentation and historically, -nographic redirects - * serial port, parallel port and monitor to stdio, which does not work - * with -daemonize. We can redirect these to null instead, but since - * -nographic is legacy, let's just error out. - * We disallow -nographic only if all other ports are not redirected - * explicitly, to not break existing legacy setups which uses - * -nographic _and_ redirects all ports explicitly - this is valid - * usage, -nographic is just a no-op in this case. - */ - if (nographic - && (default_parallel || default_serial || default_monitor)) { - error_report("-nographic cannot be used with -daemonize"); - exit(1); - } - } - - if (nographic) { - if (default_parallel) - add_device_config(DEV_PARALLEL, "null"); - if (default_serial && default_monitor) { - add_device_config(DEV_SERIAL, "mon:stdio"); - } else { - if (default_serial) - add_device_config(DEV_SERIAL, "stdio"); - if (default_monitor) - monitor_parse("stdio", "readline", false); - } - } else { - if (default_serial) - add_device_config(DEV_SERIAL, "vc:80Cx24C"); - if (default_parallel) - add_device_config(DEV_PARALLEL, "vc:80Cx24C"); - if (default_monitor) - monitor_parse("vc:80Cx24C", "readline", false); - } - - if (default_net) { - QemuOptsList *net = qemu_find_opts("net"); - qemu_opts_parse(net, "nic", true, &error_abort); -#ifdef CONFIG_SLIRP - qemu_opts_parse(net, "user", true, &error_abort); -#endif - } - -#if defined(CONFIG_VNC) - if (!QTAILQ_EMPTY(&(qemu_find_opts("vnc")->head))) { - display_remote++; - } -#endif if (dpy.type == DISPLAY_TYPE_DEFAULT && !display_remote) { if (!qemu_display_find_default(&dpy)) { dpy.type = DISPLAY_TYPE_NONE; @@ -1432,175 +532,13 @@ static void qemu_create_default_devices(void) if (dpy.type == DISPLAY_TYPE_DEFAULT) { dpy.type = DISPLAY_TYPE_NONE; } - - /* If no default VGA is requested, the default is "none". */ - if (default_vga) { - vga_model = get_default_vga_model(machine_class); - } - if (vga_model) { - select_vgahw(machine_class, vga_model); - } -} - -static int serial_parse(const char *devname) -{ - int index = num_serial_hds; - char label[32]; - - if (strcmp(devname, "none") == 0) - return 0; - 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, NULL); - if (!serial_hds[index]) { - error_report("could not connect serial device" - " to character backend '%s'", devname); - return -1; - } - num_serial_hds++; - return 0; } Chardev *serial_hd(int i) { - assert(i >= 0); - if (i < num_serial_hds) { - return serial_hds[i]; - } return NULL; } -static int parallel_parse(const char *devname) -{ - static int index = 0; - char label[32]; - - if (strcmp(devname, "none") == 0) - return 0; - if (index == MAX_PARALLEL_PORTS) { - error_report("too many parallel ports"); - exit(1); - } - snprintf(label, sizeof(label), "parallel%d", index); - 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); - return -1; - } - index++; - return 0; -} - -static int debugcon_parse(const char *devname) -{ - QemuOpts *opts; - - if (!qemu_chr_new_mux_mon("debugcon", devname, NULL)) { - error_report("invalid character backend '%s'", devname); - exit(1); - } - opts = qemu_opts_create(qemu_find_opts("device"), "debugcon", 1, NULL); - if (!opts) { - error_report("already have a debugcon device"); - exit(1); - } - qemu_opt_set(opts, "driver", "isa-debugcon", &error_abort); - qemu_opt_set(opts, "chardev", "debugcon", &error_abort); - return 0; -} - -static gint machine_class_cmp(gconstpointer a, gconstpointer b) -{ - const MachineClass *mc1 = a, *mc2 = b; - int res; - - if (mc1->family == NULL) { - if (mc2->family == NULL) { - /* Compare standalone machine types against each other; they sort - * in increasing order. - */ - return strcmp(object_class_get_name(OBJECT_CLASS(mc1)), - object_class_get_name(OBJECT_CLASS(mc2))); - } - - /* Standalone machine types sort after families. */ - return 1; - } - - if (mc2->family == NULL) { - /* Families sort before standalone machine types. */ - return -1; - } - - /* Families sort between each other alphabetically increasingly. */ - res = strcmp(mc1->family, mc2->family); - if (res != 0) { - return res; - } - - /* Within the same family, machine types sort in decreasing order. */ - return strcmp(object_class_get_name(OBJECT_CLASS(mc2)), - object_class_get_name(OBJECT_CLASS(mc1))); -} - -static void machine_help_func(const QDict *qdict) -{ - GSList *machines, *el; - const char *type = qdict_get_try_str(qdict, "type"); - - machines = object_class_get_list(TYPE_MACHINE, false); - if (type) { - ObjectClass *machine_class = OBJECT_CLASS(find_machine(type, machines)); - if (machine_class) { - type_print_class_properties(object_class_get_name(machine_class)); - return; - } - } - - printf("Supported machines are:\n"); - machines = g_slist_sort(machines, machine_class_cmp); - for (el = machines; el; el = el->next) { - MachineClass *mc = el->data; - if (mc->alias) { - printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, mc->name); - } - printf("%-20s %s%s%s\n", mc->name, mc->desc, - mc->is_default ? " (default)" : "", - mc->deprecation_reason ? " (deprecated)" : ""); - } -} - -static void -machine_merge_property(const char *propname, QDict *prop, Error **errp) -{ - QDict *opts; - - opts = qdict_new(); - /* Preserve the caller's reference to prop. */ - qobject_ref(prop); - qdict_put(opts, propname, prop); - keyval_merge(machine_opts_dict, opts, errp); - qobject_unref(opts); -} - -static void -machine_parse_property_opt(QemuOptsList *opts_list, const char *propname, - const char *arg) -{ - QDict *prop = NULL; - bool help = false; - - prop = keyval_parse(arg, opts_list->implied_opt_name, &help, &error_fatal); - if (help) { - qemu_opts_print_help(opts_list, true); - exit(0); - } - machine_merge_property(propname, prop, &error_fatal); - qobject_unref(prop); -} - static const char *pid_file; static Notifier qemu_unlink_pidfile_notifier; @@ -1611,56 +549,15 @@ static void qemu_unlink_pidfile(Notifier *n, void *data) } } -static const QEMUOption *lookup_opt(int argc, char **argv, - const char **poptarg, int *poptind) +static MachineClass *select_machine(Error **errp) { - const QEMUOption *popt; - int optind = *poptind; - char *r = argv[optind]; - const char *optarg; - - loc_set_cmdline(argv, optind, 1); - optind++; - /* Treat --foo the same as -foo. */ - if (r[1] == '-') - r++; - popt = qemu_options; - for(;;) { - if (!popt->name) { - error_report("invalid option"); - exit(1); - } - if (!strcmp(popt->name, r + 1)) - break; - popt++; - } - if (popt->flags & HAS_ARG) { - if (optind >= argc) { - error_report("requires an argument"); - exit(1); - } - optarg = argv[optind++]; - loc_set_cmdline(argv, optind - 2, 2); - } else { - optarg = NULL; - } - - *poptarg = optarg; - *poptind = optind; - - return popt; -} - -static MachineClass *select_machine(QDict *qdict, Error **errp) -{ - const char *optarg = qdict_get_try_str(qdict, "type"); + const char *optarg = NULL; GSList *machines = object_class_get_list(TYPE_MACHINE, false); MachineClass *machine_class; Error *local_err = NULL; if (optarg) { machine_class = find_machine(optarg, machines); - qdict_del(qdict, "type"); if (!machine_class) { error_setg(&local_err, "unsupported machine type"); } @@ -1679,227 +576,16 @@ static MachineClass *select_machine(QDict *qdict, Error **errp) return machine_class; } -static int object_parse_property_opt(Object *obj, - const char *name, const char *value, - const char *skip, Error **errp) -{ - if (g_str_equal(name, skip)) { - return 0; - } - - if (!object_property_parse(obj, name, value, errp)) { - return -1; - } - - return 0; -} - -/* *Non*recursively replace underscores with dashes in QDict keys. */ -static void keyval_dashify(QDict *qdict, Error **errp) -{ - const QDictEntry *ent, *next; - char *p; - - for (ent = qdict_first(qdict); ent; ent = next) { - g_autofree char *new_key = NULL; - - next = qdict_next(qdict, ent); - if (!strchr(ent->key, '_')) { - continue; - } - new_key = g_strdup(ent->key); - for (p = new_key; *p; p++) { - if (*p == '_') { - *p = '-'; - } - } - if (qdict_haskey(qdict, new_key)) { - error_setg(errp, "Conflict between '%s' and '%s'", ent->key, new_key); - return; - } - qobject_ref(ent->value); - qdict_put_obj(qdict, new_key, ent->value); - qdict_del(qdict, ent->key); - } -} - -static void qemu_apply_legacy_machine_options(QDict *qdict) -{ - const char *value; - - keyval_dashify(qdict, &error_fatal); - - /* Legacy options do not correspond to MachineState properties. */ - value = qdict_get_try_str(qdict, "accel"); - if (value) { - accelerators = g_strdup(value); - qdict_del(qdict, "accel"); - } - - value = qdict_get_try_str(qdict, "igd-passthru"); - if (value) { - object_register_sugar_prop(ACCEL_CLASS_NAME("xen"), "igd-passthru", value, - false); - qdict_del(qdict, "igd-passthru"); - } - - value = qdict_get_try_str(qdict, "kvm-shadow-mem"); - if (value) { - object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), "kvm-shadow-mem", value, - false); - qdict_del(qdict, "kvm-shadow-mem"); - } - - value = qdict_get_try_str(qdict, "kernel-irqchip"); - if (value) { - object_register_sugar_prop(ACCEL_CLASS_NAME("kvm"), "kernel-irqchip", value, - false); - object_register_sugar_prop(ACCEL_CLASS_NAME("whpx"), "kernel-irqchip", value, - false); - qdict_del(qdict, "kernel-irqchip"); - } -} - -static void object_option_foreach_add(bool (*type_opt_predicate)(const char *)) -{ - ObjectOption *opt, *next; - - QTAILQ_FOREACH_SAFE(opt, &object_opts, next, next) { - const char *type = ObjectType_str(opt->opts->qom_type); - if (type_opt_predicate(type)) { - user_creatable_add_qapi(opt->opts, &error_fatal); - qapi_free_ObjectOptions(opt->opts); - QTAILQ_REMOVE(&object_opts, opt, next); - g_free(opt); - } - } -} - -static void object_option_add_visitor(Visitor *v) -{ - ObjectOption *opt = g_new0(ObjectOption, 1); - visit_type_ObjectOptions(v, NULL, &opt->opts, &error_fatal); - QTAILQ_INSERT_TAIL(&object_opts, opt, next); -} - -static void object_option_parse(const char *optarg) -{ - QemuOpts *opts; - const char *type; - Visitor *v; - - if (optarg[0] == '{') { - QObject *obj = qobject_from_json(optarg, &error_fatal); - - v = qobject_input_visitor_new(obj); - qobject_unref(obj); - } else { - opts = qemu_opts_parse_noisily(qemu_find_opts("object"), - optarg, true); - if (!opts) { - exit(1); - } - - type = qemu_opt_get(opts, "qom-type"); - if (!type) { - error_setg(&error_fatal, QERR_MISSING_PARAMETER, "qom-type"); - } - if (user_creatable_print_help(type, opts)) { - exit(0); - } - - v = opts_visitor_new(opts); - } - - object_option_add_visitor(v); - visit_free(v); -} - -/* - * Initial object creation happens before all other - * QEMU data types are created. The majority of objects - * can be created at this point. The rng-egd object - * cannot be created here, as it depends on the chardev - * already existing. - */ -static bool object_create_early(const char *type) -{ - /* - * Objects should not be made "delayed" without a reason. If you - * add one, state the reason in a comment! - */ - - /* Reason: property "chardev" */ - if (g_str_equal(type, "rng-egd") || - g_str_equal(type, "qtest")) { - return false; - } - -#if defined(CONFIG_VHOST_USER) && defined(CONFIG_LINUX) - /* Reason: cryptodev-vhost-user property "chardev" */ - if (g_str_equal(type, "cryptodev-vhost-user")) { - return false; - } -#endif - - /* Reason: vhost-user-blk-server property "node-name" */ - if (g_str_equal(type, "vhost-user-blk-server")) { - return false; - } - /* - * Reason: filter-* property "netdev" etc. - */ - if (g_str_equal(type, "filter-buffer") || - g_str_equal(type, "filter-dump") || - 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-replay")) { - return false; - } - - /* - * Allocation of large amounts of memory may delay - * chardev initialization for too long, and trigger timeouts - * on software that waits for a monitor socket to be created - * (e.g. libvirt). - */ - if (g_str_has_prefix(type, "memory-backend-")) { - return false; - } - - return true; -} - static void qemu_apply_machine_options(QDict *qdict) { MachineClass *machine_class = MACHINE_GET_CLASS(current_machine); const char *boot_order = NULL; const char *boot_once = NULL; - QemuOpts *opts; - object_set_properties_from_keyval(OBJECT(current_machine), qdict, false, &error_fatal); current_machine->ram_size = ram_size; current_machine->maxram_size = maxram_size; current_machine->ram_slots = ram_slots; - opts = qemu_opts_find(qemu_find_opts("boot-opts"), NULL); - if (opts) { - boot_order = qemu_opt_get(opts, "order"); - if (boot_order) { - validate_bootdevices(boot_order, &error_fatal); - } - - boot_once = qemu_opt_get(opts, "once"); - if (boot_once) { - validate_bootdevices(boot_once, &error_fatal); - } - - boot_menu = qemu_opt_get_bool(opts, "menu", boot_menu); - boot_strict = qemu_opt_get_bool(opts, "strict", false); - } - if (!boot_order) { boot_order = machine_class->default_boot_order; } @@ -1907,11 +593,6 @@ static void qemu_apply_machine_options(QDict *qdict) current_machine->boot_order = boot_order; current_machine->boot_once = boot_once; - if (semihosting_enabled() && !semihosting_get_argc()) { - /* fall back to the -kernel/-append */ - semihosting_arg_fallback(current_machine->kernel_filename, current_machine->kernel_cmdline); - } - if (current_machine->smp.cpus > 1) { Error *blocker = NULL; error_setg(&blocker, QERR_REPLAY_NOT_SUPPORTED, "smp"); @@ -1921,27 +602,6 @@ static void qemu_apply_machine_options(QDict *qdict) static void qemu_create_early_backends(void) { - MachineClass *machine_class = MACHINE_GET_CLASS(current_machine); -#if defined(CONFIG_SDL) - const bool use_sdl = (dpy.type == DISPLAY_TYPE_SDL); -#else - const bool use_sdl = false; -#endif -#if defined(CONFIG_GTK) - const bool use_gtk = (dpy.type == DISPLAY_TYPE_GTK); -#else - const bool use_gtk = false; -#endif - - if ((alt_grab || ctrl_grab) && !use_sdl) { - error_report("-alt-grab and -ctrl-grab are only valid " - "for SDL, ignoring option"); - } - if (dpy.has_window_close && !use_gtk && !use_sdl) { - error_report("-no-quit is only valid for GTK and SDL, " - "ignoring option"); - } - qemu_display_early_init(&dpy); qemu_console_early_init(); @@ -1954,63 +614,21 @@ static void qemu_create_early_backends(void) exit(1); } - object_option_foreach_add(object_create_early); - /* spice needs the timers to be initialized by this point */ /* spice must initialize before audio as it changes the default auiodev */ /* spice must initialize before chardevs (for spicevmc and spiceport) */ qemu_spice.init(); - - qemu_opts_foreach(qemu_find_opts("chardev"), - chardev_init_func, NULL, &error_fatal); - -#ifdef CONFIG_VIRTFS - qemu_opts_foreach(qemu_find_opts("fsdev"), - fsdev_init_func, NULL, &error_fatal); -#endif - - /* - * Note: we need to create audio and block backends before - * setting machine properties, so they can be referred to. - */ - configure_blockdev(&bdo_queue, machine_class, snapshot); - audio_init_audiodevs(); } -/* - * The remainder of object creation happens after the - * creation of chardev, fsdev, net clients and device data types. - */ -static bool object_create_late(const char *type) -{ - return !object_create_early(type); -} - static void qemu_create_late_backends(void) { - if (qtest_chrdev) { - qtest_server_init(qtest_chrdev, qtest_log, &error_fatal); - } - net_init_clients(&error_fatal); - object_option_foreach_add(object_create_late); - if (tpm_init() < 0) { 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_DEBUGCON, debugcon_parse) < 0) - exit(1); - /* now chardevs have been created we may have semihosting to connect */ qemu_semihosting_connect_chardevs(); qemu_semihosting_console_init(); @@ -2018,8 +636,7 @@ static void qemu_create_late_backends(void) static bool have_custom_ram_size(void) { - QemuOpts *opts = qemu_find_opts_singleton("memory"); - return !!qemu_opt_get_size(opts, "size", 0); + return false; } static void qemu_resolve_machine_memdev(void) @@ -2041,11 +658,6 @@ static void qemu_resolve_machine_memdev(void) "explicitly specified 'memory-backend' property"); exit(EXIT_FAILURE); } - if (mem_path) { - error_report("'-mem-path' can't be used together with" - "'-machine memory-backend'"); - exit(EXIT_FAILURE); - } ram_size = backend_size; } @@ -2061,35 +673,9 @@ static void qemu_resolve_machine_memdev(void) static void set_memory_options(MachineClass *mc) { uint64_t sz; - const char *mem_str; const ram_addr_t default_ram_size = mc->default_ram_size; - QemuOpts *opts = qemu_find_opts_singleton("memory"); - Location loc; - - loc_push_none(&loc); - qemu_opts_loc_restore(opts); sz = 0; - mem_str = qemu_opt_get(opts, "size"); - if (mem_str) { - if (!*mem_str) { - error_report("missing 'size' option value"); - exit(EXIT_FAILURE); - } - - sz = qemu_opt_get_size(opts, "size", ram_size); - - /* Fix up legacy suffix-less format */ - if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) { - uint64_t overflow_check = sz; - - sz *= MiB; - if (sz / MiB != overflow_check) { - error_report("too large 'size' option value"); - exit(EXIT_FAILURE); - } - } - } /* backward compatibility behaviour for case "-m 0" */ if (sz == 0) { @@ -2107,39 +693,11 @@ static void set_memory_options(MachineClass *mc) } maxram_size = ram_size; - - if (qemu_opt_get(opts, "maxmem")) { - uint64_t slots; - - sz = qemu_opt_get_size(opts, "maxmem", 0); - slots = qemu_opt_get_number(opts, "slots", 0); - if (sz < ram_size) { - error_report("invalid value of -m option maxmem: " - "maximum memory size (0x%" PRIx64 ") must be at least " - "the initial memory size (0x" RAM_ADDR_FMT ")", - sz, ram_size); - exit(EXIT_FAILURE); - } else if (slots && sz == ram_size) { - error_report("invalid value of -m option maxmem: " - "memory slots were specified but maximum memory size " - "(0x%" PRIx64 ") is equal to the initial memory size " - "(0x" RAM_ADDR_FMT ")", sz, ram_size); - exit(EXIT_FAILURE); - } - - maxram_size = sz; - ram_slots = slots; - } else if (qemu_opt_get(opts, "slots")) { - error_report("invalid -m option value: missing 'maxmem' option"); - exit(EXIT_FAILURE); - } - - loc_pop(&loc); } -static void qemu_create_machine(QDict *qdict) +static void qemu_create_machine(void) { - MachineClass *machine_class = select_machine(qdict, &error_fatal); + MachineClass *machine_class = select_machine(&error_fatal); object_set_machine_compat_props(machine_class->compat_props); set_memory_options(machine_class); @@ -2175,152 +733,12 @@ static void qemu_create_machine(QDict *qdict) QDict *default_opts = keyval_parse(machine_class->default_machine_opts, NULL, NULL, &error_abort); - qemu_apply_legacy_machine_options(default_opts); object_set_properties_from_keyval(OBJECT(current_machine), default_opts, false, &error_abort); qobject_unref(default_opts); } } -static int global_init_func(void *opaque, QemuOpts *opts, Error **errp) -{ - GlobalProperty *g; - - g = g_malloc0(sizeof(*g)); - g->driver = qemu_opt_get(opts, "driver"); - g->property = qemu_opt_get(opts, "property"); - g->value = qemu_opt_get(opts, "value"); - qdev_prop_register_global(g); - return 0; -} - -/* - * Return whether configuration group @group is stored in QemuOpts, or - * recorded as one or more QDicts by qemu_record_config_group. - */ -static bool is_qemuopts_group(const char *group) -{ - if (g_str_equal(group, "object") || - g_str_equal(group, "machine") || - g_str_equal(group, "smp-opts")) { - return false; - } - return true; -} - -static void qemu_record_config_group(const char *group, QDict *dict, - bool from_json, Error **errp) -{ - if (g_str_equal(group, "object")) { - Visitor *v = qobject_input_visitor_new_keyval(QOBJECT(dict)); - object_option_add_visitor(v); - visit_free(v); - } else if (g_str_equal(group, "machine")) { - /* - * Cannot merge string-valued and type-safe dictionaries, so JSON - * is not accepted yet for -M. - */ - assert(!from_json); - keyval_merge(machine_opts_dict, dict, errp); - } else if (g_str_equal(group, "smp-opts")) { - machine_merge_property("smp", dict, &error_fatal); - } else { - abort(); - } -} - -/* - * Parse non-QemuOpts config file groups, pass the rest to - * qemu_config_do_parse. - */ -static void qemu_parse_config_group(const char *group, QDict *qdict, - void *opaque, Error **errp) -{ - QObject *crumpled; - if (is_qemuopts_group(group)) { - qemu_config_do_parse(group, qdict, opaque, errp); - return; - } - - crumpled = qdict_crumple(qdict, errp); - if (!crumpled) { - return; - } - switch (qobject_type(crumpled)) { - case QTYPE_QDICT: - qemu_record_config_group(group, qobject_to(QDict, crumpled), false, errp); - break; - case QTYPE_QLIST: - error_setg(errp, "Lists cannot be at top level of a configuration section"); - break; - default: - g_assert_not_reached(); - } - qobject_unref(crumpled); -} - -static void qemu_read_default_config_file(Error **errp) -{ - ERRP_GUARD(); - int ret; - g_autofree char *file = get_relocated_path(CONFIG_QEMU_CONFDIR "/qemu.conf"); - - ret = qemu_read_config_file(file, qemu_parse_config_group, errp); - if (ret < 0) { - if (ret == -ENOENT) { - error_free(*errp); - *errp = NULL; - } - } -} - -static void qemu_set_option(const char *str, Error **errp) -{ - char group[64], id[64], arg[64]; - QemuOptsList *list; - QemuOpts *opts; - int rc, offset; - - rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset); - if (rc < 3 || str[offset] != '=') { - error_setg(errp, "can't parse: \"%s\"", str); - return; - } - - if (!is_qemuopts_group(group)) { - error_setg(errp, "-set is not supported with %s", group); - } else { - list = qemu_find_opts_err(group, errp); - if (list) { - opts = qemu_opts_find(list, id); - if (!opts) { - error_setg(errp, "there is no %s \"%s\" defined", group, id); - return; - } - qemu_opt_set(opts, arg, str + offset + 1, errp); - } - } -} - -static void user_register_global_props(void) -{ - qemu_opts_foreach(qemu_find_opts("global"), - global_init_func, NULL, NULL); -} - -static int do_configure_icount(void *opaque, QemuOpts *opts, Error **errp) -{ - icount_configure(opts, errp); - return 0; -} - -static int accelerator_set_property(void *opaque, - const char *name, const char *value, - Error **errp) -{ - return object_parse_property_opt(opaque, name, value, "accel", errp); -} - static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp) { bool *p_init_failed = opaque; @@ -2330,7 +748,7 @@ static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp) int ret; bool qtest_with_kvm; - qtest_with_kvm = g_str_equal(acc, "kvm") && qtest_chrdev != NULL; + qtest_with_kvm = false; if (!ac) { *p_init_failed = true; @@ -2341,9 +759,6 @@ static int do_configure_accelerator(void *opaque, QemuOpts *opts, Error **errp) } accel = ACCEL(object_new_with_class(OBJECT_CLASS(ac))); object_apply_compat_props(OBJECT(accel)); - qemu_opt_foreach(opts, accelerator_set_property, - accel, - &error_fatal); ret = accel_init_machine(accel, current_machine); if (ret < 0) { @@ -2361,9 +776,6 @@ static void configure_accelerators(const char *progname) { bool init_failed = false; - qemu_opts_foreach(qemu_find_opts("icount"), - do_configure_icount, NULL, &error_fatal); - if (QTAILQ_EMPTY(&qemu_accel_opts.head)) { char **accel_list, **tmp; @@ -2419,7 +831,7 @@ static void configure_accelerators(const char *progname) exit(1); } - if (init_failed && !qtest_chrdev) { + if (init_failed) { AccelClass *ac = ACCEL_GET_CLASS(current_accel()); error_report("falling back to %s", ac->name); } @@ -2451,153 +863,13 @@ static void create_default_memdev(MachineState *ms, const char *path) &error_fatal); } -static void qemu_validate_options(const QDict *machine_opts) -{ - const char *kernel_filename = qdict_get_try_str(machine_opts, "kernel"); - const char *initrd_filename = qdict_get_try_str(machine_opts, "initrd"); - const char *kernel_cmdline = qdict_get_try_str(machine_opts, "append"); - - if (kernel_filename == NULL) { - if (kernel_cmdline != NULL) { - error_report("-append only allowed with -kernel option"); - exit(1); - } - - if (initrd_filename != NULL) { - error_report("-initrd only allowed with -kernel option"); - exit(1); - } - } - - if (loadvm && preconfig_requested) { - error_report("'preconfig' and 'loadvm' options are " - "mutually exclusive"); - exit(EXIT_FAILURE); - } - if (incoming && preconfig_requested && strcmp(incoming, "defer") != 0) { - error_report("'preconfig' supports '-incoming defer' only"); - exit(EXIT_FAILURE); - } - -#ifdef CONFIG_CURSES - if (is_daemonized() && dpy.type == DISPLAY_TYPE_CURSES) { - error_report("curses display cannot be used with -daemonize"); - exit(1); - } -#endif -} - -static void qemu_process_sugar_options(void) -{ - if (mem_prealloc) { - QObject *smp = qdict_get(machine_opts_dict, "smp"); - if (smp && qobject_type(smp) == QTYPE_QDICT) { - QObject *cpus = qdict_get(qobject_to(QDict, smp), "cpus"); - if (cpus && qobject_type(cpus) == QTYPE_QSTRING) { - const char *val = qstring_get_str(qobject_to(QString, cpus)); - object_register_sugar_prop("memory-backend", "prealloc-threads", - val, false); - } - } - object_register_sugar_prop("memory-backend", "prealloc", "on", false); - } - - if (watchdog) { - int i = select_watchdog(watchdog); - if (i > 0) - exit (i == 1 ? 1 : 0); - } -} - -/* -action processing */ - -/* - * Process all the -action parameters parsed from cmdline. - */ -static int process_runstate_actions(void *opaque, QemuOpts *opts, Error **errp) -{ - Error *local_err = NULL; - QDict *qdict = qemu_opts_to_qdict(opts, NULL); - QObject *ret = NULL; - qmp_marshal_set_action(qdict, &ret, &local_err); - qobject_unref(ret); - qobject_unref(qdict); - if (local_err) { - error_propagate(errp, local_err); - return 1; - } - return 0; -} - static void qemu_process_early_options(void) { -#ifdef CONFIG_SECCOMP - QemuOptsList *olist = qemu_find_opts_err("sandbox", NULL); - if (olist) { - qemu_opts_foreach(olist, parse_sandbox, NULL, &error_fatal); - } -#endif - - qemu_opts_foreach(qemu_find_opts("name"), - parse_name, NULL, &error_fatal); - - if (qemu_opts_foreach(qemu_find_opts("action"), - process_runstate_actions, NULL, &error_fatal)) { - exit(1); - } - -#ifndef _WIN32 - qemu_opts_foreach(qemu_find_opts("add-fd"), - parse_add_fd, NULL, &error_fatal); - - qemu_opts_foreach(qemu_find_opts("add-fd"), - cleanup_add_fd, NULL, &error_fatal); -#endif - - /* Open the logfile at this point and set the log mask if necessary. */ - if (log_file) { - qemu_set_log_filename(log_file, &error_fatal); - } - if (log_mask) { - int mask; - mask = qemu_str_to_log_mask(log_mask); - if (!mask) { - qemu_print_log_usage(stdout); - exit(1); - } - qemu_set_log(mask); - } else { - qemu_set_log(0); - } + qemu_set_log(0); qemu_add_default_firmwarepath(); } -static void qemu_process_help_options(void) -{ - /* - * Check for -cpu help and -device help before we call select_machine(), - * which will return an error if the architecture has no default machine - * type and the user did not specify one, so that the user doesn't need - * to say '-cpu help -machine something'. - */ - if (cpu_option && is_help_option(cpu_option)) { - list_cpus(cpu_option); - exit(0); - } - - if (qemu_opts_foreach(qemu_find_opts("device"), - device_help_func, NULL, NULL)) { - exit(0); - } - - /* -L help lists the data directories and exits. */ - if (list_data_dirs) { - qemu_list_data_dirs(); - exit(0); - } -} - static void qemu_maybe_daemonize(const char *pid_file) { Error *err = NULL; @@ -2625,12 +897,6 @@ static void qemu_init_displays(void) /* must be after terminal init, SDL library changes signal handlers */ os_setup_signal_handling(); - /* init remote displays */ -#ifdef CONFIG_VNC - qemu_opts_foreach(qemu_find_opts("vnc"), - vnc_init_func, NULL, &error_fatal); -#endif - if (using_spice) { qemu_spice.display_init(); } @@ -2642,12 +908,9 @@ static void qemu_init_board(void) if (machine_class->default_ram_id && current_machine->ram_size && numa_uses_legacy_mem() && !current_machine->ram_memdev_id) { - create_default_memdev(current_machine, mem_path); + create_default_memdev(current_machine, NULL); } - /* process plugin before CPUs are created, but once -smp has been parsed */ - qemu_plugin_load_list(&plugin_list, &error_fatal); - /* From here on we enter MACHINE_PHASE_INITIALIZED. */ machine_run_board_init(current_machine); @@ -2661,40 +924,6 @@ static void qemu_init_board(void) } } -static void qemu_create_cli_devices(void) -{ - DeviceOption *opt; - - soundhw_init(); - - qemu_opts_foreach(qemu_find_opts("fw_cfg"), - parse_fw_cfg, fw_cfg_find(), &error_fatal); - - /* init USB devices */ - if (machine_usb(current_machine)) { - if (foreach_device_config(DEV_USB, usb_parse) < 0) - exit(1); - } - - /* init generic devices */ - rom_set_order_override(FW_CFG_ORDER_OVERRIDE_DEVICE); - qemu_opts_foreach(qemu_find_opts("device"), - device_init_func, NULL, &error_fatal); - QTAILQ_FOREACH(opt, &device_opts, next) { - loc_push_restore(&opt->loc); - /* - * TODO Eventually we should call qmp_device_add() here to make sure it - * behaves the same, but QMP still has to accept incorrectly typed - * options until libvirt is fixed and we want to be strict on the CLI - * from the start, so call qdev_device_add_from_qdict() directly for - * now. - */ - qdev_device_add_from_qdict(opt->opts, true, &error_fatal); - loc_pop(&opt->loc); - } - rom_reset_order_override(); -} - static void qemu_machine_creation_done(void) { MachineState *machine = MACHINE(qdev_get_machine()); @@ -2702,17 +931,7 @@ static void qemu_machine_creation_done(void) /* Did we create any drives that we failed to create a device for? */ drive_check_orphaned(); - /* 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 && (!qtest_enabled() || has_defaults)) { - net_check_clients(); - } + net_check_clients(); qdev_prop_check_globals(); @@ -2724,10 +943,6 @@ static void qemu_machine_creation_done(void) */ assert(machine->cgs->ready); } - - if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) { - exit(1); - } } void qmp_x_exit_preconfig(Error **errp) @@ -2738,12 +953,8 @@ void qmp_x_exit_preconfig(Error **errp) } qemu_init_board(); - qemu_create_cli_devices(); qemu_machine_creation_done(); - if (loadvm) { - load_snapshot(loadvm, NULL, false, NULL, &error_fatal); - } if (replay_mode != REPLAY_MODE_NONE) { replay_vmstate_init(); } @@ -2764,13 +975,7 @@ void qmp_x_exit_preconfig(Error **errp) void qemu_init(int argc, char **argv, char **envp) { - QemuOpts *opts; - QemuOpts *icount_opts = NULL, *accel_opts = NULL; - QemuOptsList *olist; - int optind; - const char *optarg; MachineClass *machine_class; - bool userconfig = true; FILE *vmstate_dump_file = NULL; qemu_add_opts(&qemu_drive_opts); @@ -2816,871 +1021,8 @@ void qemu_init(int argc, char **argv, char **envp) qemu_init_subsystems(); - /* first pass of option parsing */ - optind = 1; - while (optind < argc) { - if (argv[optind][0] != '-') { - /* disk image */ - optind++; - } else { - const QEMUOption *popt; - - popt = lookup_opt(argc, argv, &optarg, &optind); - switch (popt->index) { - case QEMU_OPTION_nouserconfig: - userconfig = false; - break; - } - } - } - - machine_opts_dict = qdict_new(); - if (userconfig) { - qemu_read_default_config_file(&error_fatal); - } - - /* second pass of option parsing */ - optind = 1; - for(;;) { - if (optind >= argc) - break; - if (argv[optind][0] != '-') { - loc_set_cmdline(argv, optind, 1); - drive_add(IF_DEFAULT, 0, argv[optind++], HD_OPTS); - } else { - const QEMUOption *popt; - - popt = lookup_opt(argc, argv, &optarg, &optind); - if (!(popt->arch_mask & arch_type)) { - error_report("Option not supported for this target"); - exit(1); - } - switch(popt->index) { - case QEMU_OPTION_cpu: - /* hw initialization will check this */ - cpu_option = optarg; - break; - case QEMU_OPTION_hda: - case QEMU_OPTION_hdb: - case QEMU_OPTION_hdc: - case QEMU_OPTION_hdd: - drive_add(IF_DEFAULT, popt->index - QEMU_OPTION_hda, optarg, - HD_OPTS); - break; - case QEMU_OPTION_blockdev: - { - Visitor *v; - BlockdevOptionsQueueEntry *bdo; - - v = qobject_input_visitor_new_str(optarg, "driver", - &error_fatal); - - bdo = g_new(BlockdevOptionsQueueEntry, 1); - visit_type_BlockdevOptions(v, NULL, &bdo->bdo, - &error_fatal); - visit_free(v); - loc_save(&bdo->loc); - QSIMPLEQ_INSERT_TAIL(&bdo_queue, bdo, entry); - break; - } - case QEMU_OPTION_drive: - if (drive_def(optarg) == NULL) { - exit(1); - } - break; - case QEMU_OPTION_set: - qemu_set_option(optarg, &error_fatal); - break; - case QEMU_OPTION_global: - if (qemu_global_option(optarg) != 0) - exit(1); - break; - case QEMU_OPTION_mtdblock: - drive_add(IF_MTD, -1, optarg, MTD_OPTS); - break; - case QEMU_OPTION_sd: - drive_add(IF_SD, -1, optarg, SD_OPTS); - break; - case QEMU_OPTION_pflash: - drive_add(IF_PFLASH, -1, optarg, PFLASH_OPTS); - break; - case QEMU_OPTION_snapshot: - { - 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"), - optarg, true); - if (!opts) { - exit(1); - } - break; - case QEMU_OPTION_display: - parse_display(optarg); - break; - case QEMU_OPTION_nographic: - qdict_put_str(machine_opts_dict, "graphics", "off"); - nographic = true; - dpy.type = DISPLAY_TYPE_NONE; - break; - case QEMU_OPTION_curses: - warn_report("-curses is deprecated, " - "use -display curses instead."); -#ifdef CONFIG_CURSES - dpy.type = DISPLAY_TYPE_CURSES; -#else - error_report("curses or iconv support is disabled"); - exit(1); -#endif - break; - case QEMU_OPTION_portrait: - graphic_rotate = 90; - break; - case QEMU_OPTION_rotate: - graphic_rotate = strtol(optarg, (char **) &optarg, 10); - if (graphic_rotate != 0 && graphic_rotate != 90 && - graphic_rotate != 180 && graphic_rotate != 270) { - error_report("only 90, 180, 270 deg rotation is available"); - exit(1); - } - break; - case QEMU_OPTION_kernel: - qdict_put_str(machine_opts_dict, "kernel", optarg); - break; - case QEMU_OPTION_initrd: - qdict_put_str(machine_opts_dict, "initrd", optarg); - break; - case QEMU_OPTION_append: - qdict_put_str(machine_opts_dict, "append", optarg); - break; - case QEMU_OPTION_dtb: - qdict_put_str(machine_opts_dict, "dtb", optarg); - break; - case QEMU_OPTION_cdrom: - drive_add(IF_DEFAULT, 2, optarg, CDROM_OPTS); - break; - case QEMU_OPTION_boot: - opts = qemu_opts_parse_noisily(qemu_find_opts("boot-opts"), - optarg, true); - if (!opts) { - exit(1); - } - break; - case QEMU_OPTION_fda: - case QEMU_OPTION_fdb: - drive_add(IF_FLOPPY, popt->index - QEMU_OPTION_fda, - optarg, FD_OPTS); - break; - case QEMU_OPTION_no_fd_bootchk: - 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_nic: - default_net = 0; - if (net_client_parse(qemu_find_opts("nic"), optarg) == -1) { - exit(1); - } - break; - case QEMU_OPTION_net: - default_net = 0; - if (net_client_parse(qemu_find_opts("net"), optarg) == -1) { - exit(1); - } - break; -#ifdef CONFIG_LIBISCSI - case QEMU_OPTION_iscsi: - opts = qemu_opts_parse_noisily(qemu_find_opts("iscsi"), - optarg, false); - if (!opts) { - exit(1); - } - break; -#endif - case QEMU_OPTION_audio_help: - audio_legacy_help(); - exit (0); - break; - case QEMU_OPTION_audiodev: - audio_parse_option(optarg); - break; - case QEMU_OPTION_soundhw: - select_soundhw (optarg); - break; - case QEMU_OPTION_h: - help(0); - break; - case QEMU_OPTION_version: - version(); - exit(0); - break; - case QEMU_OPTION_m: - opts = qemu_opts_parse_noisily(qemu_find_opts("memory"), - optarg, true); - if (!opts) { - exit(EXIT_FAILURE); - } - break; -#ifdef CONFIG_TPM - case QEMU_OPTION_tpmdev: - if (tpm_config_parse(qemu_find_opts("tpmdev"), optarg) < 0) { - exit(1); - } - break; -#endif - case QEMU_OPTION_mempath: - mem_path = optarg; - break; - case QEMU_OPTION_mem_prealloc: - mem_prealloc = 1; - break; - case QEMU_OPTION_d: - log_mask = optarg; - break; - case QEMU_OPTION_D: - log_file = optarg; - break; - case QEMU_OPTION_DFILTER: - qemu_set_dfilter_ranges(optarg, &error_fatal); - break; - case QEMU_OPTION_seed: - qemu_guest_random_seed_main(optarg, &error_fatal); - break; - case QEMU_OPTION_s: - add_device_config(DEV_GDB, "tcp::" DEFAULT_GDBSTUB_PORT); - break; - case QEMU_OPTION_gdb: - add_device_config(DEV_GDB, optarg); - break; - case QEMU_OPTION_L: - if (is_help_option(optarg)) { - list_data_dirs = true; - } else { - qemu_add_data_dir(g_strdup(optarg)); - } - break; - case QEMU_OPTION_bios: - qdict_put_str(machine_opts_dict, "firmware", optarg); - break; - case QEMU_OPTION_singlestep: - singlestep = 1; - break; - case QEMU_OPTION_S: - autostart = 0; - break; - case QEMU_OPTION_k: - keyboard_layout = optarg; - break; - case QEMU_OPTION_vga: - vga_model = optarg; - default_vga = 0; - break; - case QEMU_OPTION_g: - { - const char *p; - int w, h, depth; - p = optarg; - w = strtol(p, (char **)&p, 10); - if (w <= 0) { - graphic_error: - error_report("invalid resolution or depth"); - exit(1); - } - if (*p != 'x') - goto graphic_error; - p++; - h = strtol(p, (char **)&p, 10); - if (h <= 0) - goto graphic_error; - if (*p == 'x') { - p++; - depth = strtol(p, (char **)&p, 10); - if (depth != 1 && depth != 2 && depth != 4 && - depth != 8 && depth != 15 && depth != 16 && - depth != 24 && depth != 32) - goto graphic_error; - } else if (*p == '\0') { - depth = graphic_depth; - } else { - goto graphic_error; - } - - graphic_width = w; - graphic_height = h; - graphic_depth = depth; - } - break; - case QEMU_OPTION_echr: - { - char *r; - term_escape_char = strtol(optarg, &r, 0); - if (r == optarg) - printf("Bad argument to echr\n"); - break; - } - case QEMU_OPTION_monitor: - default_monitor = 0; - if (strncmp(optarg, "none", 4)) { - monitor_parse(optarg, "readline", false); - } - break; - case QEMU_OPTION_qmp: - monitor_parse(optarg, "control", false); - default_monitor = 0; - break; - case QEMU_OPTION_qmp_pretty: - monitor_parse(optarg, "control", true); - default_monitor = 0; - break; - case QEMU_OPTION_mon: - opts = qemu_opts_parse_noisily(qemu_find_opts("mon"), optarg, - true); - if (!opts) { - exit(1); - } - default_monitor = 0; - break; - case QEMU_OPTION_chardev: - opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), - optarg, true); - if (!opts) { - exit(1); - } - break; - case QEMU_OPTION_fsdev: - olist = qemu_find_opts("fsdev"); - if (!olist) { - error_report("fsdev support is disabled"); - exit(1); - } - opts = qemu_opts_parse_noisily(olist, optarg, true); - if (!opts) { - exit(1); - } - break; - case QEMU_OPTION_virtfs: { - QemuOpts *fsdev; - QemuOpts *device; - const char *writeout, *sock_fd, *socket, *path, *security_model, - *multidevs; - - olist = qemu_find_opts("virtfs"); - if (!olist) { - error_report("virtfs support is disabled"); - exit(1); - } - opts = qemu_opts_parse_noisily(olist, optarg, true); - if (!opts) { - exit(1); - } - - if (qemu_opt_get(opts, "fsdriver") == NULL || - qemu_opt_get(opts, "mount_tag") == NULL) { - error_report("Usage: -virtfs fsdriver,mount_tag=tag"); - exit(1); - } - fsdev = qemu_opts_create(qemu_find_opts("fsdev"), - qemu_opts_id(opts) ?: - qemu_opt_get(opts, "mount_tag"), - 1, NULL); - if (!fsdev) { - error_report("duplicate or invalid fsdev id: %s", - qemu_opt_get(opts, "mount_tag")); - exit(1); - } - - writeout = qemu_opt_get(opts, "writeout"); - if (writeout) { -#ifdef CONFIG_SYNC_FILE_RANGE - qemu_opt_set(fsdev, "writeout", writeout, &error_abort); -#else - error_report("writeout=immediate not supported " - "on this platform"); - exit(1); -#endif - } - qemu_opt_set(fsdev, "fsdriver", - qemu_opt_get(opts, "fsdriver"), &error_abort); - path = qemu_opt_get(opts, "path"); - if (path) { - qemu_opt_set(fsdev, "path", path, &error_abort); - } - security_model = qemu_opt_get(opts, "security_model"); - if (security_model) { - qemu_opt_set(fsdev, "security_model", security_model, - &error_abort); - } - socket = qemu_opt_get(opts, "socket"); - if (socket) { - qemu_opt_set(fsdev, "socket", socket, &error_abort); - } - sock_fd = qemu_opt_get(opts, "sock_fd"); - if (sock_fd) { - qemu_opt_set(fsdev, "sock_fd", sock_fd, &error_abort); - } - - 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); - qemu_opt_set(device, "fsdev", - qemu_opts_id(fsdev), &error_abort); - qemu_opt_set(device, "mount_tag", - qemu_opt_get(opts, "mount_tag"), &error_abort); - break; - } - case QEMU_OPTION_serial: - add_device_config(DEV_SERIAL, optarg); - default_serial = 0; - if (strncmp(optarg, "mon:", 4) == 0) { - default_monitor = 0; - } - break; - case QEMU_OPTION_watchdog: - if (watchdog) { - error_report("only one watchdog option may be given"); - exit(1); - } - warn_report("-watchdog is deprecated; use -device instead."); - watchdog = optarg; - break; - case QEMU_OPTION_action: - olist = qemu_find_opts("action"); - if (!qemu_opts_parse_noisily(olist, optarg, false)) { - exit(1); - } - break; - case QEMU_OPTION_watchdog_action: { - QemuOpts *opts; - opts = qemu_opts_create(qemu_find_opts("action"), NULL, 0, &error_abort); - qemu_opt_set(opts, "watchdog", optarg, &error_abort); - break; - } - case QEMU_OPTION_parallel: - add_device_config(DEV_PARALLEL, optarg); - default_parallel = 0; - if (strncmp(optarg, "mon:", 4) == 0) { - default_monitor = 0; - } - break; - case QEMU_OPTION_debugcon: - add_device_config(DEV_DEBUGCON, optarg); - break; - case QEMU_OPTION_loadvm: - loadvm = optarg; - break; - case QEMU_OPTION_full_screen: - dpy.has_full_screen = true; - dpy.full_screen = true; - break; - case QEMU_OPTION_alt_grab: - alt_grab = 1; - warn_report("-alt-grab is deprecated, please use " - "-display sdl,grab-mod=lshift-lctrl-lalt instead."); - break; - case QEMU_OPTION_ctrl_grab: - ctrl_grab = 1; - warn_report("-ctrl-grab is deprecated, please use " - "-display sdl,grab-mod=rctrl instead."); - break; - case QEMU_OPTION_no_quit: - dpy.has_window_close = true; - dpy.window_close = false; - warn_report("-no-quit is deprecated, please use " - "-display ...,window-close=off instead."); - break; - case QEMU_OPTION_sdl: - warn_report("-sdl is deprecated, use -display sdl instead."); -#ifdef CONFIG_SDL - dpy.type = DISPLAY_TYPE_SDL; - break; -#else - error_report("SDL support is disabled"); - exit(1); -#endif - case QEMU_OPTION_pidfile: - pid_file = optarg; - break; - case QEMU_OPTION_win2k_hack: - win2k_install_hack = 1; - break; - case QEMU_OPTION_acpitable: - opts = qemu_opts_parse_noisily(qemu_find_opts("acpi"), - optarg, true); - if (!opts) { - exit(1); - } - acpi_table_add(opts, &error_fatal); - break; - case QEMU_OPTION_smbios: - opts = qemu_opts_parse_noisily(qemu_find_opts("smbios"), - optarg, false); - if (!opts) { - exit(1); - } - smbios_entry_add(opts, &error_fatal); - break; - case QEMU_OPTION_fwcfg: - opts = qemu_opts_parse_noisily(qemu_find_opts("fw_cfg"), - optarg, true); - if (opts == NULL) { - exit(1); - } - break; - case QEMU_OPTION_preconfig: - preconfig_requested = true; - break; - case QEMU_OPTION_enable_kvm: - qdict_put_str(machine_opts_dict, "accel", "kvm"); - break; - case QEMU_OPTION_M: - case QEMU_OPTION_machine: - { - bool help; - - keyval_parse_into(machine_opts_dict, optarg, "type", &help, &error_fatal); - if (help) { - machine_help_func(machine_opts_dict); - exit(EXIT_SUCCESS); - } - break; - } - case QEMU_OPTION_accel: - accel_opts = qemu_opts_parse_noisily(qemu_find_opts("accel"), - optarg, true); - optarg = qemu_opt_get(accel_opts, "accel"); - if (!optarg || is_help_option(optarg)) { - printf("Accelerators supported in QEMU binary:\n"); - GSList *el, *accel_list = object_class_get_list(TYPE_ACCEL, - false); - for (el = accel_list; el; el = el->next) { - gchar *typename = g_strdup(object_class_get_name( - OBJECT_CLASS(el->data))); - /* omit qtest which is used for tests only */ - if (g_strcmp0(typename, ACCEL_CLASS_NAME("qtest")) && - g_str_has_suffix(typename, ACCEL_CLASS_SUFFIX)) { - gchar **optname = g_strsplit(typename, - ACCEL_CLASS_SUFFIX, 0); - printf("%s\n", optname[0]); - g_strfreev(optname); - } - g_free(typename); - } - g_slist_free(accel_list); - exit(0); - } - break; - case QEMU_OPTION_usb: - qdict_put_str(machine_opts_dict, "usb", "on"); - break; - case QEMU_OPTION_usbdevice: - qdict_put_str(machine_opts_dict, "usb", "on"); - add_device_config(DEV_USB, optarg); - break; - case QEMU_OPTION_device: - if (optarg[0] == '{') { - QObject *obj = qobject_from_json(optarg, &error_fatal); - DeviceOption *opt = g_new0(DeviceOption, 1); - opt->opts = qobject_to(QDict, obj); - loc_save(&opt->loc); - assert(opt->opts != NULL); - QTAILQ_INSERT_TAIL(&device_opts, opt, next); - } else { - if (!qemu_opts_parse_noisily(qemu_find_opts("device"), - optarg, true)) { - exit(1); - } - } - break; - case QEMU_OPTION_smp: - machine_parse_property_opt(qemu_find_opts("smp-opts"), - "smp", optarg); - break; - case QEMU_OPTION_vnc: - vnc_parse(optarg); - break; - case QEMU_OPTION_no_acpi: - qdict_put_str(machine_opts_dict, "acpi", "off"); - break; - case QEMU_OPTION_no_hpet: - qdict_put_str(machine_opts_dict, "hpet", "off"); - break; - case QEMU_OPTION_no_reboot: - olist = qemu_find_opts("action"); - qemu_opts_parse_noisily(olist, "reboot=shutdown", false); - break; - case QEMU_OPTION_no_shutdown: - olist = qemu_find_opts("action"); - qemu_opts_parse_noisily(olist, "shutdown=pause", false); - break; - case QEMU_OPTION_uuid: - if (qemu_uuid_parse(optarg, &qemu_uuid) < 0) { - error_report("failed to parse UUID string: wrong format"); - exit(1); - } - qemu_uuid_set = true; - break; - case QEMU_OPTION_option_rom: - if (nb_option_roms >= MAX_OPTION_ROMS) { - error_report("too many option ROMs"); - exit(1); - } - opts = qemu_opts_parse_noisily(qemu_find_opts("option-rom"), - optarg, true); - if (!opts) { - exit(1); - } - option_rom[nb_option_roms].name = qemu_opt_get(opts, "romfile"); - option_rom[nb_option_roms].bootindex = - qemu_opt_get_number(opts, "bootindex", -1); - if (!option_rom[nb_option_roms].name) { - error_report("Option ROM file is not specified"); - exit(1); - } - nb_option_roms++; - break; - case QEMU_OPTION_semihosting: - qemu_semihosting_enable(); - break; - case QEMU_OPTION_semihosting_config: - if (qemu_semihosting_config_options(optarg) != 0) { - exit(1); - } - break; - case QEMU_OPTION_name: - opts = qemu_opts_parse_noisily(qemu_find_opts("name"), - optarg, true); - if (!opts) { - exit(1); - } - /* Capture guest name if -msg guest-name is used later */ - error_guest_name = qemu_opt_get(opts, "guest"); - break; - case QEMU_OPTION_prom_env: - if (nb_prom_envs >= MAX_PROM_ENVS) { - error_report("too many prom variables"); - exit(1); - } - prom_envs[nb_prom_envs] = optarg; - nb_prom_envs++; - break; - case QEMU_OPTION_old_param: - old_param = 1; - break; - case QEMU_OPTION_rtc: - opts = qemu_opts_parse_noisily(qemu_find_opts("rtc"), optarg, - false); - if (!opts) { - exit(1); - } - break; - case QEMU_OPTION_icount: - icount_opts = qemu_opts_parse_noisily(qemu_find_opts("icount"), - optarg, true); - if (!icount_opts) { - exit(1); - } - break; - case QEMU_OPTION_incoming: - if (!incoming) { - runstate_set(RUN_STATE_INMIGRATE); - } - incoming = optarg; - break; - case QEMU_OPTION_only_migratable: - only_migratable = 1; - break; - case QEMU_OPTION_nodefaults: - has_defaults = 0; - break; - case QEMU_OPTION_xen_domid: - if (!(accel_find("xen"))) { - error_report("Option not supported for this target"); - exit(1); - } - xen_domid = atoi(optarg); - break; - case QEMU_OPTION_xen_attach: - if (!(accel_find("xen"))) { - error_report("Option not supported for this target"); - exit(1); - } - xen_mode = XEN_ATTACH; - break; - case QEMU_OPTION_xen_domid_restrict: - if (!(accel_find("xen"))) { - error_report("Option not supported for this target"); - exit(1); - } - xen_domid_restrict = true; - break; - case QEMU_OPTION_trace: - trace_opt_parse(optarg); - break; - case QEMU_OPTION_plugin: - qemu_plugin_opt_parse(optarg, &plugin_list); - break; - case QEMU_OPTION_readconfig: - qemu_read_config_file(optarg, qemu_parse_config_group, &error_fatal); - break; - case QEMU_OPTION_spice: - olist = qemu_find_opts_err("spice", NULL); - if (!olist) { - error_report("spice support is disabled"); - exit(1); - } - opts = qemu_opts_parse_noisily(olist, optarg, false); - if (!opts) { - exit(1); - } - display_remote++; - break; - case QEMU_OPTION_writeconfig: - { - FILE *fp; - warn_report("-writeconfig is deprecated and will go away without a replacement"); - if (strcmp(optarg, "-") == 0) { - fp = stdout; - } else { - fp = fopen(optarg, "w"); - if (fp == NULL) { - error_report("open %s: %s", optarg, - strerror(errno)); - exit(1); - } - } - qemu_config_write(fp); - if (fp != stdout) { - fclose(fp); - } - break; - } - case QEMU_OPTION_qtest: - qtest_chrdev = optarg; - break; - case QEMU_OPTION_qtest_log: - qtest_log = optarg; - break; - case QEMU_OPTION_sandbox: - olist = qemu_find_opts("sandbox"); - if (!olist) { -#ifndef CONFIG_SECCOMP - error_report("-sandbox support is not enabled " - "in this QEMU binary"); -#endif - exit(1); - } - - opts = qemu_opts_parse_noisily(olist, optarg, true); - if (!opts) { - exit(1); - } - break; - case QEMU_OPTION_add_fd: -#ifndef _WIN32 - opts = qemu_opts_parse_noisily(qemu_find_opts("add-fd"), - optarg, false); - if (!opts) { - exit(1); - } -#else - error_report("File descriptor passing is disabled on this " - "platform"); - exit(1); -#endif - break; - case QEMU_OPTION_object: - object_option_parse(optarg); - break; - case QEMU_OPTION_overcommit: - opts = qemu_opts_parse_noisily(qemu_find_opts("overcommit"), - optarg, false); - if (!opts) { - exit(1); - } - enable_mlock = qemu_opt_get_bool(opts, "mem-lock", false); - enable_cpu_pm = qemu_opt_get_bool(opts, "cpu-pm", false); - break; - case QEMU_OPTION_compat: - { - CompatPolicy *opts; - Visitor *v; - - v = qobject_input_visitor_new_str(optarg, NULL, - &error_fatal); - - visit_type_CompatPolicy(v, NULL, &opts, &error_fatal); - QAPI_CLONE_MEMBERS(CompatPolicy, &compat_policy, opts); - - qapi_free_CompatPolicy(opts); - visit_free(v); - break; - } - case QEMU_OPTION_msg: - opts = qemu_opts_parse_noisily(qemu_find_opts("msg"), optarg, - false); - if (!opts) { - exit(1); - } - configure_msg(opts); - break; - case QEMU_OPTION_dump_vmstate: - if (vmstate_dump_file) { - error_report("only one '-dump-vmstate' " - "option may be given"); - exit(1); - } - vmstate_dump_file = fopen(optarg, "w"); - if (vmstate_dump_file == NULL) { - error_report("open %s: %s", optarg, strerror(errno)); - exit(1); - } - break; - case QEMU_OPTION_enable_sync_profile: - qsp_enable(); - break; - case QEMU_OPTION_nouserconfig: - /* Nothing to be parsed here. Especially, do not error out below. */ - break; - default: - if (os_parse_cmd_args(popt->index, optarg)) { - error_report("Option not supported in this build"); - exit(1); - } - } - } - } - /* - * Clear error location left behind by the loop. - * Best done right after the loop. Do not insert code here! - */ - loc_set_none(); - - qemu_validate_options(machine_opts_dict); - qemu_process_sugar_options(); - - /* - * These options affect everything else and should be processed - * before daemonizing. - */ qemu_process_early_options(); - qemu_process_help_options(); qemu_maybe_daemonize(pid_file); /* @@ -3699,22 +1041,16 @@ void qemu_init(int argc, char **argv, char **envp) qemu_init_main_loop(&error_fatal); cpu_timers_init(); - user_register_global_props(); - replay_configure(icount_opts); - configure_rtc(qemu_find_opts_singleton("rtc")); - qemu_create_machine(machine_opts_dict); + qemu_create_machine(); suspend_mux_open(); - qemu_disable_default_devices(); qemu_create_default_devices(); qemu_create_early_backends(); - qemu_apply_legacy_machine_options(machine_opts_dict); - qemu_apply_machine_options(machine_opts_dict); - qobject_unref(machine_opts_dict); + qemu_apply_machine_options(NULL); phase_advance(PHASE_MACHINE_CREATED); /* @@ -3756,13 +1092,9 @@ void qemu_init(int argc, char **argv, char **envp) /* parse features once if machine provides default cpu_type */ current_machine->cpu_type = machine_class->default_cpu_type; - if (cpu_option) { - current_machine->cpu_type = parse_cpu_option(cpu_option); - } /* NB: for machine none cpu_type could STILL be NULL here! */ qemu_resolve_machine_memdev(); - parse_numa_opts(current_machine); if (vmstate_dump_file) { /* dump and exit */ From patchwork Thu Dec 2 07:04:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 12651821 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 60D33C433F5 for ; Thu, 2 Dec 2021 07:16:26 +0000 (UTC) Received: from localhost ([::1]:59668 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1msgKP-0000E8-E1 for qemu-devel@archiver.kernel.org; Thu, 02 Dec 2021 02:16:25 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39554) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9M-0005T1-9z for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:01 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:27977) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9I-0006EY-W0 for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:04:59 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1638428696; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rEbd8tOszZohvM1hzIsT3+OdppvDgyOCcgQiUf6YvqE=; b=Pb+BM9/wDoYY5GxjAsU39sIGJ4038jXR4R/RoXS5tG0VXP3EvsXu4kHE5vn7mvQEN9K0q9 //WlWFeUXx1f8DwqN2vJSB/0L7BS/aLx0kHca/fpl1LYEy0FR3LTBaQSNP7SP0+Op/Rqmv hlcpXrrDtjDqHZaoW85Ahk4Ov1KPeWw= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-575-aHBJg7tVMgeDxfg_C5RyIQ-1; Thu, 02 Dec 2021 02:04:53 -0500 X-MC-Unique: aHBJg7tVMgeDxfg_C5RyIQ-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 22B6183DD25; Thu, 2 Dec 2021 07:04:52 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-112-7.ams2.redhat.com [10.36.112.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 95FD35D6BA; Thu, 2 Dec 2021 07:04:51 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 1536F113860F; Thu, 2 Dec 2021 08:04:50 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Subject: [PATCH RFC 02/11] vl: Drop x-exit-preconfig Date: Thu, 2 Dec 2021 08:04:41 +0100 Message-Id: <20211202070450.264743-3-armbru@redhat.com> In-Reply-To: <20211202070450.264743-1-armbru@redhat.com> References: <20211202070450.264743-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=armbru@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.719, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: damien.hedde@greensocs.com, berrange@redhat.com, mark.burton@greensocs.com, edgar.iglesias@gmail.co, mirela.grujic@greensocs.com, marcandre.lureau@redhat.com, pbonzini@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" The startup code is split between qemu_init() and qmp_x_exit_preconfig(). Cutting off the CLI leaves the QMP command useless. Drop it, and inline the startup code back into qemu_init(). I'm going to provide more general replacement shortly. Signed-off-by: Markus Armbruster --- qapi/misc.json | 27 ------------------------- monitor/hmp-cmds.c | 8 -------- softmmu/vl.c | 50 ++++++++++++++++++---------------------------- hmp-commands.hx | 18 ----------------- 4 files changed, 19 insertions(+), 84 deletions(-) diff --git a/qapi/misc.json b/qapi/misc.json index 358548abe1..45e6ee104e 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -174,33 +174,6 @@ ## { 'command': 'cont' } -## -# @x-exit-preconfig: -# -# Exit from "preconfig" state -# -# This command makes QEMU exit the preconfig state and proceed with -# VM initialization using configuration data provided on the command line -# and via the QMP monitor during the preconfig state. The command is only -# available during the preconfig state (i.e. when the --preconfig command -# line option was in use). -# -# Features: -# @unstable: This command is experimental. -# -# Since 3.0 -# -# Returns: nothing -# -# Example: -# -# -> { "execute": "x-exit-preconfig" } -# <- { "return": {} } -# -## -{ 'command': 'x-exit-preconfig', 'allow-preconfig': true, - 'features': [ 'unstable' ] } - ## # @human-monitor-command: # diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 9c91bf93e9..6865ed6010 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -931,14 +931,6 @@ void hmp_system_powerdown(Monitor *mon, const QDict *qdict) qmp_system_powerdown(NULL); } -void hmp_exit_preconfig(Monitor *mon, const QDict *qdict) -{ - Error *err = NULL; - - qmp_x_exit_preconfig(&err); - hmp_handle_error(mon, err); -} - void hmp_cpu(Monitor *mon, const QDict *qdict) { int64_t cpu_index; diff --git a/softmmu/vl.c b/softmmu/vl.c index 2bad7a437e..39c67b91c4 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -134,7 +134,6 @@ static const char *accelerators; static ram_addr_t maxram_size; static uint64_t ram_slots; static int display_remote; -static bool preconfig_requested; static ram_addr_t ram_size; static DisplayOptions dpy; @@ -945,34 +944,6 @@ static void qemu_machine_creation_done(void) } } -void qmp_x_exit_preconfig(Error **errp) -{ - if (phase_check(PHASE_MACHINE_INITIALIZED)) { - error_setg(errp, "The command is permitted only before machine initialization"); - return; - } - - qemu_init_board(); - qemu_machine_creation_done(); - - if (replay_mode != REPLAY_MODE_NONE) { - replay_vmstate_init(); - } - - if (incoming) { - Error *local_err = NULL; - if (strcmp(incoming, "defer") != 0) { - qmp_migrate_incoming(incoming, &local_err); - if (local_err) { - error_reportf_err(local_err, "-incoming %s: ", incoming); - exit(1); - } - } - } else if (autostart) { - qmp_cont(NULL); - } -} - void qemu_init(int argc, char **argv, char **envp) { MachineClass *machine_class; @@ -1103,9 +1074,26 @@ void qemu_init(int argc, char **argv, char **envp) exit(0); } - if (!preconfig_requested) { - qmp_x_exit_preconfig(&error_fatal); + qemu_init_board(); + qemu_machine_creation_done(); + + if (replay_mode != REPLAY_MODE_NONE) { + replay_vmstate_init(); } + + if (incoming) { + Error *local_err = NULL; + if (strcmp(incoming, "defer") != 0) { + qmp_migrate_incoming(incoming, &local_err); + if (local_err) { + error_reportf_err(local_err, "-incoming %s: ", incoming); + exit(1); + } + } + } else if (autostart) { + qmp_cont(NULL); + } + qemu_init_displays(); accel_setup_post(current_machine); os_setup_post(); diff --git a/hmp-commands.hx b/hmp-commands.hx index 70a9136ac2..838c1f5969 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -53,24 +53,6 @@ SRST Quit the emulator. ERST - { - .name = "exit_preconfig", - .args_type = "", - .params = "", - .help = "exit the preconfig state", - .cmd = hmp_exit_preconfig, - .flags = "p", - }, - -SRST -``exit_preconfig`` - This command makes QEMU exit the preconfig state and proceed with - VM initialization using configuration data provided on the command line - and via the QMP monitor during the preconfig state. The command is only - available during the preconfig state (i.e. when the --preconfig command - line option was in use). -ERST - { .name = "block_resize", .args_type = "device:B,size:o", From patchwork Thu Dec 2 07:04:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 12651831 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3B7D5C433EF for ; Thu, 2 Dec 2021 07:28:01 +0000 (UTC) Received: from localhost ([::1]:39938 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1msgVc-0006N2-AW for qemu-devel@archiver.kernel.org; Thu, 02 Dec 2021 02:28:00 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39538) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9M-0005Ss-A2 for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:01 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:42867) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9I-0006ET-Sh for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:04:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1638428695; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=poZ4keuJsaFlfWFahPlHeadvzzt0eBAV11mSciMhoqY=; b=I7xhhMaYiclC+xYgPy1SEQ1Jn7Srhki2H9ZFiXB7nu/l7DfclgwLGuq1t9f9nSQZBTirMX R7Nqt3S/xlm7Z7MqfaVn8vL7Lz27Z1Tor/ecghyXRcyVBnWhkm+jKrrYQj8ugAVwZHt7YJ F70VNBY/VEcmIR3Nb/x7zFj8pCqenVs= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-144-JwdojFj8Nf2bBSjexq73Jg-1; Thu, 02 Dec 2021 02:04:53 -0500 X-MC-Unique: JwdojFj8Nf2bBSjexq73Jg-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 06F65100CCC3; Thu, 2 Dec 2021 07:04:52 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-112-7.ams2.redhat.com [10.36.112.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 960F910016F4; Thu, 2 Dec 2021 07:04:51 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 188351138611; Thu, 2 Dec 2021 08:04:50 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Subject: [PATCH RFC 03/11] vl: Hardcode a QMP monitor on stdio for now Date: Thu, 2 Dec 2021 08:04:42 +0100 Message-Id: <20211202070450.264743-4-armbru@redhat.com> In-Reply-To: <20211202070450.264743-1-armbru@redhat.com> References: <20211202070450.264743-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=armbru@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.719, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: damien.hedde@greensocs.com, berrange@redhat.com, mark.burton@greensocs.com, edgar.iglesias@gmail.co, mirela.grujic@greensocs.com, marcandre.lureau@redhat.com, pbonzini@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" We bootstrap QMP with the CLI, but the CLI is (temporarily) gone. Hardcode a QMP monitor on stdio until we get it back. Signed-off-by: Markus Armbruster --- softmmu/vl.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/softmmu/vl.c b/softmmu/vl.c index 39c67b91c4..b14db0f47f 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -129,6 +129,9 @@ #include "config-host.h" +#include "qapi/qapi-commands-char.h" +#include "qapi/qapi-types-control.h" + static const char *incoming; static const char *accelerators; static ram_addr_t maxram_size; @@ -617,6 +620,14 @@ static void qemu_create_early_backends(void) /* spice must initialize before audio as it changes the default auiodev */ /* spice must initialize before chardevs (for spicevmc and spiceport) */ qemu_spice.init(); + + /* HACK: hardcoded monitor chardev */ + qmp_chardev_add("compat_monitor0", &(ChardevBackend){ + .type = CHARDEV_BACKEND_KIND_STDIO, + .u.stdio = { + .data = &(ChardevStdio){}, + }, + }, &error_abort); } @@ -628,6 +639,11 @@ static void qemu_create_late_backends(void) exit(1); } + /* HACK: hardcoded monitor */ + monitor_init(&(MonitorOptions){ + .chardev = (char *)"compat_monitor0", + }, false, &error_abort); + /* now chardevs have been created we may have semihosting to connect */ qemu_semihosting_connect_chardevs(); qemu_semihosting_console_init(); From patchwork Thu Dec 2 07:04:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 12651835 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5DD79C433EF for ; Thu, 2 Dec 2021 07:28:06 +0000 (UTC) Received: from localhost ([::1]:40136 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1msgVh-0006Up-7f for qemu-devel@archiver.kernel.org; Thu, 02 Dec 2021 02:28:05 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39620) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9P-0005Us-3S for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:07 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:37191) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9N-0006FG-IZ for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1638428700; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mybjs1fNoQk2Cjo30eilBMVovOmwjaKUm2k9+ozyX2E=; b=h0H0QdTnXSk3kY7NuM2+y7AIQs5W9cJWJZWDeWGYC4c6Rvw7f1FvKp9hOApt9IZ2EU+LUi jG/jEgdp8xzC+n+4c/bqDNMJbvx3eInrBi7k4V8RHhBy8VrwZbidrU3RXegujs6clg47pM ygKwb5QZ6eOqZNH2tjJCsvv2J2Zqt5Q= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-159-Gyz7kLA6M3uxqPWVrGvZVw-1; Thu, 02 Dec 2021 02:04:57 -0500 X-MC-Unique: Gyz7kLA6M3uxqPWVrGvZVw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 0A7451853022; Thu, 2 Dec 2021 07:04:56 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-112-7.ams2.redhat.com [10.36.112.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 95F9060C0F; Thu, 2 Dec 2021 07:04:51 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 1BB41113861E; Thu, 2 Dec 2021 08:04:50 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Subject: [PATCH RFC 04/11] vl: Hardcode a VGA device for now Date: Thu, 2 Dec 2021 08:04:43 +0100 Message-Id: <20211202070450.264743-5-armbru@redhat.com> In-Reply-To: <20211202070450.264743-1-armbru@redhat.com> References: <20211202070450.264743-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=armbru@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.719, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: damien.hedde@greensocs.com, berrange@redhat.com, mark.burton@greensocs.com, edgar.iglesias@gmail.co, mirela.grujic@greensocs.com, marcandre.lureau@redhat.com, pbonzini@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" My axing of the CLI also axed the (moderately complicated) code that posts a request to the board to create a VGA device. Hardcode such a request, to facilitate manual testing. Signed-off-by: Markus Armbruster --- softmmu/vl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/softmmu/vl.c b/softmmu/vl.c index b14db0f47f..07be92d5c0 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -534,6 +534,9 @@ static void qemu_create_default_devices(void) if (dpy.type == DISPLAY_TYPE_DEFAULT) { dpy.type = DISPLAY_TYPE_NONE; } + + /* HACK: hardcoded VGA device */ + vga_interface_type = VGA_STD; } Chardev *serial_hd(int i) From patchwork Thu Dec 2 07:04:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 12651869 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C928DC433FE for ; Thu, 2 Dec 2021 07:51:31 +0000 (UTC) Received: from localhost ([::1]:38274 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1msgsM-0008Dv-Fc for qemu-devel@archiver.kernel.org; Thu, 02 Dec 2021 02:51:30 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39634) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9P-0005Ut-QS for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:08 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:51851) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9N-0006FM-QJ for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1638428701; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ISNeR02c5b3tk8GCIpJBOCyn5mtLC5rckNy+rLiam5Q=; b=XJ21P4qq8KSz+/M/G34VJIrzVzz6GdfntbYAUflAl9TUpVV7XR02lOAWQ7Vz4wxHcuek2G 5MDvi82ST8rJC4uhwdRDhUjmRwmWAVGocViE8oAD0N/41j48M1RPhjZBmZTTb+BFA/h9v8 M+Uca+e/gB2kir7S7y17b7mnM6FUI+E= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-410-R5l9yjSGOlCdfDKsByWMKA-1; Thu, 02 Dec 2021 02:04:58 -0500 X-MC-Unique: R5l9yjSGOlCdfDKsByWMKA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4AB788042EA; Thu, 2 Dec 2021 07:04:57 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-112-7.ams2.redhat.com [10.36.112.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2D64E60843; Thu, 2 Dec 2021 07:04:53 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 1EF9811385BF; Thu, 2 Dec 2021 08:04:50 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Subject: [PATCH RFC 05/11] vl: Demonstrate (bad) CLI wrapped around QMP Date: Thu, 2 Dec 2021 08:04:44 +0100 Message-Id: <20211202070450.264743-6-armbru@redhat.com> In-Reply-To: <20211202070450.264743-1-armbru@redhat.com> References: <20211202070450.264743-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=armbru@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.719, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: damien.hedde@greensocs.com, berrange@redhat.com, mark.burton@greensocs.com, edgar.iglesias@gmail.co, mirela.grujic@greensocs.com, marcandre.lureau@redhat.com, pbonzini@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" To ensure you can do everything with QMP, the CLI should wrap around QMP, like HMP should. This commit does that in the stupidest way I can think of: each CLI argument is parsed as QMP command, and fed to the QMP machinery. Errors are reported, return values thrown away. This is of course *bad* CLI. To get decent CLI, we'll want to translate from CLI syntax to QMP. We may want to target QMP's C interface instead of parse trees. Note that this CLI processing code is cleanly separated from other startup code, unlike the old CLI code I axed. Only QMP commands with 'allow-preconfig': true work at this time. This is because CLI is processed early in startup. The remainder of the series is about letting the user interleave CLI and then QMP with startup. This will make arbitrary QMP commands available in the CLI. Signed-off-by: Markus Armbruster --- softmmu/vl.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/softmmu/vl.c b/softmmu/vl.c index 07be92d5c0..916cba35b7 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -129,6 +129,7 @@ #include "config-host.h" +#include "monitor/monitor-internal.h" #include "qapi/qapi-commands-char.h" #include "qapi/qapi-types-control.h" @@ -1011,6 +1012,31 @@ void qemu_init(int argc, char **argv, char **envp) qemu_init_subsystems(); + /* + * HACK to demonstrate feeding CLI to QMP + * Missing: translate CLI to QMP. Instead, each CLI argument is + * parsed as a QMP command. + */ + { + int i; + QObject *req; + QDict *resp, *error; + + for (i = 1; argv[i]; i++) { + loc_set_cmdline(argv, i, 1); + req = qobject_from_json(argv[i], &error_fatal); + resp = qmp_dispatch(&qmp_commands, req, false, NULL); + error = qdict_get_qdict(resp, "error"); + if (error) { + error_report("%s", qdict_get_str(error, "desc")); + exit(1); + } + /* TODO do something with the command's return valud? */ + qobject_unref(resp); + qobject_unref(req); + } + } + qemu_process_early_options(); qemu_maybe_daemonize(pid_file); From patchwork Thu Dec 2 07:04:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 12651825 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4434FC433FE for ; Thu, 2 Dec 2021 07:16:28 +0000 (UTC) Received: from localhost ([::1]:59736 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1msgKR-0000GU-Ae for qemu-devel@archiver.kernel.org; Thu, 02 Dec 2021 02:16:27 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39596) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9N-0005Ul-S6 for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:07 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:31358) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9K-0006Ei-4Y for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1638428697; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BgOQImmELR5gZTjk61q9HwrQaUNRwQHpb81Id/yHJpg=; b=BkJzX0/dLDeb71/BDJzvQY4e44r0x/1fusaumHKrhLuRBgKzEjaLCB7ojEgLsrlu30WrWf ktbXrq4ikslbBZp6ZTQvGJoShcAIO15c0zTCNTMijGGPEi7VQS6/8gBc44PDEVqgwgj+4K r18t+TxAUHAbeV12refSBEukIqbx25Y= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-589-zdT1qTnXPK-sQIav3ywPzA-1; Thu, 02 Dec 2021 02:04:54 -0500 X-MC-Unique: zdT1qTnXPK-sQIav3ywPzA-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 64322100CCC0; Thu, 2 Dec 2021 07:04:53 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-112-7.ams2.redhat.com [10.36.112.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2E3E55D6BA; Thu, 2 Dec 2021 07:04:53 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 2231F11384A5; Thu, 2 Dec 2021 08:04:50 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Subject: [PATCH RFC 06/11] vl: Factor qemu_until_phase() out of qemu_init() Date: Thu, 2 Dec 2021 08:04:45 +0100 Message-Id: <20211202070450.264743-7-armbru@redhat.com> In-Reply-To: <20211202070450.264743-1-armbru@redhat.com> References: <20211202070450.264743-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=armbru@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.719, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: damien.hedde@greensocs.com, berrange@redhat.com, mark.burton@greensocs.com, edgar.iglesias@gmail.co, mirela.grujic@greensocs.com, marcandre.lureau@redhat.com, pbonzini@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This loses a hidden bit of CLI that evaded the axe murderer: picking the default accelerator based on argv[0]. Signed-off-by: Markus Armbruster --- include/hw/qdev-core.h | 1 + hw/core/qdev.c | 5 +++++ softmmu/vl.c | 16 ++++++++++++---- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 20d3066595..2a3a3b0118 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -876,6 +876,7 @@ typedef enum MachineInitPhase { } MachineInitPhase; extern bool phase_check(MachineInitPhase phase); +extern MachineInitPhase phase_get(void); extern void phase_advance(MachineInitPhase phase); #endif diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 84f3019440..287eb81ff8 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -915,6 +915,11 @@ bool phase_check(MachineInitPhase phase) return machine_phase >= phase; } +MachineInitPhase phase_get(void) +{ + return machine_phase; +} + void phase_advance(MachineInitPhase phase) { assert(machine_phase == phase - 1); diff --git a/softmmu/vl.c b/softmmu/vl.c index 916cba35b7..e340475986 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -963,12 +963,10 @@ static void qemu_machine_creation_done(void) assert(machine->cgs->ready); } } +static void qemu_until_phase(void); void qemu_init(int argc, char **argv, char **envp) { - MachineClass *machine_class; - FILE *vmstate_dump_file = NULL; - qemu_add_opts(&qemu_drive_opts); qemu_add_drive_opts(&qemu_legacy_drive_opts); qemu_add_drive_opts(&qemu_common_drive_opts); @@ -1037,6 +1035,16 @@ void qemu_init(int argc, char **argv, char **envp) } } + qemu_until_phase(); +} + +void qemu_until_phase(void) +{ + MachineClass *machine_class; + FILE *vmstate_dump_file = NULL; + + assert(phase_get() == PHASE_NO_MACHINE); + qemu_process_early_options(); qemu_maybe_daemonize(pid_file); @@ -1073,7 +1081,7 @@ void qemu_init(int argc, char **argv, char **envp) * Note: uses machine properties such as kernel-irqchip, must run * after qemu_apply_machine_options. */ - configure_accelerators(argv[0]); + configure_accelerators("FIXME"); phase_advance(PHASE_ACCEL_CREATED); /* From patchwork Thu Dec 2 07:04:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 12651829 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 51BE5C433F5 for ; Thu, 2 Dec 2021 07:27:52 +0000 (UTC) Received: from localhost ([::1]:39802 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1msgVR-0006HY-7l for qemu-devel@archiver.kernel.org; Thu, 02 Dec 2021 02:27:49 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39590) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9N-0005Ui-QY for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:07 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:56928) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9K-0006Ej-5d for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1638428697; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KgSnAE2gxmi6RnKB1xvL8y2e29aE0v3OXGqSPwiqoTA=; b=birsOThi/E+wylEBsVGN4y1yhH8Z8C+wyERw/glmJ5MmNsbuHM0eGBFRNoQijH12+XFbIY zo1MfAKKsHkbPVshUXnSImwD00fDQIF5XPVuNpV6dh2JWBWuv5FoX0+NozgggzHbzeXh6e dmUGYhqBxK2mwSqnFyrKXMVMkJbSX9M= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-589-QHQWZsf9PgKVxYJgFSpA7w-1; Thu, 02 Dec 2021 02:04:54 -0500 X-MC-Unique: QHQWZsf9PgKVxYJgFSpA7w-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 629E883DD20; Thu, 2 Dec 2021 07:04:53 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-112-7.ams2.redhat.com [10.36.112.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2F23B10013D6; Thu, 2 Dec 2021 07:04:53 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 25A2B1138220; Thu, 2 Dec 2021 08:04:50 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Subject: [PATCH RFC 07/11] vl: Implement qemu_until_phase() running from arbitrary phase Date: Thu, 2 Dec 2021 08:04:46 +0100 Message-Id: <20211202070450.264743-8-armbru@redhat.com> In-Reply-To: <20211202070450.264743-1-armbru@redhat.com> References: <20211202070450.264743-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=armbru@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.719, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: damien.hedde@greensocs.com, berrange@redhat.com, mark.burton@greensocs.com, edgar.iglesias@gmail.co, mirela.grujic@greensocs.com, marcandre.lureau@redhat.com, pbonzini@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" A later patch will want to use qemu_until_phase() to advance from one arbitrary phase to another. Implement advancing from arbitrary phase to PHASE_MACHINE_READY. Indentation is intentionally off to minimize diffs. It's RFC :) Signed-off-by: Markus Armbruster --- softmmu/vl.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/softmmu/vl.c b/softmmu/vl.c index e340475986..b7f15d9f86 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -1043,7 +1043,8 @@ void qemu_until_phase(void) MachineClass *machine_class; FILE *vmstate_dump_file = NULL; - assert(phase_get() == PHASE_NO_MACHINE); + switch (phase_get()) { + case PHASE_NO_MACHINE: qemu_process_early_options(); @@ -1077,6 +1078,9 @@ void qemu_until_phase(void) qemu_apply_machine_options(NULL); phase_advance(PHASE_MACHINE_CREATED); + /* fall through */ + case PHASE_MACHINE_CREATED: + /* * Note: uses machine properties such as kernel-irqchip, must run * after qemu_apply_machine_options. @@ -1084,6 +1088,9 @@ void qemu_until_phase(void) configure_accelerators("FIXME"); phase_advance(PHASE_ACCEL_CREATED); + /* fall through */ + case PHASE_ACCEL_CREATED: + /* * Beware, QOM objects created before this point miss global and * compat properties. @@ -1128,7 +1135,13 @@ void qemu_until_phase(void) } qemu_init_board(); + assert(phase_get() == PHASE_MACHINE_INITIALIZED); + + /* fall through */ + case PHASE_MACHINE_INITIALIZED: + qemu_machine_creation_done(); + assert(phase_get() == PHASE_MACHINE_READY); if (replay_mode != REPLAY_MODE_NONE) { replay_vmstate_init(); @@ -1151,4 +1164,8 @@ void qemu_until_phase(void) accel_setup_post(current_machine); os_setup_post(); resume_mux_open(); + + case PHASE_MACHINE_READY: + break; + } } From patchwork Thu Dec 2 07:04:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 12651833 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9D4E3C4332F for ; Thu, 2 Dec 2021 07:28:01 +0000 (UTC) Received: from localhost ([::1]:39978 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1msgVc-0006OJ-C9 for qemu-devel@archiver.kernel.org; Thu, 02 Dec 2021 02:28:00 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39666) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9R-0005Uv-OR for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:09 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:60901) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9P-0006Fq-7V for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1638428702; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8EqVkmzqmqCQWqBVGCOG6CginlB03sF2CtaIT4y6+NA=; b=PkUpoRr9p4w+fEDcHX7pSf3pSElyyv0Y7WGCiwFRFEUf6x9a3GdFNP/fsKCwbdAS5VovgW kUWbBESHksMqo6EiBo4ZUyDe9AZ7pNS+L9mtYUWvi3vejkEbazHawp9T/H5IvfsKUxscy0 OfIIsdCWdQ3w2oxGr3aGa3fYMdRiqKE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-390-GUVZfxhiPumTd57Y42XruQ-1; Thu, 02 Dec 2021 02:04:59 -0500 X-MC-Unique: GUVZfxhiPumTd57Y42XruQ-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 72489100CCC0; Thu, 2 Dec 2021 07:04:58 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-112-7.ams2.redhat.com [10.36.112.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 341A25C232; Thu, 2 Dec 2021 07:04:53 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 2B0EC1138221; Thu, 2 Dec 2021 08:04:50 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Subject: [PATCH RFC 08/11] vl: Implement qemu_until_phase() running to arbitrary phase Date: Thu, 2 Dec 2021 08:04:47 +0100 Message-Id: <20211202070450.264743-9-armbru@redhat.com> In-Reply-To: <20211202070450.264743-1-armbru@redhat.com> References: <20211202070450.264743-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=armbru@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.719, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: damien.hedde@greensocs.com, berrange@redhat.com, mark.burton@greensocs.com, edgar.iglesias@gmail.co, mirela.grujic@greensocs.com, marcandre.lureau@redhat.com, pbonzini@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" A later patch will want to use qemu_until_phase() to advance from one arbitrary phase to another. The previous commit implement advancing from arbitrary phase to PHASE_MACHINE_READY. This one implements advancing to a phase given as argument. Signed-off-by: Markus Armbruster --- softmmu/vl.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/softmmu/vl.c b/softmmu/vl.c index b7f15d9f86..148c39e22c 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -963,7 +963,8 @@ static void qemu_machine_creation_done(void) assert(machine->cgs->ready); } } -static void qemu_until_phase(void); + +static void qemu_until_phase(MachineInitPhase phase); void qemu_init(int argc, char **argv, char **envp) { @@ -1035,16 +1036,21 @@ void qemu_init(int argc, char **argv, char **envp) } } - qemu_until_phase(); + qemu_until_phase(PHASE_MACHINE_READY); } -void qemu_until_phase(void) +void qemu_until_phase(MachineInitPhase phase) { MachineClass *machine_class; FILE *vmstate_dump_file = NULL; + assert(phase >= phase_get()); + switch (phase_get()) { case PHASE_NO_MACHINE: + if (phase == PHASE_NO_MACHINE) { + break; + } qemu_process_early_options(); @@ -1080,6 +1086,9 @@ void qemu_until_phase(void) /* fall through */ case PHASE_MACHINE_CREATED: + if (phase == PHASE_MACHINE_CREATED) { + break; + } /* * Note: uses machine properties such as kernel-irqchip, must run @@ -1090,6 +1099,9 @@ void qemu_until_phase(void) /* fall through */ case PHASE_ACCEL_CREATED: + if (phase == PHASE_ACCEL_CREATED) { + break; + } /* * Beware, QOM objects created before this point miss global and @@ -1139,6 +1151,9 @@ void qemu_until_phase(void) /* fall through */ case PHASE_MACHINE_INITIALIZED: + if (phase == PHASE_MACHINE_INITIALIZED) { + break; + } qemu_machine_creation_done(); assert(phase_get() == PHASE_MACHINE_READY); From patchwork Thu Dec 2 07:04:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 12651857 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E72AEC433F5 for ; Thu, 2 Dec 2021 07:41:48 +0000 (UTC) Received: from localhost ([::1]:56632 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1msgis-0001Fz-2f for qemu-devel@archiver.kernel.org; Thu, 02 Dec 2021 02:41:42 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39602) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9P-0005Up-2N for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:08 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:33902) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9K-0006Et-T4 for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:01 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1638428698; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4H0EK/DFvnglkelsvoL1QWxYWVVkAcCNhdQKrlzSVwk=; b=W5KinNEajN1pEolngAUBE8gqd6a7ziBzVgkJUD9Nljayh26BLOtT6RH1+jUPYqCBXUy8ub JkqP7LrA+rgWsP2hnMS1TtGf2ogP1l3r9A88s6YeIOjoViODhyIh4cJNkvmRZUAupFWVZo tUCF+p9gHZenC9CvW/bnt+CPF4SK2Mw= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-31-AsqBncYWN_OnPIh3mc1Bww-1; Thu, 02 Dec 2021 02:04:55 -0500 X-MC-Unique: AsqBncYWN_OnPIh3mc1Bww-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BD9B51023F50; Thu, 2 Dec 2021 07:04:53 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-112-7.ams2.redhat.com [10.36.112.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5F8AA5F4E7; Thu, 2 Dec 2021 07:04:53 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 2EBC81138222; Thu, 2 Dec 2021 08:04:50 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Subject: [PATCH RFC 09/11] vl: New QMP command until-phase Date: Thu, 2 Dec 2021 08:04:48 +0100 Message-Id: <20211202070450.264743-10-armbru@redhat.com> In-Reply-To: <20211202070450.264743-1-armbru@redhat.com> References: <20211202070450.264743-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=armbru@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.719, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: damien.hedde@greensocs.com, berrange@redhat.com, mark.burton@greensocs.com, edgar.iglesias@gmail.co, mirela.grujic@greensocs.com, marcandre.lureau@redhat.com, pbonzini@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This is a straightforward QMP wrapper around qemu_until_phase(). Useless right now, because by the time you can execute QMP, we're already in phase @machine-ready, and all you can do with the command is "advance" to that same phase. Its error message is RFC-qwality. Signed-off-by: Markus Armbruster --- qapi/phase.json | 31 +++++++++++++++++++++++++++++++ qapi/qapi-schema.json | 1 + include/hw/qdev-core.h | 32 -------------------------------- hw/core/machine-qmp-cmds.c | 1 + hw/core/machine.c | 1 + hw/core/qdev.c | 2 ++ hw/pci/pci.c | 1 + hw/usb/core.c | 1 + hw/virtio/virtio-iommu.c | 1 + monitor/hmp.c | 1 + softmmu/qdev-monitor.c | 1 + softmmu/vl.c | 15 +++++++++++++++ ui/console.c | 1 + MAINTAINERS | 1 + qapi/meson.build | 1 + 15 files changed, 59 insertions(+), 32 deletions(-) create mode 100644 qapi/phase.json diff --git a/qapi/phase.json b/qapi/phase.json new file mode 100644 index 0000000000..3f0492692b --- /dev/null +++ b/qapi/phase.json @@ -0,0 +1,31 @@ +# -*- Mode: Python -*- +# vim: filetype=python +# + +## +# = VM initialization phase +## + +## +# @MachineInitPhase: +# +# Since 7.0 +## +{ 'enum': 'MachineInitPhase', + 'prefix': 'PHASE', + 'data': [ 'no-machine', 'machine-created', 'accel-created', + 'machine-initialized', 'machine-ready' ] } + +## +# @until-phase: +# +# Features: +# @unstable: This command is experimental. +# +# Since 7.0 +# +# Returns: nothing +## +{ 'command': 'until-phase', 'allow-preconfig': true, + 'data': { 'phase': 'MachineInitPhase' }, + 'features': [ 'unstable' ] } diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json index 4912b9744e..f3c4c01393 100644 --- a/qapi/qapi-schema.json +++ b/qapi/qapi-schema.json @@ -64,6 +64,7 @@ { 'include': 'common.json' } { 'include': 'sockets.json' } { 'include': 'run-state.json' } +{ 'include': 'phase.json' } { 'include': 'crypto.json' } { 'include': 'block.json' } { 'include': 'block-export.json' } diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 2a3a3b0118..167b43102d 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -847,36 +847,4 @@ void device_listener_unregister(DeviceListener *listener); */ bool qdev_should_hide_device(const QDict *opts, bool from_json, Error **errp); -typedef enum MachineInitPhase { - /* current_machine is NULL. */ - PHASE_NO_MACHINE, - - /* current_machine is not NULL, but current_machine->accel is NULL. */ - PHASE_MACHINE_CREATED, - - /* - * current_machine->accel is not NULL, but the machine properties have - * not been validated and machine_class->init has not yet been called. - */ - PHASE_ACCEL_CREATED, - - /* - * machine_class->init has been called, thus creating any embedded - * devices and validating machine properties. Devices created at - * this time are considered to be cold-plugged. - */ - PHASE_MACHINE_INITIALIZED, - - /* - * QEMU is ready to start CPUs and devices created at this time - * are considered to be hot-plugged. The monitor is not restricted - * to "preconfig" commands. - */ - PHASE_MACHINE_READY, -} MachineInitPhase; - -extern bool phase_check(MachineInitPhase phase); -extern MachineInitPhase phase_get(void); -extern void phase_advance(MachineInitPhase phase); - #endif diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c index 4f4ab30f8c..664cef364a 100644 --- a/hw/core/machine-qmp-cmds.c +++ b/hw/core/machine-qmp-cmds.c @@ -21,6 +21,7 @@ #include "sysemu/hostmem.h" #include "sysemu/hw_accel.h" #include "sysemu/numa.h" +#include "sysemu/phase.h" #include "sysemu/runstate.h" static void cpustate_to_cpuinfo_s390(CpuInfoS390 *info, const CPUState *cpu) diff --git a/hw/core/machine.c b/hw/core/machine.c index 53a99abc56..28793d36c8 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -24,6 +24,7 @@ #include "hw/sysbus.h" #include "sysemu/cpus.h" #include "sysemu/sysemu.h" +#include "sysemu/phase.h" #include "sysemu/reset.h" #include "sysemu/runstate.h" #include "sysemu/numa.h" diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 287eb81ff8..4d592eb7f1 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -27,6 +27,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" +#include "qapi/qapi-types-phase.h" #include "qapi/qapi-events-qdev.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qerror.h" @@ -39,6 +40,7 @@ #include "hw/sysbus.h" #include "hw/qdev-clock.h" #include "migration/vmstate.h" +#include "sysemu/phase.h" #include "trace.h" static bool qdev_hot_added = false; diff --git a/hw/pci/pci.c b/hw/pci/pci.c index e5993c1ef5..02169fb728 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -38,6 +38,7 @@ #include "monitor/monitor.h" #include "net/net.h" #include "sysemu/numa.h" +#include "sysemu/phase.h" #include "sysemu/sysemu.h" #include "hw/loader.h" #include "qemu/error-report.h" diff --git a/hw/usb/core.c b/hw/usb/core.c index 975f76250a..e836138add 100644 --- a/hw/usb/core.c +++ b/hw/usb/core.c @@ -26,6 +26,7 @@ #include "qemu/osdep.h" #include "hw/usb.h" #include "qemu/iov.h" +#include "sysemu/phase.h" #include "trace.h" void usb_pick_speed(USBPort *port) diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index 1b23e8e18c..d297e5a38c 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -23,6 +23,7 @@ #include "qemu-common.h" #include "hw/qdev-properties.h" #include "hw/virtio/virtio.h" +#include "sysemu/phase.h" #include "sysemu/kvm.h" #include "qapi/error.h" #include "qemu/error-report.h" diff --git a/monitor/hmp.c b/monitor/hmp.c index b20737e63c..a6345ec8d6 100644 --- a/monitor/hmp.c +++ b/monitor/hmp.c @@ -37,6 +37,7 @@ #include "qemu/option.h" #include "qemu/units.h" #include "sysemu/block-backend.h" +#include "sysemu/phase.h" #include "sysemu/runstate.h" #include "trace.h" diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c index 01f3834db5..067f6cdeab 100644 --- a/softmmu/qdev-monitor.c +++ b/softmmu/qdev-monitor.c @@ -37,6 +37,7 @@ #include "qemu/qemu-print.h" #include "qemu/option_int.h" #include "sysemu/block-backend.h" +#include "sysemu/phase.h" #include "migration/misc.h" #include "migration/migration.h" #include "qemu/cutils.h" diff --git a/softmmu/vl.c b/softmmu/vl.c index 148c39e22c..9406368338 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -37,6 +37,7 @@ #include "qemu/cutils.h" #include "qemu/help_option.h" #include "qemu/uuid.h" +#include "sysemu/phase.h" #include "sysemu/reset.h" #include "sysemu/runstate.h" #include "sysemu/runstate-action.h" @@ -120,6 +121,7 @@ #include "qapi/qapi-commands-block-core.h" #include "qapi/qapi-commands-migration.h" #include "qapi/qapi-commands-misc.h" +#include "qapi/qapi-commands-phase.h" #include "qapi/qapi-visit-qom.h" #include "qapi/qapi-commands-ui.h" #include "qapi/qmp/qdict.h" @@ -1182,5 +1184,18 @@ void qemu_until_phase(MachineInitPhase phase) case PHASE_MACHINE_READY: break; + + default: + assert(0); } } + +void qmp_until_phase(MachineInitPhase phase, Error **errp) +{ + if (phase < phase_get()) { + error_setg(errp, "too late"); + return; + } + + qemu_until_phase(phase); +} diff --git a/ui/console.c b/ui/console.c index 29a3e3f0f5..e080873534 100644 --- a/ui/console.c +++ b/ui/console.c @@ -33,6 +33,7 @@ #include "qemu/option.h" #include "qemu/timer.h" #include "chardev/char.h" +#include "sysemu/phase.h" #include "trace.h" #include "exec/memory.h" #include "io/channel-file.h" diff --git a/MAINTAINERS b/MAINTAINERS index 006a2293ba..9b7e6de6a7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2591,6 +2591,7 @@ F: softmmu/cpu-timers.c F: softmmu/icount.c F: softmmu/runstate-action.c F: qapi/run-state.json +F: qapi/phase.json Read, Copy, Update (RCU) M: Paolo Bonzini diff --git a/qapi/meson.build b/qapi/meson.build index c0c49c15e4..9d141a517a 100644 --- a/qapi/meson.build +++ b/qapi/meson.build @@ -41,6 +41,7 @@ qapi_all_modules = [ 'misc', 'misc-target', 'net', + 'phase', 'pragma', 'qom', 'replay', From patchwork Thu Dec 2 07:04:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 12651823 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 67688C433EF for ; Thu, 2 Dec 2021 07:16:27 +0000 (UTC) Received: from localhost ([::1]:59714 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1msgKQ-0000FZ-1f for qemu-devel@archiver.kernel.org; Thu, 02 Dec 2021 02:16:26 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39592) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9N-0005Uj-R0 for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:07 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:24512) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9K-0006Eg-5a for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1638428697; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4JA9jZf/1CWOlKDFFrg38jfybtFHYIAChdjm9CwITIk=; b=DIoQnKxWsJD5c6YJmT/+zyndxjAj1cknp0yBPvtOD/0RGOXuRXnDpVMs8eAtbRreUYq55W bENdjYq4C5NJNzvZpSWJDfP0iCdS5gl/SxSaHLFA0kO7S8BtT0SzMjQDKj0h4E7f096HNg S4H4wFVSJmhNC/uhXTM9NZJBXZd1PRI= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-190-FWOmzbrMONy0_lzA1d6k7A-1; Thu, 02 Dec 2021 02:04:54 -0500 X-MC-Unique: FWOmzbrMONy0_lzA1d6k7A-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 9F0F81023F4E; Thu, 2 Dec 2021 07:04:53 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-112-7.ams2.redhat.com [10.36.112.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6B1845D6BA; Thu, 2 Dec 2021 07:04:53 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 3823E1138223; Thu, 2 Dec 2021 08:04:50 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Subject: [PATCH RFC 10/11] vl: Disregard lack of 'allow-preconfig': true Date: Thu, 2 Dec 2021 08:04:49 +0100 Message-Id: <20211202070450.264743-11-armbru@redhat.com> In-Reply-To: <20211202070450.264743-1-armbru@redhat.com> References: <20211202070450.264743-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=armbru@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.133.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.719, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: damien.hedde@greensocs.com, berrange@redhat.com, mark.burton@greensocs.com, edgar.iglesias@gmail.co, mirela.grujic@greensocs.com, marcandre.lureau@redhat.com, pbonzini@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" I'd like to use device cold plug as an example for how how the user can now interleave CLI with startup. Doesn't work, because only commands with 'allow-preconfig': true are available before phase @machine-ready, and device_add isn't. Instead of changing just device_add, this hack allows all commands all the time, for easy experimentation. Some commands don't work, but this is RFC. Hot pci-serial works: $ qemu-system-x86_64 '{"execute": "until-phase", "arguments": {"phase": "machine-ready"}}' '{"execute": "device_add", "arguments": {"driver": "pci-serial"}}' Hot isa-serial fails as it should: $ qemu-system-x86_64 '{"execute": "until-phase", "arguments": {"phase": "machine-ready"}}' '{"execute": "device_add", "arguments": {"driver": "isa-serial"}}' [...] qemu-system-x86_64: {"execute": "device_add", "arguments": {"driver": "isa-serial"}}: Bus 'isa.0' does not support hotplugging Cold isa-serial works: $ qemu-system-x86_64 '{"execute": "until-phase", "arguments": {"phase": "machine-initialized"}}' '{"execute": "device_add", "arguments": {"driver": "isa-serial"}}' A command that works even in phase @no-machine: $ qemu-system-x86_64 '{"execute": "chardev-add", "arguments": {"id": "chr0", "backend": {"type": "null", "data": {}}}}' {"QMP": {"version": {"qemu": {"micro": 92, "minor": 1, "major": 6}, "package": "v6.2.0-rc2-38-gff2c6103bf"}, "capabilities": ["oob"]}} {"execute": "qmp_capabilities", "arguments": {"enable": ["oob"]}} {"return": {}} {"execute": "query-chardev"} {"return": [{"frontend-open": false, "filename": "null", "label": "chr0"}, {"frontend-open": true, "filename": "stdio", "label": "compat_monitor0"}]} A command that doesn't work there: $ qemu-system-x86_64 '{"execute": "screendump", "arguments": {"filename": "scr"}}' qemu-system-x86_64: ../qapi/qmp-dispatch.c:226: qmp_dispatch: Assertion `!oob && qemu_in_coroutine() && !(cmd->options & QCO_COROUTINE)' failed. Aborted (core dumped) Signed-off-by: Markus Armbruster --- softmmu/qdev-monitor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c index 067f6cdeab..ddb12c68e6 100644 --- a/softmmu/qdev-monitor.c +++ b/softmmu/qdev-monitor.c @@ -1041,11 +1041,13 @@ int qemu_global_option(const char *str) bool qmp_command_available(const QmpCommand *cmd, Error **errp) { +#if 0 if (!phase_check(PHASE_MACHINE_READY) && !(cmd->options & QCO_ALLOW_PRECONFIG)) { error_setg(errp, "The command '%s' is permitted only after machine initialization has completed", cmd->name); return false; } +#endif return true; } From patchwork Thu Dec 2 07:04:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Armbruster X-Patchwork-Id: 12651863 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 956BAC433EF for ; Thu, 2 Dec 2021 07:46:55 +0000 (UTC) Received: from localhost ([::1]:33786 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1msgns-0004yh-U9 for qemu-devel@archiver.kernel.org; Thu, 02 Dec 2021 02:46:52 -0500 Received: from eggs.gnu.org ([209.51.188.92]:39674) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9T-0005Uw-91 for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:09 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:26648) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1msg9P-0006Fz-Rg for qemu-devel@nongnu.org; Thu, 02 Dec 2021 02:05:06 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1638428703; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HuDNU5cB6zt9MhfLlrF0Gf7BvooKApGl+AABzywjdHw=; b=OwqAFBURGMf39sAgJW33pA9aNr99Ah6L44bK3NU346BKFQq4Q9B8H8N1aG6eieAEH0HbNB Ny17I8opbZHJVkR1hxm/c6T7jDOuVEVscuylErupO89mdkScaLHoamrCrKbom4HzeHu1Z5 SYv7i4UYgUQYhaOqCe+pi2loIKBDJ+c= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-225-Ep_VwwKUNxO6Rfjw5cti8w-1; Thu, 02 Dec 2021 02:05:01 -0500 X-MC-Unique: Ep_VwwKUNxO6Rfjw5cti8w-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4AAD583DD20; Thu, 2 Dec 2021 07:05:00 +0000 (UTC) Received: from blackfin.pond.sub.org (ovpn-112-7.ams2.redhat.com [10.36.112.7]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9F4FA19EF9; Thu, 2 Dec 2021 07:04:54 +0000 (UTC) Received: by blackfin.pond.sub.org (Postfix, from userid 1000) id 3F9DA1138224; Thu, 2 Dec 2021 08:04:50 +0100 (CET) From: Markus Armbruster To: qemu-devel@nongnu.org Subject: [PATCH RFC 11/11] vl: Enter main loop in phase @machine-initialized Date: Thu, 2 Dec 2021 08:04:50 +0100 Message-Id: <20211202070450.264743-12-armbru@redhat.com> In-Reply-To: <20211202070450.264743-1-armbru@redhat.com> References: <20211202070450.264743-1-armbru@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=armbru@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=170.10.129.124; envelope-from=armbru@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -34 X-Spam_score: -3.5 X-Spam_bar: --- X-Spam_report: (-3.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.719, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: damien.hedde@greensocs.com, berrange@redhat.com, mark.burton@greensocs.com, edgar.iglesias@gmail.co, mirela.grujic@greensocs.com, marcandre.lureau@redhat.com, pbonzini@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" The previous commit demonstrated how you can interleave QMP-over-CLI with startup. We want the same for real QMP. QMP-over-CLI starts in phase @no-machine, and may advance the phase. We then advance to phase @machine-ready, and enter the main loop, and real QMP becomes available. If we skip the phase advance, real QMP becomes exactly as expressive as QMP-over-CLI. Except the main loop crashes. If we skip to phase @machine-created, it doesn't crash, but it doesn't give me a QMP monitor either. Same for phase @accel-created. Skipping to @machine-initialized works, and suffices to let me demonstrate cold plug via QMP: $ qemu-system-x86_64 {"QMP": {"version": {"qemu": {"micro": 92, "minor": 1, "major": 6}, "package": "v6.2.0-rc2-39-g8c7f07732b"}, "capabilities": ["oob"]}} {"execute": "qmp_capabilities", "arguments": {"enable": ["oob"]}} {"return": {}} {"execute": "device_add", "arguments": {"driver": "isa-serial"}} {"return": {}} Signed-off-by: Markus Armbruster --- softmmu/vl.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/softmmu/vl.c b/softmmu/vl.c index 9406368338..01f87aec07 100644 --- a/softmmu/vl.c +++ b/softmmu/vl.c @@ -1038,7 +1038,12 @@ void qemu_init(int argc, char **argv, char **envp) } } - qemu_until_phase(PHASE_MACHINE_READY); + /* + * FIXME need to force phase, because staying in PHASE_NO_MACHINE + * crashes, and going only to PHASE_MACHINE_CREATED or + * PHASE_ACCEL_CREATED gives no monitor. + */ + qemu_until_phase(PHASE_MACHINE_INITIALIZED); } void qemu_until_phase(MachineInitPhase phase)